🐶
blog.terrier.dev

posted: 2019/09/04

parcel + rustでwasm_bindingを使うとき (TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an objectの解決


parcel + rustで基礎的な部分は公式ドキュメントでも十分だったがwasm-bindgenなどを噛ませようとすると、色々と工夫が必要だと下記よりわかった。
おそらくpacel2になったら解決する可能性などはある

手順

準備

cargo install wasm-pack

ひとまずrust-parcel-templateに習いやっておく
cargo install wasm-pack

cargoの作成

cargo new wasm
今回はwasmという名前で作成
Cargo.tomlにwasm-bindgen追加
[dependencies]
wasm-bindgen = "^0.2.50"

src/lib.rs

こんな感じで作成。
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn main() -> String {
    return "Hello, world!!".to_string();
}
JSの呼び出し側はこんな具合
const start = async () => {
  const { main } = await import("../wasm/src/lib.rs")
  
  console.log(main())
  // console.log(add(1, 2))
}
で、このあたりで下記のようなエラーにぶつかる
Uncaught (in promise) TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object 

解決策

parcel-plugin-wasm.rsのインストール

現状parcel本体側ではどうもwasm-bindgenとうまく噛み合わないようなので、pluginを入れる
parcelの場合はpluginをインストールすれば読み込まれるので、あとは不要。
npm install parcel-plugin-wasm.rs
そしてこれは深く読んでないので原因は不明だが、呼び出し元をCargo.tomlにする必要があった。
const start = async () => {
  const { main } = await import("../wasm/Cargo.toml")
  // もと -> const { main } = await import("../wasm/src/lib.rs")
  
  console.log(main())
  // console.log(add(1, 2))
}
これで解決した

参考2


Edit on Github
@terrierscript