Rust and WebAssemblyのチュートリアルで詰まったところ

Rust and WebAssemblyのチュートリアルを進めているときにうまく行かなかったところのまとめ。

環境

  • MacOS Ventura 13.3.1
  • rustup 1.26.0
  • rustc 1.69.0
  • cargo 1.69.0
  • wasm-pack 0.11.0
  • wasm-bindgen 0.2.63
  • node v18.16.0
  • webpack 5.82.0

詰まったところ

wasmのmemoryにアクセスするところがうまくいなかい

Game of Lifeの実装のところで、wasm-packのコマンド実行後に作成されるpkg/wasm_game_of_life.jsmemoryにアクセスするところでエラーが発生する。

ファイルの中身を見てもmemoryをexportしているところがないので、wasm_game_of_life.jsの1行目の記載を参考に、wasm_game_of_life_bg.wasmindex.js内でimportするようにしてwasm.memory.bufferにアクセスするようにした。

import { Universe } from "wasm-game-of-life";
import * as wasm from "wasm-game-of-life/wasm_game_of_life_bg.wasm";
// ...

const drawCells = () => {
  const cellsPtr = universe.cells();
  const cells = new Uint8Array(wasm.memory.buffer, cellsPtr, width * height);
// ...

しかし、npm run startすると以下のエラーで失敗。

# ...
ERROR in ../pkg/wasm_game_of_life_bg.wasm 1:0
Module parse failed: Unexpected character '' (1:0)
The module seem to be a WebAssembly module, but module is not flagged as WebAssembly module for webpack.
BREAKING CHANGE: Since webpack 5 WebAssembly is not enabled by default and flagged as experimental feature.
You need to enable one of the WebAssembly experiments via 'experiments.asyncWebAssembly: true' (based on async modules) or 'experiments.syncWebAssembly: true' (like webpack 4, deprecated).
For files that transpile to WebAssembly, make sure to set the module type in the 'module.rules' section of the config (e. g. 'type: "webassembly/async"').
(Source code omitted for this binary file)
 @ ./index.js 2:0-68 60:4-22
 @ ./bootstrap.js 4:0-20

webpack 5.82.0 compiled with 1 error in 428 ms

エラーの内容に従って、webpack.config.jsexperiments.syncWebAssembly: trueを追加したらうまく行った。

// ...
module.exports = {
  experiments: {
    asyncWebAssembly: true,
  },
  entry: "./bootstrap.js",
  // ...
};

wasm-pack testが失敗する

Testingのページの例にしたがい、wasm-pack test --chrome --headlessを実行すると以下のエラーで失敗する。

# ...
    Starting ChromeDriver 113.0.5672.63 (0e1a4471d5ae5bf128b1bd8f4d627c8cbd55f70c-refs/branch-heads/5672@{#912}) on port 60573
    Only local connections are allowed.
    Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
    ChromeDriver was started successfully.

Error: non-200 response code: 404
{"value":{"error":"invalid session id","message":"invalid session id","stacktrace":"0   chromedriver
# ...

これはChromeとChrome Driverのバージョンが合っていないことが原因だった。Chromeのバージョンを上げることで解決。