Getting started into Go and WebAssembly

Go is an opensource programming language that makes it easy to build simple, reliable, and efficient software.

Why should I learn one more language, what is so exciting about Go ?
  • Simple and easy syntax
  • Concurrency
  • Fun to program in Go
  • Easy Networking
  • ~ Fast

and more

Coming back to our next hero in this story, WebAssembly

WebAssembly in simple language, is running your native code (C / C++ / Rust / Go ) in the browser. It is fast, secure and maintainable.

They are a set of binary instruction format that runs on any stack based machine.

There were several attempts made by browser vendors to run the native code in browser. The one thing that was widely popular was asm.js. But even it had many limitations.

WebAssembly is binary encoded instructions that are size- and load-time-efficient. They are secure and run on sandboxed environment.

Wait, isn’t Javascript fast. Yes it is, you can achieve ~native speed in Javascript. But, the work around and amount of effort that you have to spend is high. But with WebAssembly you can get this right out of the box.

Maintainable Performance is the key.

Let us get started with Go and WebAssembly.

To start, you will need to install latest version of Go. If you already have go installed, then install the latest version v1.11 by running:

go get golang.org/dl/go1.11rc1

Then you can run go1.11rc1 command in your terminal instead of go command.

Now it is the time to download the source.

go1.11rc1 download

🏁 Step 1 is complete. You have installed the latest version.

If you don’t have Go installed already, Check out here for more detailed steps.

Lets get started with the sample helloworld now.

Let us create our go file,

mkdir go-awsm-with-wasm

cd go-awsm-with-wasm

touch main.go

Open this with your favourite code editor and start typing.

package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}

WebAssembly currently supports only numbers , But we need to pass in and get back Strings and other object types. Who just plays with numbers. So we need binding files that help to translate the things that we send from WASM to JavaScript and JavaScript to WASM. So we need to have the binding files. Go src has the binding file, lets grab that.

So we have got the wasm_exec.htmland the wasm_exec.js file (AKA, the binding file).

🏁 Step 2 completed we have all the things necessary.

Now it is the time to generate the WASM file from the Go file.

Lets run

GOARCH=wasm GOOS=js go1.11rc1 build -o test.wasm main.go

So what are we doing here,

We are telling the GO compiler the,

architecture to consider is wasm with GOARCH

OS that we target is js

build my main.go and output test.wasm

🎉 Hooray, you did it.

🏁 Step3 is completed, we have our wasm ready.

Now the final step. Running and seeing the output.

There are multiple ways to do this,

Option 1: Easy way

If you have Python installed, you can run

python -m SimpleHTTPServer 8000

Then you can go to http://localhost:8000

Option 2: Gopher way

If you are series gopher, you can then create a server and use that instead.

touch server.go


package main
import "net/http"
func addMIMEToWasmFiles(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/wasm")
http.ServeFile(w, r, "test.wasm")
}
func main() {
mux := http.NewServeMux()
mux.Handle("/", http.FileServer(http.Dir(".")))

// WASM files need MIME type to be set
mux.HandleFunc("/test.wasm", addMIMEToWasmFiles)
http.ListenAndServe(":8000", mux)
}

Then you can go to http://localhost:8000

Option 3: The Web Dev way

This is my personal favorite, use Webpack

npm init --yes

npm i --save-dev webpack webpack-cli webpack-dev-server

touch webpack.config.js

And add the configuration,

const path = require('path');

module.exports = {
    entry: "./wasm_exec.js",
   output: {
       path: path.resolve(__dirname, "dist"),
       filename: "index.js",
   },
   mode: "development",
};

Add the scripts into package.json

"scripts": {
    "build": "webpack --config webpack.config.js",
    "start": "webpack-dev-server"
}

Now you can just run npm run start and go to the http://localhost:8000

🏁 Step4 and post is completed

Lets start hacking WebAssembly and make the Web even more a better place.