Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

Importing WASM files into Electron main process

Writer Mia Lopez

I'm building an Electron app that needs to use Web-Assembly (WASM), however I'm hitting an issue with Fetch throwing a TypeError: Only absolute URLs are supported when importing my WASM file.

Also, perhaps this raises the broader question as to whether the Electron main process or the renderer process should be used to run the WASM ? It does seem to work in the render process.

Here's the complete error:

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)

And here's the main-process code I'm testing with:

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 Answers

The problem is not WASM at all, but the request that is supposed to get the binary. Your fetch comes from node-fetch; the main process runs in Node.js and as such, does not have a base address like a normal page. Either provide a full file:/// absolute URL to fetch, or, more easily, use fs.readFileSync:

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

I can only answer part of your question.

WASM should probably not be run in the Main process. Even though WASM will run in an independent thread, you should reduce the load on the Main process to the maximum extent possible. When the Main process is blocked, even something like minimizing your app will not occur until it becomes unblocked.

For more info, this is a good article:

Have you tried changing fetch("test.wasm") to fetch("./test.wasm") or hardcoding a direct path to local file at least for dev purposes?

2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy