TL;DR; Rust、Node.js、wasm-pack、webpack、そしてwebpack-dev-serveが必要です

2019年3月の時点で、何が必要がわからなかったのでまとめました。

Rustを使ってWebAssemblyを出力するまでの流れ

RustはそのままでもWebAssembly(以下、WASM)に出力することはできます。しかしJavaScriptとの連携を考えると、wasm-packを使うのが、一番簡単です。

プロジェクトの作成から、作ったWASMをWebブラウザーで動かすまでの流れは、こんな感じです:

    1. Cargoでプロジェクトを作成

 

    1. Rustでプログラムを書く

 

    1. wasm-packを使って、RustをWASMを出力。

 

    1. WASMを利用するJSを書く

 

    1. JSとWASMをバンドルする

 

    1. サーバーで作ったものを配信する

 

    ブラウザーでアクセスする

Rustをビルドした後に、JSをビルドするというところがコツです。

プロジェクトを始める前に必要なもの

プロジェクトを始める前に、次の2つは必要です。

    • rustupとRustコンパイラー

Node.jsとnpm(http://npmjs.com/)
wasm-pack

rustupの使い方はこちらの記事を参照してください。

wasm-packのインストールは、Rustをインストールした後です。次のようにCargoを使えばインストールできます。

% cargo install wasm-pack

プロジェクトの準備

Cargoを使ってプロジェクトを作成します。ライブラリとして作ります。

% cargo new --lib hello-world 

つくったら、cargo.tomlに依存するライブラリを追加していきます。最低でも、次のようにwasm-bindgenは追加します。

[package]
name = "greet"
version = "0.1.0"
authors = ["chikoski <some.email.address@example.com>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2.37"

詳しくはwasm-bindgenのドキュメントを参照してください。

JavaScript開発の準備

wasm-packコマンドでビルドすると.wasmファイルに加えて、WASMからエクスポートされた関数をラップした関数や、文字列やオブジェクトをWASM-JS間でやり取りするためのユーティリティなどが定義されているJSファイルも作成されます。これらはpkgフォルダ以下に配置されています。

/ 
├── Cargo.lock
├── Cargo.toml
├── bin
├── pkg
├── src
├── target
├── wasm-pack.log

ビルド直後のプロジェクトフォルダ直下は上記のようになっています。

JSプロジェクトへの組み込みかた

作成したWASMファイルをJSへ組み込むには、2つの選択肢があります。

    1. JSのプロジェクトを別に作り、そちらからnpmパッケージとしてインポートする

 

    Rustのソースコード中に、JSのコードも配置する

どちらの場合でもWebpackを使ってビルドします。フォルダの配置が異なるので、webpack.config.jsの内容や、package.jsonの記述が少し変わります。

Webpackを使ってビルド

wasm-packで出力されるJSは、次のようにWASMファイルをインポートしています。WASMのモジュールと、JSのモジュールの相互運用は提案されていますが、利用できる実行環境はありません。したがって、Webpackを使いビルドして、現在の環境でも利用できるコードを生成します。

プラグインなしでもWebpackはWASMを処理できます。もし、JSのビルドに合わせてRustのビルドも行いたい場合は、@wasm-tool/wasm-pack-pluginというプラグインを使います。

Webサーバーに配置する際の注意

Webpackで出力されたコードは、WASMファイルをストリームコンパイルします。

WASMファイルはapplication/wasmというコンテントタイプで配信されなければなりません。webpack-dev-serverは特に設定する必要ありませんが、他の場合は設定の追加が必要な場合があります。

まとめ

wasm-packとWebpackが、よしなにしてくれます。特にWebpackは特別なプラグインなしで使えるのは楽でした。

どういうコードを書けば良いかは、wasm-bindgenのチュートリアルをやると、見えてくると思います。