vite-plugin-singlefileでwasmを単一HTMLに埋め込む
備忘録メモ
どうしてもネットから隔離されたローカル環境の某RADソフトウェアでwasmを動作させたかったため、単一HTMLにRustで作ったwasmを埋め込めるか試してみました。
単一HTMLを某RADソフトウェア内に埋め込んでwasmがWebビューで動作することを確認しました。
Viteで新規プロジェクト
今回はViteで新規プロジェクトを立ち上げてみます。
$ npm create vite@latest my-wasm-app -- --template vanilla-ts
$ cd my-wasm-app
$ npm install
publicディレクトリは使わないので削除(状況に応じて残すかを決めてください)
srcディレクトリもサンプルコードが入っているので一旦削除し、空のmain.tsファイルを作ります。
$ rm -r public
$ rm -r src
$ mkdir src
$ touch src/main.ts
wasmのためにRustのコードを追加
プロジェクトディレクトリ内でRustでwasmのコードを書くためにcargo new
します。
$ cargo new --lib wasm
Cargo.tomlを編集してcrate-type = ["cdylib"]
を追加したり、dependenciesにwasm-bindgen = "0.2"
を追加しています。
このあたりはcargo add wasm-bindgen
してもいいかもしれません。
[package]
name = "wasm"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
足し算ができる関数add()
をTypeScript側に公開しておきます。
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
wasm-packをインストールし、一旦ビルドします。
$ npm i -D wasm-pack
$ npx wasm-pack build ./wasm --target web
これでwasm/pkgディレクトリができました。
TypeScriptのコードを追加
import init, { add } from '../wasm/pkg';
init().then(() => {
alert(add(1n, 2n));
});
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>my-wasm-app</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
動作確認のためviteを立ち上げ
$ npm run dev
ブラウザでhttp://localhost:5173/
を開いてアラートダイアログで3
と表示されていればOK
確認が終わったらControl+Cで終了します。
vite-plugin-singlefileを導入
$ npm i -D vite-plugin-singlefile
import { defineConfig } from 'vite';
import { viteSingleFile } from 'vite-plugin-singlefile';
export default defineConfig({
plugins: [viteSingleFile()],
});
$ npm run build
buildするとdist/index.htmlに単一のHTMLファイルとして出力されます。index.htmlをブラウザにドラッグ&ドラップすると動作を確認できます。
package.jsonを編集してnpm run build
にwasm-pack build ./wasm/ --target web
を仕込んでもいいかもしれません。
{
"name": "my-wasm-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
- "build": "tsc && vite build",
+ "build": "wasm-pack build ./wasm/ --target web && tsc && vite build",
"preview": "vite preview"
},
"devDependencies": {
"typescript": "~5.8.3",
"vite": "^6.3.5",
"vite-plugin-singlefile": "^2.2.0",
"wasm-pack": "^0.13.1"
}
}
以上です。
Discussion