I am trying to run a game I built with Bevy and Rust in the browser. Bevy started supporting WebGL2 from version 0.11.0, and I am using this version. I have compiled my Rust code to WebAssembly using wasm-pack build --target web
.
However, when I try to initialize the WebAssembly module in my HTML file, I get the following error:
WebAssembly.instantiate(): Import #0 module="__wbindgen_placeholder__" error: module is not an object or function
Here is the JavaScript code I am using to initialize the WebAssembly module:
import init, { run } from './game.js';
async function main() {
await init('./game.wasm');
run();
}
main();
In main.rs I have my run function with the export defined like:
#[wasm_bindgen]
pub fn run() {
App::new()
.add_plugins(DefaultPlugins)
//initialize more systems and resources
}
I have verified my paths are correct, and I am serving the files using the Live Server extension in VSCode. I am using the latest version of chrome and rust on popOS.
I have also checked the Bevy documentation and examples, but I couldn't find any specific guidance on this issue.
Does anyone know what could be causing this error and how to fix it?
If you want to compile a bevy
application to wasm using wasm-pack
you need to do it a bit different than usual.
First of all there is no need to add the #[wasm_bindgen]
attribute anywhere in your rust code (e.g. no need to explicetly depend on wasm-bindgen
).
To build your project for the wasm32-unknown-unknown
target, run:
cargo build --release --target wasm32-unknown-unknown
and after that create the JavaScript bindings using wasm-pack
and the binary built in the previous step:
wasm-bindgen --out-dir out --target web target/wasm32-unknown-unknown/release/game.wasm
Lastly serve such an index.html
with a http-server of your choice:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bevy Game</title>
<meta charset="UTF-8" />
<style>
body {
background: linear-gradient(135deg,
white 0%,
white 49%,
black 49%,
black 51%,
white 51%,
white 100%);
background-repeat: repeat;
background-size: 20px 20px;
}
canvas {
background-color: white;
}
</style>
</head>
<script type="module">
import init from './out/game.wasm'
init()
</script>
</html>
with the relevant part of course being:
<script type="module">
import init from './out/game.wasm'
init()
</script>
I have a full repository where this workflow is set up over here.