将WASM文件导入到Electron主进程中

时间:2020-05-30 12:14:18

标签: node.js electron webassembly

我正在构建一个需要使用Web-Assembly(WASM)的Electron应用程序,但是在导入WASM文件时Fetch抛出TypeError: Only absolute URLs are supported时遇到了一个问题。

此外,也许这引发了一个更大的问题,即应使用电子主进程还是渲染器进程来运行WASM?它似乎确实在渲染过程中起作用。

这是完整的错误:

TypeError: Only absolute URLs are supported
    at parseURL (/Users/devuser/development/electron-api-demos/node_modules/node-fetch/dist/index.cjs:897:8)
    at new Request (/Users/devuser/development/electron-api-demos/node_modules/node-fetch/dist/index.cjs:922:17)
    at /Users/devuser/development/electron-api-demos/node_modules/node-fetch/dist/index.cjs:1175:19
    at new Promise (<anonymous>)
    at fetch (/Users/devuser/development/electron-api-demos/node_modules/node-fetch/dist/index.cjs:1173:9)
    at IpcMainImpl.<anonymous> (/Users/cbourne/development/electron-api-demos/main-process/communication/async-msg.js:20:36)
    at IpcMainImpl.emit (events.js:223:5)
    at WebContents.<anonymous> (electron/js2c/browser_init.js:4093:15)
    at WebContents.emit (events.js:223:5)

这是我正在测试的主要代码:

const {ipcMain} = require('electron')
require('/Users/devuser/development/electron-api-demos/script/wasm_exec.js')

const fetch = require("node-fetch");

ipcMain.on('asynchronous-message', (event, arg) => {

  if (!WebAssembly.instantiateStreaming) { // polyfill
    WebAssembly.instantiateStreaming = async (resp, importObject) => {
      const source = await (await resp).arrayBuffer();
      return await WebAssembly.instantiate(source, importObject);
    };
  }

  const go = new Go();
  let mod, inst;
  WebAssembly.instantiateStreaming(fetch("test.wasm"), go.importObject).then((result) => {
    mod = result.module;
    inst = result.instance;
    document.getElementById("runButton").disabled = false;
  }).catch((err) => {
    console.error(err);
  });

  async function run() {
    console.clear();
    await go.run(inst);
    inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance
  }

  event.sender.send('asynchronous-reply', 'pong')
})

3 个答案:

答案 0 :(得分:1)

问题根本不是 WASM,而是应该获取二进制文件的请求。您的 fetch 来自 node-fetch;主进程在 Node.js 中运行,因此没有像普通页面那样的基地址。要么为 file:/// 提供完整的 fetch 绝对 URL,要么更轻松地使用 fs.readFileSync

const fs = require('fs');
WebAssembly.instantiate(fs.readFileSync("text.wasm"));

答案 1 :(得分:1)

我只能回答你的部分问题。

WASM 应该在主进程中运行。即使 WASM 将在独立线程中运行,您也应该尽可能减少 Main 进程的负载。当 Main 进程被阻塞时,即使是最小化你的应用程序也不会发生,直到它被解除阻塞。

有关更多信息,这是一篇不错的文章:https://medium.com/actualbudget/the-horror-of-blocking-electrons-main-process-351bf11a763c

答案 2 :(得分:0)

您是否尝试过将fetch("test.wasm")更改为fetch("./test.wasm")或硬编码到本地文件的直接路径,至少出于开发目的?