https://tech-blog.optim.co.jp/entry/2020/10/28/100000
シェアしました。
はじめに
こんにちは。20年度新卒の今枝と申します。
気になっていた WebAssembly を業務ツールアプリで使ってみたので、そのときに利用した Vue.js + WebAssembly(Go) のお話をしようと思います。
今回は Go のコードで書かれた関数を、ビルドして WebAssembly として、Vue.js 上で動作させるサンプルアプリを作成します。
今回使う技術について
今回扱う技術について簡単に説明をします。
WebAssembly (WASM)
WebAssembly は、モダンなブラウザーで実行することができるバイナリー形式の言語です。 C言語、Rust や、今回扱う Go のような言語からコンパイルして生成することができます。 WebAssembly は WASM と省略して呼ばれることが多く、本記事でも WASM と記述します。 Webアプリケーションで動作している JavaScript と並行して動作するので、WebアプリケーションからGoで記述された関数を WASM 形式にコンパイルすることで呼び出すことができます。 Vue.js のような単一コンポーネントファイルを利用して、Go + WASM で Webアプリケーションを作ることのできる Vugu というライブラリも存在します。
(今回Vuguは、扱いません。)
Swift(SwiftUI) + WASM で Webアプリケーションを作ることできる Tokamak についてはこちらで解説しています。気になる方は是非ご覧ください。
Go
Goは、Googleによって開発されたオープンソースの静的型付け言語です。
言語の仕様がシンプル、高速、メモリ効率が良い、並行処理を簡単に行うことができるメリットがあり、弊社内の様々なプロジェクトでもGoが採用されています。
Goは、1.11 以上から WASM のビルドに対応していますが、現在は生成する WASM 形式のファイルサイズに問題があるようです。
公式のGoコンパイラ が生成する WASM ファイルは、最小でも約2MB,ライブラリを使用した場合は、10MB 以上になってしまうことが公式のWikiにも記載されています。 しかし、この問題を解消するための改善策が公式のWikiに記載されていたので、改善策の1つである TinyGo という Go のコンパイラを使用します。
Vue
Evan You氏が中心となって開発されているクライアントサイド JavaScript フレームワークです。Vue.jsでは、コンポーネント指向でアプリケーションなどの開発を行うことが可能です。
最近(2020年9月18日)に、Vue.js の新バージョンである Version 3 が正式リリースされて話題になりました!!
弊社内の様々なプロジェクトでも Vue.js が採用されています。
今回は、Vue.js アプリケーションのための 状態管理パターン + ライブラリである Vuex も使用します。
Vue.js から Go で実装された関数を呼び出そう
早速、Vue.js から Go で実装された関数を呼びだすサンプルのアプリを作っていきます。
環境
- npm:6.14.4
- node:v14.1.0
- yarn:1.22.4
- Vue-cli:4.5.8
- docker を動作させる環境
まず、Go の関数を作成していきます。
Go でWASMファイルを出力する
TinyGo の公式ページを参考にして、関数を定義していきます。 今回は、サンプルと同様に足し算をする関数を用意します。
//export export-name
と記述することで、Go の関数を Export して、JavaScript から Export された関数を呼び出すことができるようになります。
次に、TinyGo の docker Image を使用して、wasm ファイルを作成します。
ボリュームのマウント先は、自分の環境に合わせて行ってください。
出力されたwasm.wasm ファイルのサイズは約 7.5 KB となりました。
公式のGoコンパイラから出力されるWASMのファイルサイズよりは十分に小さいことが分かります。
Vue からGoの関数を呼び出す
構成図は、下記のようになります。
VueCLIでプロジェクトを作成します。
今回は、Vuexの Actions からWASMの関数を呼び出すので、 Vuex のライブラリにチェックを入れます。
次に、WASM ファイルを呼び出すために必要な wasm_exec.js ファイルを用意します。
これらを、main.wasm と、 wasm_exec.js ファイルをpublic配下に移動します。
次に、DevServer に WASM の MIMEtype を登録します。
今回は、DevServer でのみ動作確認をしますが、 本番環境で使用する場合もWASMのMIMEtypeを忘れないように気をつけてください。
index.html に wasm_exec.js で読み込む処理を記述します。
最後に、Vuex で WASM ファイルを読み込み、Go の関数を呼び出してあげれば完成です。
確認
任意のコンポーネントの中で、ActionsのwasmInit()
を呼び出した後に、add
関数が実行できることを確認できたら成功です。
上記のコマンドで Dev Server を起動することができます。
おわりに
Go で書かれた既存の実装を JavaScript で書き直さなくても、既存の Webアプリケーションに取り込めることが分かりました。 TinyGo では、サポートされていないパッケージもあるので事前に確認が必要です。使用可能なパッケージ
また、TinyGo で生成したWASM とJavaScript間で文字列を渡し合うのは大変みたいです。 https://alcarney.me/blog/2020/passing-strings-between-tinygo-wasm/alcarney.me
Goの標準のコンパイラでWASMを生成した場合は、文字列の受け渡しも容易にできます。( WASMファイルが大きくなってしまいますが )
いろいろな制限はありますが、既存のGoの実装をJavaScriptで再実装せずにWebフロントで動かすことができるのは嬉しいですね。
OPTiMでは、ものづくりが大好きなエンジニアのみなさんを募集しています!
0 コメント:
コメントを投稿