🦀

100日後にRustをちょっと知ってる人になる: [Day 27]Wasm プロジェクトの作り方あれこれ

2022/09/20に公開

Day 27 のテーマ

この数日間、Rust を使っての WebAssembly プロジェクトの作成やビルドについて調べてきました。ただ、WebAssembly バイナリを作るだけにしても、いろいろな作り方があることがわかりました。
場当たり的に確認をしていたので、ここで一度整理をしておこうと思います。

WebAssembly プロジェクトの作成

Rust はコンパイラが標準で WebAssembly に対応しているので、敢えて特別なプロジェクト構成にしなくても WebAssembly バイナリのビルドを行うことは可能です。ですが、Rust のパッケージマネージャの Cargo を使うことで便利になったりなど、いろいろなプロジェクト作成の方法がありました。

  • プレーンディレクトリ (mkdir)
  • cargo new
  • cargo generate
  • wasm-pack new
  • npm init rust-webpack
  • npm init wasm-app

プレーンディレクトリ (mkdir)

これは、適当なディレクトリを設けてそこで自由に構成して rustc コマンドで直接コンパイルするような場合のみな気がします。

Day 20WASI のビルドを行ったときにも適当なディレクトリをプロジェクトを開発ディレクトリとして扱いました。

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 には標準で以下のクレートが登録されています。

また、今までのプロジェクトとは異なり、コンパイルターゲットとして、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-wasi
  • rustc --target wasm32-unknown-unknown
  • cargo build --target wasm32-wasi
  • cargo build --target wasm32-unknown-unknown
  • cargo wasi build // wasm32-wasi 指定
  • wasm-pack build // wasm32-unknown-unknown 指定
  • npm run build

WebAssembly プロジェクトのテンプレート

npm init rust-webpacknpm 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) で、プロジェクトの作り方とビルドの仕方が変わってくるってことですね。

GitHubで編集を提案

Discussion