コンテンツへスキップ

Rust/WASM/JavaScript/Viteを使ったプロジェクトの作成と管理 3/4 ビルド編

ビルドをするスクリプトを用意する

Rust/Wasm/Viteの3回目の記事になります。今回はビルドについてです。このビルドについてもRustとJavaScriptのプロジェクト2つ必要なためにやや乱雑になっています。そこで一つのスクリプトで解決させるのが狙いですね。全体的にwasm-setup (1回目),wasm-project(2回目)wasm-build(今回)です。最後にもう一つローカルサーバーを立ち上げるwasm-dev(4回目)で合計4つのスクリプトの話は終了します。これでRust/Wasm/Viteの開発環境の整備を整えてたのです。つまり、0章という立ち位置です。

今回の流れ

  • Rustのコンパイル
  • JavaScriptプロジェクト内へ一部Rustの生成ファイル(pkgディレクトリ)をコピーします。
  • JavaScriptのコンパイル

この3つの流れがあります。これをスクリプト1つで完了させるものになります。

スクリプト

さてスクリプトは次のとおりです。

#!/bin/bash

set -e

name=$1

if [ -z "$name" ]; then
  echo "usage: wasm-build <project-name>"
  exit 1
fi

# 1. パスの定義(ここを一箇所にまとめると管理が楽)
BASE_DIR="${WASM_BASE:-$HOME/projects/wasm}"
PROJECT_ROOT="$BASE_DIR/$name"
RUST_PROJ_DIR="$PROJECT_ROOT/${name}_rs"
JS_PROJ_DIR="$PROJECT_ROOT/${name}_js"
RUST_PKG_PATH="$RUST_PROJ_DIR/pkg"
JS_WASM_DIR="$JS_PROJ_DIR/src/wasm"

# 2. Rust のビルド
echo "=== Rust をビルドして WASM 出力 ==="
if [ ! -d "$RUST_PROJ_DIR" ]; then
  echo "Error: Rust project not found at $RUST_PROJ_DIR"
  exit 1
fi

# ビルド時だけそのディレクトリへ移動
pushd "$RUST_PROJ_DIR" > /dev/null
wasm-pack build --target web || exit 1
popd > /dev/null

# 3. JS 側の設定チェックとコピー
echo "=== JS プロジェクトの同期 ==="
if [ ! -d "$JS_PROJ_DIR" ]; then
  echo "Error: JS project not found at $JS_PROJ_DIR"
  exit 1
fi

# JSディレクトリでの作業
pushd "$JS_PROJ_DIR" > /dev/null

# プラグインチェック
if ! grep -q "vite-plugin-wasm" package.json; then
  echo "[!] プラグインを追加インストールします..."
  npm install -D vite-plugin-wasm vite-plugin-top-level-await
fi

# node_modulesチェック
if [ ! -d "node_modules" ]; then
  npm install
fi

# WASMのコピー
if [ -d "$RUST_PKG_PATH" ]; then
    mkdir -p "$JS_WASM_DIR"
    rm -rf "$JS_WASM_DIR/pkg"
    cp -r "$RUST_PKG_PATH" "$JS_WASM_DIR/"
    echo "Successfully copied pkg to $JS_WASM_DIR"
else
    echo "[!] pkg が見つかりません: $RUST_PKG_PATH"
    popd > /dev/null
    exit 1
fi

popd > /dev/nullCode language: Bash (bash)

これを~/bin/wasm-buildとしてセーブしてください。

$ cd ~/bin
$ cat > wasm-build
 .... コピペする ....
$ chmod 700 wasm-build

実行は次のようにします。

$ wasm-build プロジェクト名 # たとえば、wasm-build helloCode language: PHP (php)

少し説明すると、スクリプト内部でrustはwasm-buildを動かしてコンパイルします。これは既にwasm-setを実行した際にwasm-packをインストールされているので特に意識する必要はありません。プロジェクトの場所は環境変数WASM_BASEでしていされたところになり、つまり、 $WASM_BASE/プロジェクト名 の下にrustとjavascriptのそれぞれのプロジェクトがあります。もしこの記事から見始めたのでしたら、wasm_setup の最初の記事を読んでください。

具体例

ここでは ディレクトリ$WASM_BASEにあるhelloというプロジェクトをすでにあるとしますね。プロジェクトの構成はこのようになっています。

$ pwd
/home/yasuto/projects/wasm/
$ tree -L 2 hello
hello/
├── hello_rs/  <-- Rust側(ここを編集)
│   └── pkg/   <-- wasm-packが生成(自動)
└── hello_js/  <-- JS側
    └── src/
        └── wasm/ <-- スクリプトが pkg をコピーする場所

これでコンパイルするとこんな感じの出力が見られます。

$ wasm-build hello
=== Rust をビルドして WASM 出力 ===
~/projects/wasm/hello ~/projects/wasm/hello
[INFO]: 🎯  Checking for the Wasm target...
[INFO]: 🌀  Compiling to Wasm...
    Finished `release` profile [optimized] target(s) in 0.00s
[INFO]: ⬇️  Installing wasm-bindgen...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
[INFO]: ✨   Done in 0.35s
[INFO]: 📦   Your wasm pkg is ready to publish at /home/yasuto/projects/wasm/hello/hello_rs/pkg.
=== JS プロジェクトの同期 ===
Successfully copied pkg to /home/yasuto/projects/wasm/hello/hello_js/src/wasm
$Code language: JavaScript (javascript)

こんな感じでコンパイルは完了します。~/projects/wasm/hello ~/projects/wasm/hello はスクリプト内のpushd が動作しているために出力されています。

補足説明

もともとこのスクリプトは、cp -rよりln -sをつかってコピーよりリンクを使おうとしましたが、おそらくViteのセキュリティ上の理由で、一工夫が必要になるのです。

そこでvite.config.jsを定義して、サーバーから利用できるディレクトリを増やすことが必要です。それを簡略化して、この環境ファイル不要でも動作ができるように、Rustのプロジェクト/pkgJavaScriptのプロジェクト/src/wasm/pkgにコンパイル後に一旦全削除してコピーを取るようにしています。

つまり、JavaScriptのプロジェクト/src/wasm/以下のところは触らないでください。独自のファイルを作る場合はスクリプトを改造する必要があります。たとえば、独自ファイルを他に置いといて常にwasm以下の指定場所にコピーをすると行ったことになります。その点はご注意ください。スクリプトのcp -r $WASM…の前後にそのコピー操作を書き加えることになります。

また、Rust/WASM/Vite(JavaScript)を想定して作っていますので他のフレームワークを使う場合もスクリプト書き換えが必要です。
コンパイル後に生成されるこの例のpkgは次のように放っています。

$ ls
hello_rs.d.ts  hello_rs.js  hello_rs_bg.wasm  hello_rs_bg.wasm.d.ts  package.json

tsもjsもできていますので動作未確認ですが、TypeScriptも生成されるようです。ちなみに、このd.tsファイルはTypeScriptで型補完の恩恵を受けられる準備ができてるのです。

これだけ複数の言語をまたいだプロジェクトを作って、コンパイル後にコピーが必要だという乱雑さはこのようにスクリプトを作成するとその後の開発に集中できるようになる利点がありますので、参考にしてください。Unix系の昔の乱雑さの工夫はこのように皆さんやっていたってことです。

次はプロジェクトのローカルサーバーを起動するためのwasm-devについての記事です。

最終更新: 2026.01.15