npm install
sh install_wasm_exec.sh
- package.json:
Edit
nameandversionas you like.
"name": "vue-electron-go-wasm",
"version": "0.1.0",
go.mod: Edit user and project in the package path.
module github.com/<USER>/<PROJECT>
make
npm run serve
npm run electron:serve
Note: Force reloading browser window is recommended (Shift-reload).
npm run build
npm run electron:build
Note: An executable built with electron:build did not work properly because of different practices of file loading (use of Fetch API) in server-side and Electron.
The following code is added to background.js to enable Fetch API.
However, there may be security risk discussions when allowing Fetch API.
protocol.registerSchemesAsPrivileged([
{
scheme: 'app',
privileges: {
secure: true, standard: true, supportFetchAPI: true
},
},
])
npm run test:unit
npm run lint
-
How to load
wasm_exec.jsand Go binary for use in index.html- Look at
index.html:then find that a bare<script src="/wasm/wasm_exec.js"></script> <script> const go = new Go() WebAssembly.instantiateStreaming( fetch("/wasm/main.wasm"), go.importObject ).then((result) => { go.run(result.instance) }) </script>echo()can be called within the same html.<button onClick="console.log('index.html: ' + echo('Hello, World!'))"> index.html: say hello to console </button>
- Look at
-
How to load
wasm_exec.jsand Go binary for use in Vue.-
Note that
wasm_exec.jsis alredy loaded inindex.html -
Find that the Go-wasm loader is stored in variable
global. -
Use
global.Go()const go = new global.Go() // Loaded in public/index.html const WASM_URL = '/wasm/main.wasm' WebAssembly.instantiateStreaming( fetch(WASM_URL), go.importObject ).then( function (obj) { const wasm = obj.instance go.run(wasm) } ) -
Declare a global function using Vue.mixin
Vue.mixin({ methods: { run: function (program, data) { return global.run(program, data) }, }, }) -
Consume the functions in vue files (HTML part).
<input v-model="message" type="textarea" /> <button @click="result = run('echo', message)"> Say Hello </button> <button @click="result = run('uppercase', message)"> SAY UPPER </button> <button @click="result = run('lowercase', message)"> say lower </button> <div>Result: {{ result }}</div>The functions can be bare. The entry point is
run()and it takes two args: (1) program and (2) data.Currently three simple programs are supported:
echo,uppercase, andlowercase. There is no options, no spacing, strictly. -
Consume the functions in vue files (script part).
methods: { update(program, data) { this.liveResult = run(program, data) // eslint-disable-line no-undef },The functions can be bare. Add
eslint-disable-line no-undefto avoid a lint error, as it seems unable to find the declarations in vue mixin.
-
-
How to write Go files
- Declare a bare function. Functions can be in lowercase.
func run(this js.Value, inputs []js.Value) interface{} {thisis the context from JavaScript. The function args are stored ininputs. - The args must be cast using String() or an appropriate function.
var program = inputs[0].String() var data = inputs[1].String() - Return a plain string value or an appropriate numeric value.
return result - Don't forget to register the function to expose to JavaScript.
func main(){ js.Global().Set("run", js.FuncOf(run)) - Use channel for keeping the process alive.
ch := make(chan struct{}, 0) <-ch
- Declare a bare function. Functions can be in lowercase.
-
How to include an external go package
-
Import the external package
package main import ( "syscall/js" "local.packages/gossi" )This
gossiis a sample project that provides a core functionality:echo,uppercase, andlowercase. -
Put go.mod at the project home directory, such as
~/github/vue-electron-go-wasm/go.mod.This go.mod file controls the location of the external project. The content will be like below, pointing to another local go package.
module github.com/<USER>/vue-electron-go-wasm go 1.15 replace local.packages/gossi => ./go_external/gossi require local.packages/gossi v0.0.0-00010101000000-000000000000 // indirectreplaceis redirecting to the current project's./go_external/gossidirectory. -
The package can be located outside of the main project. Suppose you want to maintain these as separate projects, like below.
~/github/ vue-electron-go-wasm/ go.mod go/ main.go gossi/ go.mod main.goIn this case, the
replacepath should look like:replace local.packages/gossi => ../gossi(up one directory, which is
~/github/, then down togossi) -
The content of the external
go.modshould simply look like:
module github.com/<USER>/gossi go 1.15 -
- Q: I get
Uncaught SyntaxError: Unexpected token '<' [wasm_exec.js:1]- A: Missing
wasm_exec.jsat./public/wasm. Use the scriptinstall_wasm_exec.shto install it.
- A: Missing