GoではじめるWebAssebmly その2「JavaScriptイベントハンドリング」
WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。
WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。
一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js
パッケージを用いることで、DOMやネットワーク操作を可能にしています。
そこで今回はDOMのクリックイベントをWebAssemblyで扱う方法を紹介します。
まずGoのコードです。今回はmain.goとしています。最初に syscall/js
をインポートします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "syscall/js" |
そして、トップレベルのDOMであるドキュメントを作成します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
document := js.Global().Get("document") |
IDやクラスを使ってDOMを取得します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
button := document.Call("getElementById", "btn") |
取得したボタンに対してコールバックを指定します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cb := js.NewCallback(func(args []js.Value) { | |
println("Clicked"); | |
}) |
ボタンのクリックイベントにコールバックを指定します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
button.Call("addEventListener", "click", cb) |
最後にプログラムが終了しないようにチャネルを待ち受けます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<-make(chan struct{}, 0) |
これで完成です。全体のコードは次のようになります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "syscall/js" | |
func main() { | |
document := js.Global().Get("document") | |
button := document.Call("getElementById", "btn") | |
cb1 := js.NewCallback(func(args []js.Value) { | |
println("Clicked"); | |
}) | |
button.Call("addEventListener", "click", cb1) | |
<-make(chan struct{}, 0) | |
} |
HTMLを準備する
HTMLはボタンを貼り付けだけのものです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="wasm_exec.js"></script> | |
<script> | |
const go = new Go(); | |
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => { | |
go.run(result.instance); | |
}); | |
</script> | |
</head> | |
<body> | |
<button id="btn">クリック</button> | |
</body> | |
</html> |
JavaScriptファイルを用意する
専用のJavaScriptファイルを設置します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" . |
Goをコンパイルする
最後にGoファイルをコンパイルして WebAssebmly化します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ GOOS=js GOARCH=wasm go build -o main.wasm |
サーバを立ち上げる
Webサーバは goexec を用います。インストールは go get -u github.com/shurcooL/goexec
になります。インストールされたら以下のコマンドでHTTPサーバを立ち上げます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ goexec 'http.ListenAndServe(":8080", http.FileServer(http.Dir(".")))' |
これで http://localhost:8080/ でアクセスできます。
試す
では実際に試しているところです。ボタンをクリックすると開発者ツールのコンソールにログが出力されます。
このようにしてGoのコードからイベントハンドリングができます。
Goを使うことでWebアプリケーションをまるっとWebAssemblyで提供できる可能性が出てきました。高速、かつコードの隠蔽化も実現しますのでWebアプリケーションの可能性を飛躍的に向上できるでしょう。
ぜひトライしてみてください。
コメントは受け付けていません。