在 chrome 扩展中使用 WebAssembly
using WebAssembly in chrome extension
我有一个 chrome 扩展,其中包含一个复杂的函数 comp_func(data)
,它通过执行许多按位运算需要大量 CPU。因此,我正在尝试使用 WebAssembly。
我试过几个教程,例如 this one and this 一个。
第一个 link 说:
fetch('simple.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
results.instance.exports.exported_func();
});
但是我得到一个错误:
Uncaught (in promise) TypeError: WebAssembly Instantiation: Import #0 module="env" error: module is not an object or function
我已经尝试了很多次来使用这种方法,但都没有用。我无法理解如何使用从 .wasm
文件加载的 WebAssembly。
所以我尝试了一种更简单的方法:
第二个 link 表示将此行放入 html 文件中:
<script src="index.js"></script>
然后只使用导出的函数:
var result = _roll_dice();
但是,我在扩展中,所以我只有一个 background.html
文件。
所以我正在寻找一种方法来访问后台文件中加载的模块。
事情变得复杂了,因为函数 comp_func(data)
是从 .
调用的
这是我迄今为止尝试过的方法:
如果我调用 chrome.extension.getBackgroundPage()
我可以访问该模块
但我无法将其发送给工人:
Failed to execute 'postMessage' on 'Worker': # could not be cloned.
如果我先尝试stringify
它:
Uncaught TypeError: Converting circular structure to JSON
(我试过取消循环,没用...)
而且我无法从 Worker 调用 chrome.extension.getBackgroundPage()
,因为我无法从那里访问 chrome API。
所以我的问题是:
- 是否有人尝试在 chrome 扩展名中加载
.wasm
文件并成功?
第二种方法(加载 js
文件)听起来更简单,但如果您有这种方法的工作示例,那就太好了。
或2.如何访问background.html
中加载的模块(来自第二个例子)?
或者3.如何将我需要的函数从js文件传递给Worker(通过postMessage
)?
总而言之,是否有人尝试在 chrome 扩展中使用 WebAssembly 并幸存下来?
编辑:
我最终离开了 WebAssembly 的方法。
我还在 bugs-chromium 上发布了这个问题,
几个月后得到了答复。不确定这是否真的有效,但也许这个连同标记的答案会对某人有所帮助。
我最近一直在摆弄 WebAssembly,并找到了一种让它工作的方法。以下是脚本文件:
main.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "content_script.js"});
});
content_script.js
var importObject = { imports: { imported_func: arg => console.log(arg) } };
url = 'data:application/wasm;base64,' + "AGFzbQEAAAABCAJgAX8AYAAAAhkBB2ltcG9ydHMNaW1wb3J0ZWRfZnVuYwAAAwIBAQcRAQ1leHBvcnRlZF9mdW5jAAEKCAEGAEEqEAAL";
WebAssembly.instantiateStreaming(fetch(url), importObject)
.then(obj => obj.instance.exports.exported_func());
数据URL属于普通教程wasm sample(simple.wasm),在控制台写42
PS。如果这对您来说像是作弊或不良做法,这个 content_script.js 也可以:
var importObject = {
imports: {
imported_func: function(arg) {
console.log(arg);
}
}
};
var response = null;
var bytes = null;
var results = null;
var wasmPath = chrome.runtime.getURL("simple.wasm");
fetch(wasmPath).then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
results.instance.exports.exported_func();
});
仅当您在 manifest.json 的 web_accessible_resources 部分包含代码文件时,但是:
...
"web_accessible_resources": [
"content_script.js",
"main.js",
"simple.wasm"
],
...
Github: https://github.com/inflatablegrade/Extension-with-WASM
也可以是made compatible with Manifest V3.
我有一个 chrome 扩展,其中包含一个复杂的函数 comp_func(data)
,它通过执行许多按位运算需要大量 CPU。因此,我正在尝试使用 WebAssembly。
我试过几个教程,例如 this one and this 一个。
第一个 link 说:
fetch('simple.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
results.instance.exports.exported_func();
});
但是我得到一个错误:
Uncaught (in promise) TypeError: WebAssembly Instantiation: Import #0 module="env" error: module is not an object or function
我已经尝试了很多次来使用这种方法,但都没有用。我无法理解如何使用从 .wasm
文件加载的 WebAssembly。
所以我尝试了一种更简单的方法: 第二个 link 表示将此行放入 html 文件中:
<script src="index.js"></script>
然后只使用导出的函数:
var result = _roll_dice();
但是,我在扩展中,所以我只有一个 background.html
文件。
所以我正在寻找一种方法来访问后台文件中加载的模块。
事情变得复杂了,因为函数 comp_func(data)
是从
这是我迄今为止尝试过的方法:
如果我调用 chrome.extension.getBackgroundPage()
我可以访问该模块
但我无法将其发送给工人:
Failed to execute 'postMessage' on 'Worker': # could not be cloned.
如果我先尝试stringify
它:
Uncaught TypeError: Converting circular structure to JSON
(我试过取消循环,没用...)
而且我无法从 Worker 调用 chrome.extension.getBackgroundPage()
,因为我无法从那里访问 chrome API。
所以我的问题是:
- 是否有人尝试在 chrome 扩展名中加载
.wasm
文件并成功? 第二种方法(加载js
文件)听起来更简单,但如果您有这种方法的工作示例,那就太好了。
或2.如何访问background.html
中加载的模块(来自第二个例子)?
或者3.如何将我需要的函数从js文件传递给Worker(通过postMessage
)?
总而言之,是否有人尝试在 chrome 扩展中使用 WebAssembly 并幸存下来?
编辑: 我最终离开了 WebAssembly 的方法。 我还在 bugs-chromium 上发布了这个问题, 几个月后得到了答复。不确定这是否真的有效,但也许这个连同标记的答案会对某人有所帮助。
我最近一直在摆弄 WebAssembly,并找到了一种让它工作的方法。以下是脚本文件:
main.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "content_script.js"});
});
content_script.js
var importObject = { imports: { imported_func: arg => console.log(arg) } };
url = 'data:application/wasm;base64,' + "AGFzbQEAAAABCAJgAX8AYAAAAhkBB2ltcG9ydHMNaW1wb3J0ZWRfZnVuYwAAAwIBAQcRAQ1leHBvcnRlZF9mdW5jAAEKCAEGAEEqEAAL";
WebAssembly.instantiateStreaming(fetch(url), importObject)
.then(obj => obj.instance.exports.exported_func());
数据URL属于普通教程wasm sample(simple.wasm),在控制台写42
PS。如果这对您来说像是作弊或不良做法,这个 content_script.js 也可以:
var importObject = {
imports: {
imported_func: function(arg) {
console.log(arg);
}
}
};
var response = null;
var bytes = null;
var results = null;
var wasmPath = chrome.runtime.getURL("simple.wasm");
fetch(wasmPath).then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
results.instance.exports.exported_func();
});
仅当您在 manifest.json 的 web_accessible_resources 部分包含代码文件时,但是:
...
"web_accessible_resources": [
"content_script.js",
"main.js",
"simple.wasm"
],
...
Github: https://github.com/inflatablegrade/Extension-with-WASM
也可以是made compatible with Manifest V3.