JS glue: Please provide a way to initialize with an already loaded `WebAssembly.Module`
Motivation
Cloudflare Workers has a wacky way of importing wasm modules.
import module from "./hello.wasm";
...is the only allowed way to bring in wasm (in module-based workers). module is then a WebAssembly.Module, not its exports like the upcoming standard proposal.
Currently this means any wasm-bindgen generated JS cannot be initialized properly out of the box. They need to be manually edited with something like a setModule function, which is then picked up and used in instantiateModule.
Once this is done, the wasm lib usually works fine on Cloudflare (modulo some other intentionally missing classes that need to be stubbed like FinalizationRegistry)
Proposed Solution
It would be great if a future version of the JS glue code could accept an WebAssembly.Module already in hand, for environments like this.
Alternatives
Tweaking wasm-bindgen generated JS by hand
Thanks! - John
Cloudflare Workers has a wacky way of importing wasm modules.
I completely agree that it would be nicer if this just worked out the box, but it sounds like this is more of an issue with Cloudflare rather than wasm-bindgen, right?
It's a constrained and security-focused runtime, so I suppose it's reasonable for them to prevent fetching wasm and instantiating modules on the fly. Instead, they are essentially uploaded (and checked) at deploy time.
They are, however, provided at runtime as a web-standard WebAssembly.Module, and it would be great if the bindgen script supported using it (in instantiateModule) instead of assuming fetch
The glue depends on the target. Which target do you use? With --target web, init with WebAssembly.Module does work fine. If you know how to tweak the output file, just tweak the template code in this repo instead and create a PR, like #3016.
Hi @johnspurlock, I believe I have a fix for you in https://github.com/rustwasm/wasm-bindgen/pull/3510.
Thanks! As long as I can hand in my WebAssembly.Module to init, that'll be great
@johnspurlock With my PR, you'd only need to:
- run
wasm-bindgen --target bundler --workerd - import your Wasm bindings in a Cloudflare Worker, like so:
import { yourFunction } from './wasm/your_crate.js' // call yourFunction()
As pointed out before in https://github.com/rustwasm/wasm-bindgen/issues/2972#issuecomment-1204150245, the web target already supports importing a module without fetching:
https://github.com/rustwasm/wasm-bindgen/blob/e13d8985a24d841a93d35e3e4374ec26f7456e0d/crates/cli-support/src/js/mod.rs#L871-L873
I've been extensively using Cloudflare Workers lately with the Web target, this has worked well for me:
#[wasm_bindgen]
pub fn fetch() -> Result<Response, JsValue> {
Response::new_with_opt_str(Some("Hello, World!"))
}
import wasm from './test_bg.wasm'
import init, * as exports from './test.js';
await init(wasm);
export default exports;
So I believe this has already been solved by #1384. Please leave a comment if I'm wrong about this!