Sunday, May 20, 2018

WebAssembly (WASM) with Go

This is the first time that I've tried to compile the Go compiler so I figure that I'll document it here for others who might be wanting to try WASM with Go before the official Go release in August.

The next release of Go (1.11) is scheduled for Aug and it will be first time WebAssembly (WASM) will be supported.  WASM will be a build target much like how one builds a binary for other machine and operating systems except that in this case the machine is a "virtual" machine that runs inside the browser.

I've been very excited for WASM and I've been eagerly waiting for the time when I can use Go to write WASM.  The branch for the 1.11 release has is now locked for only bug fixes so I figured that it might be a good time to try writing a WASM code with Go.

Note that this first release for WASM isn't going to be "production" ready.  I don't think it'll be very optimized and WASM itself is only at its MVP release it doesn't allow WASM code direct access to the DOM or the browser APIs so all calls is still going through JavaScript.

Unfortunately, as of this writing, the code in the Go repo doesn't work for WASM.  The work on WASM for Go is primarily being done by Richard Musiol (neelance), the author of GopherJS, so I decided to get the version Go from this GitHub repo.

First, you will need a version of Go on your system to compile the source.  The easiest way is to download and install the binary distribution from the main Go website.

Until 1.11 is released to get WASM is to build from source.

git clone https://go.googlesource.com/go
cd go
Once you have the source, it's time to compile it.

cd src
./all.bash
If everything is built correctly then there will be a new "go" binary in ../bin.  Also, there are two files to help you get started with loading future WASM files in ../misc/wasm.

Create a test.go file:

package main

func main() {
    println("hello, wasm")
}
Compile to WASM with:

GOOS=js GOARCH=wasm go build -o test.wasm test.go
Make sure you're running the go command that you've just built and not the version that you installed originally.

In the same directory with your test.wasm file, copy over wasm_exec.html and wasm_exec.js from misc/wasm.

The browser will expect the test.wasm file to be served with a MIME of application/wasm so you'll need to add the following to your /etc/mime.types file:

application/wasm wasm
To run it in your browser, you'll need to have a web server.  Creating one with Go is easy, or you can also use Python with the following command.

python -m SimpleHTTPServer

Point your browser to your web server and load wasm_exec.html.  Click on the button and you should see "hello, wasm" appear in the browser's console.

I've been experimenting with WASM here.

1 comment:

  1. Great post! I followed it and got it working perfectly, thank you. They also have a Dockerfile now which would be a next thing to try: https://github.com/neelance/go/compare/master...neelance:wasm-wip#diff-3254677a7917c6c01f55212f86c57fbf

    ReplyDelete