WebAssembly を学ぶための実践的なチュートリアル集です。3 つの異なるアプローチで、WebAssembly の基礎から実践まで段階的に学べます。
📦 リポジトリ: https://github.com/optimisuke/hello-wasm-with-ai
すべてのサンプルコードは上記リポジトリで公開しています。クローンして手元で試してみてください。
git clone https://github.com/optimisuke/hello-wasm-with-ai.git
cd hello-wasm-with-aiWebAssembly(WASM)は、ブラウザで高速に動作するバイナリ形式のコードです。C/C++、Rust、Go などの言語で書かれたコードをコンパイルし、JavaScript と並行して Web ブラウザで実行できます。
- 高速性: JavaScript よりも高速な実行が可能
- 移植性: 既存の C/C++/Rust コードをブラウザで動かせる
- 安全性: サンドボックス環境で安全に実行
- 汎用性: ブラウザだけでなく、サーバーサイドやエッジでも動作
このリポジトリでは、3 つの異なるアプローチで WebAssembly を体験できます:
- WAT(WebAssembly Text Format) - WebAssembly の基本を理解する
- Rust + wasm-pack - ブラウザ上で WebAssembly を動かす実践的な方法
- WASI - ブラウザ外で WebAssembly を動かす
WebAssembly はバイナリ形式のコードで、人間が直接読み書きするのは困難です。そのため、テキスト形式のWATや、Rust などのプログラミング言語から変換して使います。
graph LR
A[高級言語<br/>Rust/C/C++] -->|コンパイル| B[WASM<br/>バイナリ]
C[WAT<br/>テキスト] -->|変換| B
B -->|実行| D[ブラウザ]
B -->|実行| E[サーバー<br/>wasmtime]
WebAssembly には大きく 2 つの実行環境があります:
- ブラウザ: JavaScript と連携して Web 上で動作
- サーバー/CLI: WASI を使ってブラウザ外で動作
WAT(WebAssembly Text Format)は、WebAssembly のテキスト表現です。テキストで WebAssembly の処理を記載できます。
graph LR
A[hello.wat<br/>テキスト形式] -->|wat2wasm| B[hello.wasm<br/>バイナリ]
B -->|fetch| C[JavaScript]
C -->|WebAssembly API| D[ブラウザで実行]
(module
;; JavaScriptからログを出力する関数をインポート
(import "console" "log" (func $log (param i32)))
;; メモリを定義(1ページ = 64KB)
(memory (export "memory") 1)
;; "Hello, WASM!" という文字列をメモリに配置
(data (i32.const 0) "Hello, WASM!")
;; greet関数をエクスポート
(func (export "greet")
;; メモリの0番地を渡してログ出力
i32.const 0
call $log
)
)ポイント:
import: JavaScript の関数を WASM から呼び出せるようにするmemory: WASM と JavaScript 間でデータを共有するメモリ領域export: WASM の関数を JavaScript から呼び出せるようにする
- ✅ WebAssembly の基本構造を理解できる
- ✅ メモリの仕組みが分かる
- ✅ JavaScript 連携の基礎が学べる
- ✅ 最小限のツールで動作確認できる
→ 詳細は 1-hello-wat へ
Rust は、WebAssembly の開発において最も人気のある言語です:
- メモリ安全性が保証される
- 優れたツールチェーン(wasm-pack、wasm-bindgen)
- 高速でコンパクトな WASM を生成
- JavaScript との連携が簡単
graph TB
subgraph Rust側
A["Rustコード<br/>wasm_bindgen属性付き"]
end
subgraph wasm-pack
B[コンパイル]
C[バインディング生成]
end
subgraph 出力
D[.wasm<br/>バイナリ]
E[.js<br/>グルーコード]
end
subgraph JavaScript側
G["import { greet }"]
end
A --> B
B --> C
C --> D
C --> E
D --> G
E --> G
wasm-bindgen は、Rust と JavaScript 間の型変換やメモリ管理を自動的に処理し、.wasmバイナリと.jsグルーコードを生成します。
use wasm_bindgen::prelude::*;
// JavaScriptのalert関数をインポート
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
// greet関数をJavaScriptにエクスポート
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}ポイント:
#[wasm_bindgen]属性で関数を自動的にエクスポート- 文字列などの複雑な型も自動変換
- TypeScript 型定義も自動生成
- ✅ 実際のプロジェクトで使える構成
- ✅ 型安全な JavaScript 連携
- ✅ 複雑なデータ構造の扱い方
- ✅ モダンなツールチェーンの活用
→ 詳細は 2-hello-rust へ
WASI(WebAssembly System Interface)は、WebAssembly をブラウザの外で実行するための標準インターフェースです。ファイルシステム、ネットワークなどのシステムリソースにアクセスできます。
graph TB
subgraph ブラウザWASM
A1[WASM] --> B1[JavaScript API]
B1 --> C1[DOM/Web API]
end
subgraph WASI
A2[WASM] --> B2[WASI API]
B2 --> C2[ファイルシステム]
B2 --> D2[ネットワーク]
end
| 項目 | ブラウザ | ブラウザ以外 (+WASI) |
|---|---|---|
| 実行環境 | ブラウザ | コマンドライン、サーバー |
| API | JavaScript/Web API | WASI |
| ユースケース | Web アプリ | CLI ツール、サーバーアプリ |
| ランタイム | ブラウザ内蔵 | wasmtime、wasmer 等 |
graph LR
A[main.rs<br/>通常のRust] -->|cargo build<br/>--target wasm32-wasi| B[hello-wasi.wasm]
B -->|wasmtime| C[コマンドライン実行]
fn main() {
println!("Hello, WASI!");
}通常の Rust コードそのままです。println!マクロは、WASI の標準出力 API に自動的に変換されます。
- ✅ ブラウザ不要の WASM 実行
- ✅ システムリソースへのアクセス
- ✅ サーバーサイドアプリケーションの可能性
- ✅ ポータブルなバイナリの作成
→ 詳細は 3-hello-wasi へ
| 項目 | WAT | Rust + wasm-pack | WASI |
|---|---|---|---|
| 実行環境 | ブラウザ | ブラウザ | コマンドライン |
| 言語 | WAT | Rust | Rust |
| ツール | wabt (wat2wasm) | wasm-pack | wasmtime, cargo |
| 学習目的 | WASM の内部理解 | 実践的な Web 開発 | サーバーサイド WASM |
| ユースケース | 教育 | ブラウザでの高度な計算処理 | CLI、プラグイン |
| JavaScript 連携 | 手動(低レベル) | 自動(高レベル) | なし |
🎯 推奨学習順序:
-
まずは 1-hello-wat
- WebAssembly の基本概念を理解
- メモリやインポート/エクスポートの仕組みを学ぶ
-
次に 2-hello-rust
- 実践的なツールチェーンに慣れる
- 実際のプロジェクトで使える知識を習得
-
最後に 3-hello-wasi
- WebAssembly の可能性を広げる
- サーバーサイド活用を検討
目的別の選択:
- 🔍 WebAssembly を深く理解したい → WAT
- 🚀 Web アプリに組み込みたい → Rust + wasm-pack
- ⚙️ CLI ツールを作りたい → WASI
WebAssembly は、Web 開発の新しい可能性を開く技術です。この 3 つのアプローチを通じて:
- WATで WebAssembly の本質を理解し
- Rust + wasm-packで実践的な開発手法を学び
- WASIでブラウザを超えた活用方法を知る
ことができます。