Contents
- 1 概要 — 初心者・実務者・上級者別の短い案内
- 2 Wasm の概念とプラットフォーム差分(ブラウザ / Node / WASI)
- 3 互換性マトリクス(ブラウザ / Node / Wasm ランタイムと機能サポート)
- 4 最小プロジェクトとファイル構成(ブラウザ向けの実践サンプル)
- 5 ビルドフローとツールの使い分け(wasm-bindgen / wasm-pack / trunk / wasm-opt)
- 6 デバッグ・テスト・CI・デプロイ(運用面の実務チェックリスト)
- 7 セキュリティと運用上の注意点
- 8 よく使われるユースケース別の推奨ターゲット
- 9 よくあるトラブルと診断コマンド
- 10 参考情報(公式ドキュメントを優先)
- 11 まとめ
概要 — 初心者・実務者・上級者別の短い案内
ここでは読者の技術レベル別に、まず何をすべきかを端的に示します。短時間で動かしたい人、チーム導入で気をつける点、深い最適化や機能差の確認ポイントを分けて提示します。
初心者向けの短い案内
最短でブラウザ上に Wasm を動かすための簡潔な手順です。
- Rust を公式手順でインストールし、stable toolchain を有効にする(スクリプト実行時は内容を確認してください)。
- プロジェクトをライブラリ(crate-type = ["cdylib"])で作成する。
- wasm-pack または wasm-bindgen を使ってパッケージ化し、Vite 等で読み込む。
- ローカルで HTTP サーバを立てて .wasm が Content-Type: application/wasm で配信されることを確認する。
実務者(導入担当)向けの要点
チームやプロダクションで運用する際の優先事項をまとめます。
- rust-toolchain で toolchain をピン留めし、Cargo.lock を管理する。
- CI で同じ手順を再現し、ビルドアーティファクト(.wasm、パッケージ)を署名/ハッシュ化して保存する。
- 配信はハッシュ付きファイル名+長期キャッシュ+SRI を組み合わせる。
- 重要ヘッダ(Content-Type、COOP/COEP、Cache-Control)とプリコンプレス(.br/.gz)を設定する。
上級者向けの注目点
高性能化や複雑な環境で使う際のチェックポイントです。
- スレッド/SIMD を使う場合はランタイムのサポートとビルドフラグを確認する。
- wasm-opt や LTO の効果を測定し、デバッグ可能性とのトレードオフを整理する。
- WASI の権限(ファイル/ネットワーク)設計は最小権限で行う。
- 依存クレートは定期的に監査(cargo-audit/cargo-deny)する。
Wasm の概念とプラットフォーム差分(ブラウザ / Node / WASI)
Wasm はバイナリ実行フォーマットで、各ランタイムごとに API と実装差があります。用途(UI向け計算/サーバ処理/CLI/エッジ)に応じてターゲットを選ぶと効率的です。以下で主要プラットフォームの特徴を整理します。
ブラウザ向け(特徴)
ブラウザは JavaScript と密に連携し、DOM 操作は JS 側が担います。非同期初期化や MIME タイプの扱い、COOP/COEP の必要性(スレッド利用時)などの実装上の注意があります。
Node 向け(特徴)
Node は V8 上で Wasm を直接実行できます。モジュール種別(CommonJS/ESM)に依存した扱いと、バイナリを扱う I/O 統合が強みです。古い Node ではスレッドなどがフラグ経由の有効化だったため、利用する Node バージョンの仕様を確認してください。
WASI 向け(特徴)
WASI はサンドボックス化された POSIX ライクな API を提供し、CLI やエッジランタイムでの実行に向いています。標準ライブラリの fs/env が使える一方で、ホスト側で明示的にアクセス権を与える必要があります(最小権限が重要です)。
機能差(threads / SIMD / bulk-memory / exceptions)
主な拡張機能はランタイムごとにサポート状況が異なります。threads は SharedArrayBuffer と COOP/COEP を要します。SIMD はコンパイラフラグとランタイム対応が必要です。bulk-memory は多くのランタイムでサポートされていますが、例外処理(exceptions)は仕様・実装が追随中で利用に注意がいります。必ず最新の公式情報を確認してください。
互換性マトリクス(ブラウザ / Node / Wasm ランタイムと機能サポート)
下表は概要です。実運用では各ランタイムの公式ドキュメントやバージョン情報を都度確認してください。
| 機能 / ランタイム | Chrome / Chromium系 | Firefox | Safari | Edge | Node | wasmtime / wasmer |
|---|---|---|---|---|---|---|
| threads(共有メモリ) | 広くサポート(要 COOP/COEP) | 広くサポート(要 COOP/COEP) | サポート状況が限定的 | Chromium 系に準拠 | 動作するがバージョン依存/フラグあり | 実験的またはランタイム依存 |
| SIMD | 広くサポート | 広くサポート | サポートあり(バージョン依存) | 広くサポート | Node のビルドで有効化可能 | 実装により可 |
| bulk-memory | 広くサポート | 広くサポート | サポートあり | 広くサポート | サポート | 実装により可 |
| exception handling | 提案段階の差異あり | 提案段階の差異あり | 部分サポート/未完 | 提案段階 | 実装差あり | 実装差あり |
| WASI syscalls | 非該当 | 非該当 | 非該当 | 非該当 | 非該当 | フルサポート(wasmtime/wasmer) |
注: 上の表は概観です。具体的なバージョンや挙動は各プロジェクトの公式リリースノートを参照してください。
最小プロジェクトとファイル構成(ブラウザ向けの実践サンプル)
ブラウザ向けに最小限で動く構成と、期待される生成物を示します。ここをベースに実務用に拡張してください。
期待されるファイル構成
以下はサンプルのディレクトリ構成例です。
|
1 2 3 4 5 6 7 8 9 10 |
my_wasm/ ├─ Cargo.toml ├─ src/ │ └─ lib.rs ├─ pkg/ # wasm-bindgen / wasm-pack の出力 └─ web/ ├─ index.html └─ src/ └─ main.js |
Cargo.toml の例
Cargo 設定の最小例です。依存バージョンは検証済みの具体的パッチを固定してください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[package] name = "my_wasm" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2" # 実運用では 0.2.x の具体的なパッチを明示すること [dev-dependencies] console_error_panic_hook = "0.1" |
src/lib.rs の例
公開 API の最小例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn greet(name: &str) -> String { format!("Hello, {}", name) } #[cfg(debug_assertions)] #[wasm_bindgen(start)] pub fn init_panic_hook() { console_error_panic_hook::set_once(); } |
フロントエンド(Vite + ESM の簡易例)
Vite から ESM で読み込む最小コード例です。初期化は非同期なので await を忘れないでください。
web/src/main.js の例:
|
1 2 3 4 5 6 7 8 9 |
import init, { greet } from '../pkg/my_wasm.js'; async function run() { await init(); console.log(greet('World')); } run(); |
web/index.html の例(モジュールとして読み込む):
|
1 2 3 4 5 6 7 8 9 10 11 |
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>Wasm sample</title> </head> <body> <script type="module" src="/src/main.js"></script> </body> </html> |
Vite の設定で .wasm をアセット扱いにすると安定します(optimizeDeps.exclude / assetsInclude 等)。
期待される生成物とビルド手順
ビルド手順(概念):
- cargo build --target wasm32-unknown-unknown --release
- wasm-bindgen target/.../release/my_wasm.wasm --out-dir pkg --target web
- あるいは wasm-pack build --target web --release を利用
- wasm-opt などで最適化(任意)
- フロントエンドビルド(Vite 等)で pkg を組み込む
期待ファイル(pkg):
- pkg/my_wasm.js
- pkg/my_wasm_bg.wasm
- pkg/package.json(必要に応じて)
必ずローカルで実際に動作確認し、.wasm が正しい Content-Type で配信されることを確認してください。
ビルドフローとツールの使い分け(wasm-bindgen / wasm-pack / trunk / wasm-opt)
目的や配布形態に応じてツールを使い分けます。ここでは典型的な選択肢と注意点を示します。
典型的なビルド手順(wasm-bindgen を用いる場合)
wasm-bindgen を明示的に使うフローは以下のようになります。各ステップで生成物を確認してください。
- cargo build --target wasm32-unknown-unknown --release
- wasm-bindgen target/wasm32-unknown-unknown/release/my_wasm.wasm --out-dir pkg --target web
- wasm-opt -Oz -o pkg/my_wasm_bg.wasm pkg/my_wasm_bg.wasm (任意だが検証必須)
最終的には pkg 配下の JS/wasm をフロントエンドに取り込みます。
wasm-pack の使い分け
wasm-pack は配布先に応じて target を切り替えます。
- --target web: ブラウザで直接 import する ESM を生成
- --target bundler: webpack/Vite 等のバンドラ経由で利用
- --target nodejs: Node 向けのラッパーを生成
配布形態とバンドラの要件に合わせて選択してください。
最適化(Cargo プロファイルと wasm-opt)
サイズ最適化の一例として release プロファイルを調整します。副作用(デバッグ情報削除やパニック挙動の変更)があるため検証してください。
|
1 2 3 4 5 6 7 8 |
[profile.release] opt-level = "z" lto = true codegen-units = 1 debug = false panic = "abort" incremental = false |
wasm-opt による最終パスは大きく効果を出すことがありますが、挙動変化がないか必ずテストしてください。
マルチスレッド / SIMD のビルド(注意点)
スレッドや SIMD を使う場合はコンパイルフラグとランタイム側の要件が重要です。多くの場合、以下を確認します。
- コンパイル時に atomics/ bulk-memory / mutable-globals を有効にする必要がある(RUSTFLAGS の設定など)。
- ブラウザでスレッドを使うには SharedArrayBuffer を有効化し、COOP/COEP ヘッダが必要。
- wasm-bindgen-rayon 等の既存ライブラリを利用すると実装が簡単になる場合がある。
この領域はランタイム依存性が大きいため、公式ガイドに従って慎重に構築してください。
デバッグ・テスト・CI・デプロイ(運用面の実務チェックリスト)
運用に必要なデバッグ手法、CI 設定の方針、配信時の注意点をまとめます。CI や CDN 設定は再現性とセキュリティを重視してください。
デバッグとログ出力
- 開発時は console_error_panic_hook を有効にして JS コンソールでトレースを見る。
- wasm2wat や wasm-objdump でバイナリを解析する。
- wasm-sourcemap を利用すれば Rust へのマッピングが可能だが、構築と配布の運用が必要です。
- 例: wasm2wat pkg/my_wasm_bg.wasm -o out.wat
テストと CI(GitHub Actions の概念例)
CI はビルド再現性、キャッシュ、アーティファクト管理を重視します。概念例:
- checkout → setup Rust/Node → ターゲット追加 → ビルド → wasm-bindgen/wasm-pack → wasm-opt → アーティファクト保存
- キャッシュ: cargo ~/.cargo/registry と target ディレクトリをキャッシュ
- アーティファクト: 生成した pkg/ をアップロードし、署名(sigstore/cosign 等)やハッシュを保存する
ワークフローではツールのバージョンを固定し、ビルド環境を再現できるようにしてください。
配布時のヘッダと CDN 設定
配信時に確認すべき主要設定です。
- Content-Type: application/wasm を設定する。
- 圧縮: pre-compressed(.br/.gz)を用意するか CDN のプリコンプレス機能を使う。
- Cache-Control: ハッシュベース運用で長期キャッシュを設定する。
- SRI: サブリソースインテグリティで配信ファイルの改ざんを検出する。
- COOP / COEP: SharedArrayBuffer を使う場合は Cross-Origin-Opener-Policy と Cross-Origin-Embedder-Policy を設定する。
- CSP: 必要に応じて script-src 等で制限をかける。
SRI のハッシュはビルド時に生成し、HTML の参照に組み込む運用を推奨します。
セキュリティと運用上の注意点
Wasm を利用する上での具体的なセキュリティ対策を述べます。特にホスト側アクセスや依存管理は重要です。
権限設計と最小権限の原則
WASI やネイティブバインディングを使う場合、ホストアクセスは最小化してください。ランタイム(wasmtime 等)では事前にディレクトリやネットワークアクセスを明示的に許可する方式が一般的です。不要なアクセスは与えないでください。
依存クレートの監査と SBOM
- 依存ライブラリは cargo-audit / cargo-deny 等で定期的にチェックしてください。
- サプライチェーン対策として SBOM(ソフトウェア部品表)や依存ロックファイルの管理を導入してください。
ブラウザ特有の安全対策(COOP / COEP / SRI / CSP)
- SharedArrayBuffer を使う場合は COOP/COEP を適切に設定してください。
- SRI と CSP で配信ファイルの整合性と実行元を制限してください。
- XSS、動的スクリプト挿入などの基本的な防御策も継続して適用してください。
よく使われるユースケース別の推奨ターゲット
ユースケースに応じたターゲット選びの指針です。短い理由も添えます。
フロントエンドの計算オフロード(ブラウザ)
推奨ターゲット: wasm32-unknown-unknown + wasm-bindgen(または wasm-pack --target web)
理由: JS との連携が容易で、UI と計算を分離できるため応答性が向上します。
サーバーサイドのバイナリ処理(Node)
推奨ターゲット: wasm-pack --target nodejs または直接 ESM を使う
理由: Node 上で軽量にサンドボックス化されたバイナリ処理を行えます。モジュール種別に注意してください。
CLI・エッジ環境(WASI)
推奨ターゲット: wasm32-wasi(実行は wasmtime / wasmer 等)
理由: 権限を明示しやすく、サーバレスやエッジでの実行に適しています。
よくあるトラブルと診断コマンド
典型的な問題と初期診断コマンドの例を示します。まずは環境・バージョン確認から行ってください。
- ターゲット未追加
- 対処: rustup target add wasm32-unknown-unknown
- __wbindgen_throw 等の未定義 import
- 対処: wasm-bindgen で JS ラッパーを生成しているか確認する
- import / require のエラー(Node)
- 対処: package.json の "type" を確認し、ESM / CommonJS を合わせる
- .wasm が正しい Content-Type でない
- 確認: curl -I https://your.domain/file.wasm でヘッダを確認
- wasm-opt 後に動作が変わった
- 対処: 最適化前後で機能テストを自動化して比較する
診断に使えるコマンド例:
- rustc --version
- cargo --version
- node --version
- wasm-pack --version
- wasm2wat pkg/my_wasm_bg.wasm -o out.wat
参考情報(公式ドキュメントを優先)
以下は主要な一次情報です。実運用では必ず公式ドキュメントを確認してください。
- Rust(公式): https://rust-lang.org
- MDN WebAssembly: https://developer.mozilla.org/ja/docs/WebAssembly
- wasm-bindgen: https://github.com/rustwasm/wasm-bindgen
- wasm-pack: https://rustwasm.github.io/wasm-pack/
- Binaryen / wasm-opt: https://github.com/WebAssembly/binaryen
- wasmtime: https://github.com/bytecodealliance/wasmtime
- wasmer: https://wasmer.io
- Trunk: https://trunkrs.dev
- Vite: https://vitejs.dev
コミュニティ記事は補助資料として有用ですが、技術的に重要な箇所は必ず上記一次情報で確認してください。
まとめ
Wasm を実務で使うにはターゲット設計(ブラウザ / Node / WASI)を初期に決めることが鍵です。初心者はまずブラウザ向けで最小実装を動かし、実務者はツールのバージョン固定と CI・配信ヘッダ・SRI を整備してください。上級者はスレッド/SIMD や最適化の効果と互換性を検証し、依存の監査と最小権限設計を徹底してください。公式ドキュメントを参照し、インストール時はスクリプトの内容確認やパッケージマネージャ経由の導入を優先してください。