Introduction to WebAssembly in Go

WebAssembly is one of the modern technologies designed to run more languages ​​in the browser with Javascript interop.

WebAssembly (WASM) is a platform-independent binary instruction format for stack-based virtual machines designed as a portable build target for programming languages ​​to run in supportive environments (i.e. web and server applications).

With WASM, you can run various programming languages, including Go, in your browser and take advantage of language features. Also, interact with Javascript on the web.

Getting started with WebAssembly in Go

Go provides first-class support for using WebAssembly in your Go applications, you just need to do some configuration and compile the Go code into WebAssembly.

You will need to do some configuration to transpile your Go code into WebAssembly. You will have to change your Go architecture GOARCH environment variable a it was me and wow operating system GOOS variable to js.

Run this command in the terminal from your working directory to make these settings.

Set GOARCH=wasm GOOS=js 

The next step is to transpile your Go code into a WebAssembly. .was m proceedings. Run this command to transpile your main.ir file to a file named lib.wasm

go build -o lib.wasm main.go

When you run the command, you will find a lib.wasm in your working directory.

You must copy the WebAssembly file that came with your Go installation to your working directory to run the WebAssembly file with NodeJS in a web page.

cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

The command copies the wasm_exec.js file to your working directory and serves as the entry point to your application.

Now you can use the wasm_exec.js script to run your WASM files with Go and make DOM API calls.

node wasm_exec.js main.wasm

Starting a web server to host the website

Add this code from the Go authors to an HTML file in your working directory to instantiate a WebAssembly dataflow with the instantiateStreaming method.

<!DOCTYPE html>
<!--
Copyright 2018 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->

<html>
<head>
    <meta charset=”utf-8″ />
    <title>Go wasm</title>
</head>

<body>
<script src=”wasm_exec.js”></script>

<script>
    if (!WebAssembly.instantiateStreaming) {
        
        WebAssembly.instantiateStreaming = async (resp, importObject) => {
            const source = await (await resp).arrayBuffer();
            return await WebAssembly.instantiate(source, importObject);
        };
    }

    const go = new Go();

    let mod, inst;

    WebAssembly.instantiateStreaming(fetch(“lib.wasm”), go.importObject).then(
        result => {
            mod = result.module;
            inst = result.instance;
            document.getElementById(“runButton”).disabled = false;
        }
    );

    async function run() {
        await go.run(inst);
        inst = await WebAssembly.instantiate(mod, go.importObject);
    }
</script>

<button onClick=”run();” id=”runButton” disabled>Run</button>
</body>
</html>

The HTML code is from Go Authors, to instantiate a WebAssembly flow that connects your Go code to the web page.

Starting a web server to run the page

You will configure the server with the http package. import the http package and the Log in package to log possible errors to the console.

import (
    "log"
    "net/http"
)

You can declare variables for the address of the server and the directory of the files you want to serve at the address.

var (
    serverAddr = ":8080"
    directory = "."
)

you can use the File server method of http package to serve files in a specified directory. The File server The method takes the directory and returns a file server instance.

func main() {
    serveFiles := http.FileServer(http.Dir(directory))
    if err := http.ListenAndServe(serverAddr, serveFiles); err != nil {
        log.Fatalln(err)
}
}

In it major function, declared a file server instance variable to serve the files in the root directory. The listenandserve The method serves the files in the specified directory on the specified port.

result of loading WASM in the browser

WebAssembly functions in Go

Go provides functionality to call JS functions and interact with the DOM in the system call/js package.

The js The package provides access to the WebAssembly host environments on the js/wasm architecture. You will need to have your development environment set up for the GOARCH=wasm GOOS=js to access and use the package.

js package document preview

You can use the various methods in the package to interact with your web page. This is how you can register functions with the js package.


func print(this js.Value, i []js.Value) interface{} {
    return js.ValueOf(i[:])
}

The print The function registering as a callback function will output the data passed to the function in the browser console.

You can register callback functions with the Place method of Global method of js package. The Place The method takes the function handle and a callback function instance.

func RegisterCallbackFunctions() {
    js.Global().Set("print", js.FuncOf(print))
}

The Callback registration functions The method records the print they work like a callback function that you can use in the browser console.

WebAssembly is an experimental feature in many languages, including Go

WebAssembly features are relatively new to many languages, especially since the language recently became a W3C standard. The js The package is experimental and exempt from the promise of compatibility with Go.

Leave a Reply

Your email address will not be published. Required fields are marked *