100日後にRustをちょっと知ってる人になる: [Day 27]Wasm プロジェクトの作り方あれこれ
Day 27 のテーマ
この数日間、Rust を使っての WebAssembly プロジェクトの作成やビルドについて調べてきました。ただ、WebAssembly バイナリを作るだけにしても、いろいろな作り方があることがわかりました。
場当たり的に確認をしていたので、ここで一度整理をしておこうと思います。
WebAssembly プロジェクトの作成
Rust はコンパイラが標準で WebAssembly に対応しているので、敢えて特別なプロジェクト構成にしなくても WebAssembly バイナリのビルドを行うことは可能です。ですが、Rust のパッケージマネージャの Cargo を使うことで便利になったりなど、いろいろなプロジェクト作成の方法がありました。
- プレーンディレクトリ (
mkdir) cargo newcargo generatewasm-pack newnpm init rust-webpacknpm init wasm-app
プレーンディレクトリ (mkdir)
これは、適当なディレクトリを設けてそこで自由に構成して rustc コマンドで直接コンパイルするような場合のみな気がします。
Day 20 で WASI のビルドを行ったときにも適当なディレクトリをプロジェクトを開発ディレクトリとして扱いました。
cargo new
これは、Cargo によるパッケージ管理とビルドの仕組みを利用するためのプロジェクト構成です。Cargo.toml に依存関係などを定義しておくことで自動でライブラリモジュールの取得などを行ってくれます。
cargo build --target wasm32-wasi のように、--target を指定して WebAssembly バイナリのビルドを行います。
cargo generate
これは、定義済みのプロジェクトテンプレートを用いてプロジェクト構成を作成します。
cargo generate --git https://github.com/rustwasm/wasm-pack-template のように GitHub に公開されたプロジェクトテンプレートを直接指定してプロジェクトを作成する事ができます。
wasm-pack new
これは、Web ブラウザで WebAssembly を動作させることを目的としたプロジェクト構成です。Cargo.toml には標準で以下のクレートが登録されています。
- wasm-bindgen
- cdylib
- rlib
また、今までのプロジェクトとは異なり、コンパイルターゲットとして、wasm32-unknown-unknown が想定されています。
wasm-pack build を行うと暗黙的に wasm32-unknown-unknown が指定されてビルドされています。
npm init rust-webpack
これは、Rust, WebAssenbly そして Webpack 用の npm パッケージである create-rust-webpack によりプロジェクトが構成されます。
npm run build でビルドすることで、暗黙的に wasm-pack build も内部で行われています。
npm init wasm-app
これは、Rust で生成された WebAssembly を含む npm パッケージを使用して、Webpack でバンドルするプロジェクトを作るための npm テンプレート create-wasm-app を使ったプロジェクトです。つまり、このプロジェクト構成のみでは、Rust のコード構成が含まれていません。wasm-pack-template と組み合わせて、Rust と JavaScript のプロジェクトの構成にすることができます。
WebAssembly プロジェクトのビルド
Rust による WebAssembly プロジェクトのビルドも、プロジェクトのタイプにより複数ありました。そこで以下のように整理しておきます。
rustc --target wasm32-wasirustc --target wasm32-unknown-unknowncargo build --target wasm32-wasicargo build --target wasm32-unknown-unknown-
cargo wasi build// wasm32-wasi 指定 -
wasm-pack build// wasm32-unknown-unknown 指定 npm run build
WebAssembly プロジェクトのテンプレート
npm init rust-webpack や npm init wasm-app によりプロジェクト構成が自動生成されるように、WebAssemblyでは予め定義されたプロジェクトテンプレートが以下のように公開されています。
wasm-pack-template
wasm-pack で使用する Rust および WebAssembly のためのプロジェクトです。
wasm-pack new
cargo generate --git https://github.com/rustwasm/wasm-pack-template.git
create-wasm-app
wasm-pack で Rust から作成された npm から使用する JavaScript のプロジェクトです。
cd <WASM_PROJECT>
npm init wasm-app <PROJECT_NAME>
rust-webpack-template
Rust を WebAssembly にコンパイルし、Webpack の rust-loader で Webpack のビルドパイプラインに直接フックするための定型文が全て予め設定されているプロジェクトです。
npm init rust-webpack <PROJECT_NAME>
Day 27 のまとめ
WebAssembly のプロジェクトの作り方、ビルドの仕方、そしてプロジェクトのテンプレートについて整理してみました。
ブラウザ上での動作 (wasm32-unknown-unknown) を考えるか、それ以外の用途 (WASI) で考えるか (wasm32-wasi) で、プロジェクトの作り方とビルドの仕方が変わってくるってことですね。
Discussion