Contents
1. Rust と WebAssembly の基礎
1.1 コンポーネントモデルとは
WebAssembly Component Model は、Wasm モジュールを再利用可能な部品(コンポーネント)として組み合わせるための新規標準です。従来はモジュール間でインターフェースが暗黙的だったため型安全性が担保しにくかった点が課題でしたが、WIT (WebAssembly Interface Types) によって インターフェースを明示的に定義 できるようになり、複数言語間の相互運用が安全かつ簡潔になります。
参考 – WIT 仕様(MDN)[1]
実装例(.wit ファイル)
|
1 2 3 4 |
interface greeting { fn greet(name: string) -> string; } |
このインターフェースは wit-bindgen や cargo-component が自動で Rust 側の型へ変換し、JavaScript からは同名関数として呼び出せます。
1.2 WASI の役割
WASI (WebAssembly System Interface) は ファイル I/O・ネットワークなどのシステムコールを Wasm に提供 するサブセットです。ブラウザ外(CLI、サーバー、組み込みデバイス)で Rust 製 Wasm を安全に実行したい場合に必須となります。
簡易例(wasm32-wasi ターゲット)
|
1 2 3 4 5 6 |
use std::fs; #[no_mangle] pub fn read_file() -> String { fs::read_to_string("data.txt").unwrap_or_default() } |
このバイナリは Wasmtime などの WASI ランタイムでそのまま動作しますが、ブラウザでは利用できません。
2. ツールチェーンの構築(2026 年版)
注記:以下に示すバージョンは「執筆時点」で確認できた最新リリースです。実際のインストール時には
--versionオプションで最新版かどうかを必ず確認してください。
2.1 Rustup とコンパイラ
| ツール | 推奨取得方法 | 確認コマンド |
|---|---|---|
| rustup | https://rustup.rs(公式インストーラ) | rustup --version |
| rustc (stable) | rustup toolchain install stable |
rustc --version |
| wasm32-unknown-unknown / wasm32-wasi ターゲット | rustup target add … |
- |
|
1 2 3 4 5 6 |
# Linux/macOS の例 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source "$HOME/.cargo/env" rustup update stable rustup target add wasm32-unknown-unknown wasm32-wasi |
出典 – rustup ドキュメント[2]
2.2 Node.js と nvm
| ツール | 推奨取得方法 | 確認コマンド |
|---|---|---|
| nvm (Unix 系) | https://github.com/nvm-sh/nvm(install script) | nvm --version |
| Node 20 LTS | nvm install 20 && nvm use 20 |
node -v |
|
1 2 3 4 5 |
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.nvm/nvm.sh nvm install 20 nvm use 20 |
出典 – nvm README[3]
2.3 Wasm 関連ツール
| ツール | 推奨インストール方法 | 確認コマンド |
|---|---|---|
| wasm-pack | cargo install wasm-pack --locked(バージョンはリリースページで確認) |
wasm-pack --version |
| cargo-wasi | cargo install cargo-wasi |
cargo wasi --version |
| wit-bindgen-cli / cargo-component | cargo install wit-bindgen-cli cargo-component |
wit-bindgen --version、cargo component --version |
|
1 2 3 4 5 |
# 例:バージョン指定(2026 年初期リリース) cargo install wasm-pack --locked --vers 0.12.1 # リリースページ https://github.com/rustwasm/wasm-pack/releases cargo install cargo-wasi cargo install wit-bindgen-cli cargo-component |
注意:
wasm-packのバージョンは GitHub Releases ページで最新を確認してください。
2.4 バイナリ最適化ツール(binaryen)
|
1 2 3 4 |
# macOS (Homebrew) / Ubuntu (apt) brew install binaryen # macOS sudo apt-get update && sudo apt-get install -y binaryen # Ubuntu |
3. ハンズオン:Hello World アプリの作成
3.1 プロジェクト構造と Cargo.toml 設定
|
1 2 3 |
git clone https://github.com/rustwasm/wasm-hello-world.git cd wasm-hello-world |
ディレクトリ構成(抜粋)
|
1 2 3 4 5 6 7 8 |
wasm-hello-world/ ├─ src/ │ └─ lib.rs ├─ Cargo.toml └─ www/ ├─ index.html └─ package.json |
Cargo.toml のポイント:
|
1 2 3 4 5 6 7 8 9 10 11 |
[package] name = "wasm_hello_world" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] # Wasm 用に必須 [dependencies] wasm-bindgen = "0.2.92" # 2026 年時点の最新 |
3.2 ビルドフロー(cargo → wasm-pack)
|
1 2 3 4 5 6 |
# 1️⃣ Rust 側だけでコンパイルしてエラーを早期検出 cargo build --target wasm32-unknown-unknown # 2️⃣ wasm-pack がバインディングと npm パッケージ化を実行 wasm-pack build --target web --out-dir ./www/pkg --release |
生成物(www/pkg/)
wasm_hello_world_bg.wasm – 実体バイナリ
wasm_hello_world.js – JS グルーコード
* package.json – npm 用メタ情報
3.3 ブラウザでの実行確認
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!-- www/index.html --> <!DOCTYPE html> <html lang="ja"> <head><meta charset="utf-8"><title>Hello Wasm</title></head> <body> <script type="module"> import init, { greet } from "./pkg/wasm_hello_world.js"; async function run() { await init(); // .wasm のロード console.log(greet("Wasm")); // => "Hello, Wasm!" } run(); </script> </body> </html> |
ローカルサーバは MDN が推奨する Python http.server または Node の serve を利用します。
|
1 2 3 4 5 |
cd www python -m http.server 8000 # http://localhost:8000/ # または npx serve . -l 8000 |
コンソールに "Hello, Wasm!" が出れば成功です。
4. JavaScript ↔ Rust の相互操作とデバッグ手法
4.1 Rust 側のエクスポート例(文字列加工)
|
1 2 3 4 5 6 7 |
use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn reverse(input: &str) -> String { input.chars().rev().collect() } |
JS 呼び出し
|
1 2 3 4 5 |
import init, { reverse } from "./pkg/wasm_hello_world.js"; await init(); console.log(reverse("Rust")); // "tsuR" |
4.2 DOM 操作(web-sys)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
use wasm_bindgen::prelude::*; use web_sys::{window, HtmlElement}; #[wasm_bindgen(start)] pub fn start() -> Result<(), JsValue> { let doc = window().unwrap().document().unwrap(); let btn: HtmlElement = doc.create_element("button")?.dyn_into()?; btn.set_inner_text("クリックしてね"); let closure = Closure::wrap(Box::new(move || { web_sys::console::log_1(&"ボタンが押されました".into()); }) as Box<dyn FnMut()>); btn.add_event_listener_with_callback("click", closure.as_ref().unchecked_ref())?; // メモリリーク防止 closure.forget(); doc.body().unwrap().append_child(&btn)?; Ok(()) } |
4.3 デバッグのベストプラクティス
| 手順 | 内容 |
|---|---|
| ローカルサーバ | CORS が有効になる http:// 経由でロード(file:// は NG)。 |
| DevTools → Sources | .wasm が表示されるのでブレークポイントを設定可能。 |
console.log! と debugger; |
Rust 側の web_sys::console::log_1 でメッセージ出力、JS 側に debugger; を埋め込んで一時停止。 |
| サイズ確認 | wasm-objdump -x target.wasm(binaryen に同梱)でシンボル情報をチェック。 |
参考 – MDN のローカルサーバガイド[4]
5. パフォーマンス最適化・CI/CD
5.1 バイナリサイズ削減
|
1 2 3 4 5 6 |
# binaryen の wasm-opt を使う例 wasm-opt -Oz \ --strip-debug \ --vacuum \ -o pkg/wasm_hello_world_opt.wasm pkg/wasm_hello_world_bg.wasm |
| フラグ | 効果 |
|---|---|
-Oz |
サイズ最優先の最適化 |
--strip-debug |
デバッグ情報除去 |
--vacuum |
未使用セクション削除 |
5.2 コンポーネント単位でのコード分割
- WIT ファイルを機能ごとに作成(例:
image_processor.wit,text_utils.wit) - 各ディレクトリで
cargo component build --releaseを実行 →.wasmが独立したコンポーネントとして出力。
これにより 必要な機能だけをオンデマンドでロード でき、初回ダウンロードサイズが劇的に削減されます。
5.3 GitHub Actions による自動ビルド・最適化
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
name: Build & Deploy Wasm on: push: branches: [ main ] pull_request: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Rust toolchain + WASI targets - name: Set up Rust uses: dtolnay/rust-toolchain@stable with: targets: wasm32-unknown-unknown,wasm32-wasi # Cache Cargo registry & build artefacts - uses: actions/cache@v3 with: path: ~/.cargo/registry key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} # Install wasm-pack と binaryen - name: Install tools run: | cargo install wasm-pack --locked --vers 0.12.1 # 必要に応じてバージョン更新 sudo apt-get update && sudo apt-get install -y binaryen # Build & optimise - name: Build with wasm-pack run: | wasm-pack build --target web --release wasm-opt -Oz -o pkg/wasm_hello_world_opt.wasm pkg/wasm_hello_world_bg.wasm # Simple test (Node) - name: Run Node tests run: | npm install -g @wasm-tools/wasm-objdump wasm-objdump -x pkg/wasm_hello_world_opt.wasm | grep "type section" # Deploy to GitHub Pages - name: Publish uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./www |
このワークフローは プッシュ / PR のたびに最適化済み Wasm を生成し、GitHub Pages に自動デプロイします。CI キャッシュを利用することでビルド時間が大幅に短縮されます。
6. ブラウザ別コンポーネントモデル対応状況(2026 年 1 月時点)
| ブラウザ | バージョン | MVP 実装 | コンポーネントモデル実装 |
|---|---|---|---|
| Chrome | 122 | ✅ 完全 | ✅ デフォルトで有効(--enable-experimental-webassembly-components フラグは不要) |
| Edge | 124 | ✅ 完全 | ✅ Chrome と同様にサポート |
| Safari | 17 | ✅ 完全 | ⚠️ 実験的フラグ WebAssembly.componentModel が必要(設定方法は WebKit のリリースノート参照) |
実装時の留意点
- Chrome / Edge はフラグ不要なのでそのまま
importが可能。 - Safari は実験フラグが必要なため、テスト用に
--enable-experimental-webassembly-componentsを付与した起動オプションか、about:configで有効化してください。 - フォールバック:
WebAssembly.compileStreamingが失敗した場合はfetch().then(r => r.arrayBuffer())に切り替えるコードを用意すると、Safari の実験フラグが無い環境でも動作します。
7. まとめ
- コンポーネントモデルと WASI が Rust ↔ Wasm 開発の根幹を成し、型安全かつモジュール化されたアーキテクチャを実現。
- 2026 年版ツールチェーン(rustup・Node 20·nvm・wasm‑pack·cargo‑wasi·wit‑bindgen·cargo‑component)をインストールすれば、ローカル環境は即座に構築可能。バージョンは公式リリースページで随時確認してください。
- ハンズオン では
wasm‑hello‑worldをベースにcargo build → wasm-pack buildの二段階フローでブラウザ実行可能な Wasm が得られます。 - 相互操作・デバッグ は
#[wasm_bindgen]、web-sysと MDN 推奨ローカルサーバを組み合わせるだけで快適に行えます。 - パフォーマンス最適化 には
wasm-opt -Ozが有効で、CI に組み込むと毎回自動的にサイズ削減が保証されます。 - CI/CD は GitHub Actions + binaryen の構成がシンプルかつ高速。GitHub Pages へのデプロイまでワンステップで完結します。
- ブラウザ対応 は Chrome/Edge がフラグ不要で本格サポート、Safari は実験的フラグの有無に注意が必要です。
これらの手順とベストプラクティスを踏めば、2026 年の最新環境でも 安全・高速・モジュール化された WebAssembly アプリ を自信を持って開発・デプロイできます。 Happy coding!