Go言語が、WebAssemblyを標準でサポートしているということで、実際に動かしてみました。
ブラウザでJavaScript経由で呼び出します。
参考)
https://atmarkit.itmedia.co.jp/ait/articles/2305/19/news002.html
環境は前回のProtocolBufferと同じで、Go は、v1.20.5 です。
前準備
mkdir go_wasm
cd go_wasm
go mod init sample
go get github.com/shurcooL/goexec
go install github.com/shurcooL/goexec@latest
main.go (用意するのはこれだけ)
1 2 3 4 5 |
package main import "fmt" func main() { fmt.Println("Hello, WebAssembly!") } |
コンパイル
GOOS=js GOARCH=wasm go build -o test.wasm main.go
ファイル確認
% file test.wasm
test.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)
Webで実行させるために生成されたファイルをカレントにコピー
cp $(go env GOROOT)/misc/wasm/wasm_exec.js .
cp $(go env GOROOT)/misc/wasm/wasm_exec.html .
WebServerの起動
~/go/bin/goexec ‘http.ListenAndServe(
:8080
, http.FileServer(http.Dir(.
)))’
参考サイトそのままですが、それだけ何もいじることをしなくても良い、というシンプルな仕組みになっています。
miscフォルダにrunボタンでwasmを実行するjsとhtmlを生成することは、至れり尽くせりだと思いました。
wasmは、バイナリでありながら様々な場所で実行できるため、いろいろな使われ方をします。またGoも様々な使われ方を考えたいろいろな機能を持っています。今回はとりあえず、やってみた、という感じですが、次はデータのやり取りなどやってみようと思っています。
以下にhtmlを引用します。jsはサイスが大きいためとりやめ。
wasm_exec.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<!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> <!-- Add the following polyfill for Microsoft Edge 17/18 support: <script src="https://cdn.jsdelivr.net/npm/text-encoding@0.7.0/lib/encoding.min.js"></script> (see https://caniuse.com/#feat=textencoder) --> <script src="wasm_exec.js"></script> <script> if (!WebAssembly.instantiateStreaming) { // polyfill 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("test.wasm"), go.importObject).then((result) => { mod = result.module; inst = result.instance; document.getElementById("runButton").disabled = false; }).catch((err) => { console.error(err); }); async function run() { console.clear(); await go.run(inst); inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance } </script> <button onClick="run();" id="runButton" disabled>Run</button> </body> </html> |