🎉
React + TypeScript + Vite で Wasmを触ってみるメモ
環境
- ubuntu 22.04 LTS
- bun 1.0.14
- vite 5.0.0
- typescript 5.2.2
- react 18.2.0
- wabt 1.0.32
環境構築
bunのインストール。
curl -fsSL https://bun.sh/install | bash
が、以下のコマンドで環境作成が途中までで止まってしまう...。
bun create vite vite-react-wasm-example
もしかして、と思ってnpmとNode.jsをインストール。(こちらを参考にしています)
sudo apt install -y nodejs npm
sudo npm i -g n
sudo n stable
sudo apt purge -y nodejs npm
sudo autoremove -y
もう一度以下を実行したら、最後まで完遂しました。うーん?
bun create vite vite-react-wasm-example
初期インストールと、wabtの追加
cd vite-react-wasm-example
bun i
bun i -D wabt
一旦起動してみる。
bun dev
実装
初期画面のカウンターをwasmで計算させてみる。
src/increment.wat
(module
(func (export "increment") (param $value i32) (result i32)
(i32.add (local.get $value) (i32.const 1))
)
)
src/App.tsx
import { useState, useEffect, useRef } from 'react';
import reactLogo from './assets/react.svg';
import viteLogo from '/vite.svg';
import './App.css';
type Increment = (value: number) => number;
function App() {
const [count, setCount] = useState<number>(0);
const wasmFunctions = useRef<{ increment?: Increment }>({});
useEffect(() => {
const loadWasm = async () => {
try {
const module = await WebAssembly.instantiateStreaming(fetch('/increment.wasm'));
wasmFunctions.current = {
increment: module.instance.exports.increment as Increment
};
} catch (error) {
console.error('Error loading WebAssembly module:', error);
}
};
loadWasm();
}, []);
const handleButtonClick = () => {
const newCount = wasmFunctions.current.increment?.(count) ?? 0;
setCount(newCount);
};
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={handleButtonClick}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
);
};
export default App;
WATをコンパイルしてpublicに置く。
bunx wat2wasm src/increment.wat -o public/increment.wasm
ホットリロードで起動。
bun dev
とりあえず動きました。
Discussion