Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use Wasm in the content script of a Firefox web extension?

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.

like image 973
kunicmarko20 Avatar asked Aug 21 '19 20:08

kunicmarko20


People also ask

How do I run a Wasm file?

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.

Does Wasm compile to JavaScript?

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.

Can Wasm interact with Dom?

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.


1 Answers

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.

like image 89
Nickolay Avatar answered Sep 29 '22 07:09

Nickolay