Go で WebAssembly を書いてみよう
今回は Web 技術の 1 つである WebAssembly を Go で作り、JavaScript から使ってみます。
WebAssembly とは
WebAssembly とはブラウザでネイティブに近いコードを実行する技術です。MDN の概要ページはこちらです。 より高速に実行されるコードを JavaScript 以外の言語で記述することができます。
WebAssembly は
.wasm
という拡張子のファイルで、サーバーからは
application/wasm という MimeType で提供します。C++や Rust
などの言語で.wasm を生成することができますが、今回は Go
で作ってみます。
本記事のサンプルはこちらにあります。デモサイトはこちらです。
環境構築
Go で WebAssembly を作るには、通常の Go
開発環境を用意するだけです。本記事では Go 1.13.4
を使用しました。また、$GOROOT
に Go
のインストール先が入っているものとして説明をします。
$ go version
go version go1.13.4 darwin/amd64
main.go を作る
早速 WebAssembly として動かすコードを Go で書きましょう。main.go としておなじみのコードを書きます。
package main
import (
"fmt"
)
func main() {
fmt.Printf("Hello wasm world!\n")
}
\n
がないと標準出力が flush
されず、動作してるか確認できなくなるので忘れずにつけておきましょう。
.wasm を作る
GOOS を js
に、GOARCH を
wasm
にしてビルドします。
$ GOOS=js GOARCH=wasm go build -o docs/main.wasm
index.html を作る
wasm
ファイルができたので、ブラウザで読み込んで実行させましょう。まずは
index.html です。wasm_exec.js
とアプリのコード(main.js)を読み込みます。
<html>
<head>
<title>WASM demo</title>
</head>
<body>
<p>See your console.log()!</p>
<script src="./wasm_exec.js"></script>
<script type="module" src="./main.js"></script>
</body>
</html>
wasm_exec.js は Go に付属しています。場所は$GOROOT/misc/wasm/wasm_exec.js
です。コピーしておきましょう。なお wasm のビルドに使った Go
のバージョンとは違うバージョンの wasm_exec.js(例えば Go 1.12.9
に付属している
wasm_exec.js)を使うと実行時にエラーとなるので注意しましょう。
main.js を作る
最後に wasm を読み込んで実行する部分です。wasm_exec.js で提供されているクラスを利用します。
const go = new Go();
const exec = async () => {
const result = await WebAssembly.instantiateStreaming(
fetch("main.wasm"),
go.importObject
);
go.run(result.instance);
};
exec();
fetch()で読み込んでいるので、実行するためにはサーバーが必要です。また、wasm
の GET に対し、Content-type: application/wasm
で返す必要があります。
実行すると、次のように Console.log()に wasm 内に記述したテキストが表示されます。

まとめ
Go で WebAssembly を記述・ビルド・実行までを説明しました。Go での開発環境があればすぐ始めれるので、みなさんもチャレンジしてみてください。