【问题标题】:using WebAssembly in chrome extension在 chrome 扩展中使用 WebAssembly
【发布时间】:2018-09-11 16:06:27
【问题描述】:

我有一个 chrome 扩展,其中包含一个复杂的函数 comp_func(data),它通过执行许多按位运算来占用大量 CPU。因此,我正在尝试使用 WebAssembly。

我尝试了几个教程,例如this 一个和this 一个。

第一个链接说:

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。

所以我尝试了一种更简单的方法: 第二个链接说将这一行放在 html 文件中:

<script src="index.js"></script>

然后只使用导出的函数:

var result = _roll_dice();

但是,我在扩展中,所以我只有一个 background.html 文件。 所以我正在寻找一种方法来访问在后台文件中加载的模块。 事情变得复杂了,因为函数 comp_func(data) 是从 Worker 调用的。

这是我迄今为止尝试过的:

如果我打电话给chrome.extension.getBackgroundPage(),我可以访问模块 但我无法将其发送给 Worker:

在“Worker”上执行“postMessage”失败:# 无法克隆。

如果我先尝试stringify:

未捕获的 TypeError:将循环结构转换为 JSON

(我试图取消循环它,没有用......)

我无法从 Worker 调用 chrome.extension.getBackgroundPage(),因为我无法从那里访问 chrome API。

所以我的问题是:

  1. 是否有人尝试在 chrome 扩展中加载 .wasm 文件并成功? 第二种方法(加载js 文件)听起来更简单,但如果您有这种方法的工作示例,那就太好了。

或者2.如何访问background.html中已经加载的Module(来自第二个例子)?

或者3.如何将我需要的函数从js文件传递给Worker(通过postMessage)?

总而言之,是否有人尝试在 chrome 扩展中使用 WebAssembly 并幸存下来?

编辑: 我最终离开了 WebAssembly 的方法。 我也在bugs-chromium发布了这个问题, 几个月后得到了答案。不确定这是否真的有效,但也许这以及标记的答案会对某人有所帮助。

【问题讨论】:

  • 我认为扩展可能还不能运行 wasm。至于消息传递部分:1)只能使用 chrome API 传输简单数据,即由此类简单数据组成的数字、字符串、布尔值、数组和对象,2)Worker 也可以传输a few specific types,3)函数不是可转让。
  • 您知道如何确定扩展程序是否无法运行 wasm?
  • 您可以在crbug.com 和/或Chromium-Extensions-Announce 上提问。

标签: javascript google-chrome-extension web-worker webassembly


【解决方案1】:

我最近一直在摆弄 WebAssembly,并找到了使其工作的方法。以下是脚本文件:

ma​​in.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示例(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 和Manifest V3。

【讨论】:

  • 使用 WASM 时,Chrome 应用商店是否需要源代码进行代码审核才能发布?
  • 说实话,我从未尝试过。我只是想看看它作为一个概念是否可行。我的扩展没有任何实际用途,所以我没有尝试发布它。 WASM 在计算密集型 Web 应用程序和扩展方面具有很大潜力,但我对此没有特别的扩展想法。不过它与 Manifest V3 兼容。
  • 其实uBlock Origin里面有WASM:github.com/gorhill/uBlock/tree/master/src/js/wasm
猜你喜欢
  • 2014-08-05
  • 2018-04-15
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-16
  • 2016-05-15
  • 2020-04-26
相关资源
最近更新 更多