グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



GoのコードをWebAssenblyにコンパイルしてブラウザ上でGoを実行する

今回は、GoのコードをWebAssenblyにコンパイルしてブラウザで動かす方法を試してみたいと思います。

WebAssemblyとは

WebAssembly(wasm)はブラウザが解釈できる専用のバイナリ形式で、低レベルなアセンブリ風言語です。
Web標準として開発されており、現在では様々な言語がコンパイル後のバイナリ形式としてWebAssemblyを指定できるようになっています。

WebAssemblyにコンパイルされたプログラムはブラウザやNode.jsなどの環境で、Javascriptと一緒に実行することができます。
代表的な言語ではC、C++、Rustがあります。
Goもv1.11から標準機能として、コンパイル時にWebAssemblyが指定できるようになりました。

GoのコードをWebAssembly形式にコンパイルする

今回はgo 1.18の環境で作業を行います。

$ go version
go version go1.18 linux/amd64

まずはじめに作業用ディレクトリを作成して go mod init しておきます。

$ mkdir wasm
$ cd wasm
$ go mod init hoge.com

次に作業ディレクトリ内にgoのコードを書きます。

main.go

package main

import "fmt"

func main() {
	fmt.Println("Hello, Go Assembly!!!")
}

次のコマンドでコンパイルを行います。

$ GOOS=js GOARCH=wasm go build -o main.wasm

すると、2MB程度のmain.wasmが作成されます。
 GOOS  GOARCH はクロスコンパイル用の設定で最新情報は公式ドキュメントOptional environment variablesを参照してください。

ブラウザで実行する

出来上がったmain.wasmをブラウザで実行するにはGo公式が配布しているwasm_exec.jsを使います。

上記のファイルを作業ディレクトリ内に格納します。

HTMLファイルを作成する

wasm_exec.jsを読み込んで、コンパイルしたmain.wasmを指定するhtmlを作成します。

index.html

<html>

<head>
    <meta charset="utf-8">
    <title>Go WebAssembly</title>
</head>

<body>
    <h1>Go WebAssembly</h1>
    <script src="./wasm_exec.js"></script>
    <script>
        const go = new Go();
        let mod, instance;
        WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
            mod = result.module;
            inst = result.instance;
            document.getElementById("run").disabled = false;
        });

        async function run() {
            console.clear();
            await go.run(instance);
            instance = await WebAssembly.instantiate(mod, go.importObject);
        }
    </script>
    <button onClick="run();" id="run" disabled>Run</button>
</body>

</html>

HTTPサーバを起動する

先ほど作成したindex.htmlをHTTPで配信するためにGoでサーバを作成します。

server.go

package main

import (
	"log"
	"net/http"
)

func main() {
	http.Handle("/", http.FileServer(http.Dir("")))
	log.Fatal(http.ListenAndServe(":8080", nil))
}
$ go run server.go
 http://localhost:8080/ にアクセスして「Run」をクリックするとConsole にGoのファイルでfmtした「Hello, Go Assembly!!!」が表示されてるのがわかります。

さいごに

意外と簡単にGoのプログラムをWebAssemblyにコンパイルしてブラウザ上から実行できました。

今回は単純にコンパイル済みのGoのプログラムを実行しただけですが、Go側からJavascriptを操作したり、Javascript側からGoの関数を呼び出せたりと相互に呼び出しができるようです。
次回はそのあたりもためしてみようと思います。

この記事を書いた人

アーティス
アーティス
創造性を最大限に発揮するとともに、インターネットに代表されるITを活用し、みんなの生活が便利で、豊かで、楽しいものになるようなサービスやコンテンツを考え、創り出し提供しています。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします