Before Go 1.11 gets released, which introduces an experimental port to WebAssembly (WASM for short), I'm going to demonstrate how to compile Go source code into WASM and execute in the browser!
Here are the steps:
- Setup
go1.11beta3
- Compile Go to WASM
- Use HTML and JavaScript to load WASM
- Spin up a web server
- Open the website!
Step 1: Setup go1.11beta3
Although we need Go version 1.11 which is still in beta (due in August!), because Go is open-source we can just download the latest beta instead.
https://github.com/golang/go/releases/tag/go1.11beta3
$ go get golang.org/dl/go1.11beta3
$ go1.11beta3 download
# => Success. You may now run 'go1.11beta3'
Step 2: Compile Go to WASM
We can now write Go! The plan is to print the classic hello, Go/WASM!
but in the browser––in the developer console.
// main.go
package main
import "fmt"
func main() {
fmt.Println("hello, Go/WASM!")
}
To compile our program from Go to WASM, we use the command go build
.
Note: We need to tell Go to compile for the web and not the default environment; our computer. So we need to set the environmental variables GOOS=js
and GOARCH=wasm
to target the web.
$ GOOS=js GOARCH=wasm go1.11beta3 build -o test.wasm main.go
Step 3: Use HTML and JavaScript to load WASM
This step isn't difficult; the Go team has prepared some files for us to experiment with.
# -s == silent mode
# -O == output mode
$ curl -sO https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.html
$ curl -sO https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.js
Step 4: Spin up a web server
Now we need to spin up a simple web server to serve some static assets. This is just a few lines of code:
// server.go
package main
import (
"flag"
"log"
"net/http"
)
func main() {
port := flag.String("port", "8000", "port")
flag.Parse()
log.Fatal(http.ListenAndServe(":"+*port, http.FileServer(http.Dir("."))))
}
Let's start it! Cheers!
$ go1.11beta3 run server.go
# or to run on a different port:
# $ go1.11beta3 run -port=8080 server.go
Step 5: Open the website!
Open localhost:8000/wasm_exec.html
!
Note: A 'Run' button (at the top left) will appear disabled until the compiled WASM is loaded.
Once the 'Run' button is enabled, open the console and press the button!
See hello, Go/WASM!
??
Congratulations! 🎉
You've just compiled, loaded, and run a Go program via WASM!
Is that true?
Why don't you confirm that Content-Type
is application/wasm
in the response header of test.wasm
? ;)
Acknowledgements
Thank you ZAYDEK for recommending me to translate my article into English and reviewing this article.
Top comments (4)
Hmm...Good job, it literally looks like my tutorial I posted at 9th July, a month ago but why not, you can find it at: facebook.com/iris.framework/photos...
No joy using 1.11rc2:
Uncaught (in promise) CompileError: AsyncCompile: Wasm decoding failed: expected magic word 00 61 73 6d, found 4d 5a 90 00 @+0
You're building into an exe with a wasm extension, which then isn't executable by the browser. I tried to fix this on my machine by setting the environment variables again, but it didn't work. If you can, try compiling on a UNIX system instead of using Windows.
If you're using goland, try using these directions:
buildersbox.corp-sansan.com/entry/...
I'm not really surprised this doesn't work on Windows, considering that plugins don't work on Windows, which seems to indicate to me that wasm is really only going to be well-supported on UNIX systems.
This is awesome. Can't wait to try this out!