DEV Community

CIARANA
CIARANA

Posted on

Quick Tutorial: Write Go, Run WASM!

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:

  1. Setup go1.11beta3
  2. Compile Go to WASM
  3. Use HTML and JavaScript to load WASM
  4. Spin up a web server
  5. 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'
Enter fullscreen mode Exit fullscreen mode

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!")
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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("."))))
}

Enter fullscreen mode Exit fullscreen mode

Let's start it! Cheers!

$ go1.11beta3 run server.go

# or to run on a different port:
# $ go1.11beta3 run -port=8080 server.go
Enter fullscreen mode Exit fullscreen mode

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.

References

Top comments (4)

Collapse
 
kataras profile image
Gerasimos (Makis) Maropoulos

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...

Collapse
 
interthresh profile image
Timothy McClanahan • Edited

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

Collapse
 
gregoryledray profile image
Gregory Ledray • Edited

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.

Collapse
 
itsrainingmani profile image
Manikandan Sundararajan

This is awesome. Can't wait to try this out!