もうすぐリリースのGo1.11ではWebAssemblyのサポートが予定されています。 (2018/08/19現在の最新版はGo1.11rc1)
正式リリース前に少し遊んでみようということで、@yuroyoroさんのGoAst ViewerをWebAssemblyへビルドしてみました。
JavaScriptの連携方法
コードをASTに変換し、JSONとしてエンコードする部分(ast.go)に関しては、一切変更しなくても動きました。素晴らしい。
ただし、さすがにブラウザ上でHTTPサーバーは動かない(そういえば試してないけど、動かないよね??)ので、JavaScriptとの連携部分を実装してあげる必要があります。 syscall/jsパッケージはまだ実験段階というステータスで機能が限られているので、 連携には少し工夫が必要です。
JavaScriptからGoの関数を呼ぶ
JavaScriptからGoの関数を呼ぶには window
にコールバック関数として必要な関数を登録します。
// GoASTParse 関数を定義(Go言語)
js.Global().Set("GoASTParse", js.NewCallback(func(args []js.Value) {
source := args[0].String()
// ...ASTへの変換処理...
}))
戻り値をGoからJavaScriptへ返す
js.NewCallback
なのですが、もともとは addEventListener
にわたすコールバック関数なので、
関数の戻り値を受けわたす方法がありません。
回避方法はいろいろあるでしょうが、今回はコールバック関数の引数にコールバック関数指定してもらうことにしました。
// GoASTParse 関数を定義(Go言語)
js.Global().Set("GoASTParse", js.NewCallback(func(args []js.Value) {
source := args[0].String()
// ...ASTへの変換処理...
args[1].Invoke(string(body))
}))
// GoASTParseを呼び出す(JavaScript)
GoASTParse("package main; func main() {}", function(body) {
// ASTの表示処理
})
まとめ
Goのバイナリ全般に言えることですが、WASMになってもやっぱりサイズが大きい(3.5M)。 今後のパフォーマンス向上に期待です。
GoよりAngulerJSの方が難しかったʕ ゚皿゚ ʔ