I am building a Firefox addon using Rust. I am trying to insert HTML and do stuff on specific pages. Apparently, a content script is the thing I want to use. My content script is:
import("../crate/pkg").then(({ Addon }) => {
const addon = Addon.new();
console.log(addon.where_am_i());
}).catch(e => console.error("Error importing:", e));
The error I am getting is:
TypeError: "0125c9960050e7483877.module.wasm is not a valid URL."
I tried to add to manifest.json
:
"web_accessible_resources": [
"0125c9960050e7483877.module.wasm"
]
I accessed it as moz-extension://<extension-UUID>/0125c9960050e7483877.module.wasm"
but then I got:
Error importing: Error: "Loading chunk 0 failed.
I also tried a background script, but that is loaded in extension context so it doesn't allow me to alter page content.
Briefly, the steps to get your WASM WebApp working are: Compile C/C++ code with Emscripten, to obtain a WASM binary. Bind your WASM binary to your page using a JavaScript "glue code". Run your app and let the browser to instantiate your WASM module, the memory and the table of references.
With around 40 languages that can compile to WebAssembly, developers can finally use their favorite language on the Web. WebAssembly does not replace JavaScript; in fact, some JavaScript code is required to load WebAssembly modules. WebAssembly runs in all major browsers and in all platforms.
wasm binary. By itself, WebAssembly cannot currently directly access the DOM; it can only call JavaScript, passing in integer and floating point primitive data types. Thus, to access any Web API, WebAssembly needs to call out to JavaScript, which then makes the Web API call.
I'm not sure how import("../crate/pkg")
works at all for you, as dynamic module imports are not supported in content scripts in Firefox and "../crate/pkg" doesn't look like a path that can work. Perhaps you're doing some preprocessing?
Loading bare WASM (I took add.wasm from this sample) works fine if you have "web_accessible_resources": ["add.wasm"]
in your manifest.json:
WebAssembly.instantiateStreaming(fetch(browser.runtime.getURL("add.wasm")), {})
.then(results => {
console.log("wasm returned", results.instance.exports.add_one(41));
}).catch((err) => {
console.error("Unable to instantiateStreaming", err)
});
Getting a generated JS wrapper to work in content script is a different question, which depends on the tooling and the specific mode you run in.
If you are able to run WASM in a background script, you can communicate between the content script and the background script via sendMessage to get the job done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With