概要
Nuxt.js v2.0.0がリリースされたので触ってみた【変更点まとめ】の記事を読んでNuxt v2ではWeb Assemblyがサポートされたらしいので、動かしてみた。
動かしてみる
Nuxtの動かし方はドキュメントのインストールのページを見れば問題ないので、Nuxtの動かし方についてはあまり言及しない。
話はWebAssemblyのファイルを準備するところから始める。とは、言っても今回うごかすWebAssemblyのファイルは爆速でjsでWebAssemblyを動かすの記事で作ったものを持ってくる。手持ちのwasmファイルがある方はそちらを利用してもいいと思う。
上記の記事で作成された以下の3つのファイルを用意して話を進める。(js_hello_world.d.ts
はもしかすると不要かもしれないが、wasm出力の際に以下の3つのファイルが出力されるのため、とりあえず3つ用意する)。これらのファイルの関係について述べておくと、js_hello_world.js
の中でjs_hello_world_bg.wasm
が呼び出されるようになっている。
- js_hello_world_bg.wasm
- js_hello_world.js
- js_hello_world.d.ts
そして持ってきたファイルを以下のjsフォルダの中に配置する。
-| assets/
----| js/
これで、動かすwasmファイルの準備はできたので、次はwasmを読み込むための準備をする。
読み込む側では、まずwasmのインポートを記述する。ただ、wasmファイルの関係性の部分で述べたとおり、js_hello_world_bg.wasm
はjs_hello_world.js
の中で呼び出されるため、js_hello_world.js
を読み込む記述をしてあげる。
<script>
...
const myWasmModule = import("~/assets/js/greet/js_hello_world");
...
</script>
今回利用するwasmファイルについて簡単に説明しておくと、greet()という関数があり、引数として文字列を渡してあげるとHello, {渡した文字列}!
と表示するalertモーダルが出るようになっている。
今回は、ボタンを用意して、クリックしたらalertモーダルが出るようにする。そのため、callGreet()というメソッドを用意し、クリックしたらcallGreet()が動くようなアプリケーションにする。
ビュー側は以下のようになる。Nuxtのプロジェクト作成時にできたaタグを少し書き換えて@click="callGreet"
を足してあげるだけだ。
...
<div class="links">
<a
@click="callGreet"
class="button--green"
>click me</a>
</div>
...
クリック時の動作については以下のようになる。こちらも基本的にはNuxtのプロジェクト作成時と変わらず、少しだけ追記をしているだけだ。モジュールはimport()によりを呼び出しているため、Promiseオブジェクトとして関数を取り出してあげる必要がある。そして、取り出した関数に表示したい文字列を渡す。
<script>
...
export default {
...
data() {
return {
myName: 'mk-tool'
}
},
methods: {
callGreet() {
myWasmModule.then(myWasmModule => myWasmModule.greet(this.myName));
},
},
...
}
</script>
やることはたったこれだけだ。プロジェクトを実行してボタンを押すと、WebAssemblyによるモジュールが読み込まれて正常に実行されることが分かる。
ソースコードはGitHubにあげています。
その他
今回はjs_hello_world.js
を読み込んだが、js_hello_world_bg.wasm
を直接呼び出してもalertモーダルが表示された。しかしながら、こちらの場合は引数部分に渡した文字列が表示されなかった。js_hello_world.js
の中身を見てみると、webassemblyのgreet()を呼び出し、受け取った引数を関数へ渡したりしていたため、我々人間はおとなしくコンパイラが出力したjs_hello_world.js
経由でjs_hello_world_bg.wasm
にアクセスしたほうが良いんだな、と感じた。
<script>
...
const myWasmModule = import("~/assets/js/greet/js_hello_world_bg");
...
</script>
参考
- import()がPromiseを返すことについて
MDN - import - 今回とはあまり関係はないがwasmのコードの実行については以下の記事が参考になった。
- WebAssembly JavaScript API を使用する
- WebAssemblyコードのロードと実行