Skip to content

URL path generated for Worker imports doesn't work with Webpack #22140

@Twinklebear

Description

@Twinklebear

Hi, I'm setting up a C++ WASM app to use threads that I distribute as part of a frontend app that uses webpack, however I'm running into an issue with how webpack is handling the URL for the worker import. In Emscripten's generated JS, the worker file is imported in allocateUnusedWorker as:

allocateUnusedWorker() {
  var worker;
  var workerOptions = {
    "type": "module",
    "name": "em-pthread"
  };
  worker = new Worker(new URL(import.meta.url), workerOptions);
  PThread.unusedWorkers.push(worker);
},

Webpack seems to resolve this import URL to a local file:// path, producing:

 allocateUnusedWorker() {
    var worker;
    var workerOptions = {
        "type": "module",
        "name": "em-pthread"
    };
    worker = new Worker(new URL("file:///Users/will/repos/webgpu-cpp-wasm/web/src/cpp/wgpu_app.js"),workerOptions);
    PThread.unusedWorkers.push(worker);
},

which results in the following error when trying to run the app, since the URL import path is not valid:

wgpu_app.js:1050 Uncaught (in promise) DOMException: Failed to construct 'Worker': Script at 'file:///Users/will/repos/webgpu-cpp-wasm/web/src/cpp/wgpu_app.js' cannot be accessed from origin 'http://localhost:8080'.
    at Object.allocateUnusedWorker (http://localhost:8080/6009193530ba34a86bac.js:4590:14)
    at Object.initMainThread (http://localhost:8080/6009193530ba34a86bac.js:4487:15)
    at Object.init (http://localhost:8080/6009193530ba34a86bac.js:4481:15)
    at http://localhost:8080/6009193530ba34a86bac.js:12723:9
    at http://localhost:8080/6009193530ba34a86bac.js:982:81

If I patch the function to change the import URL to (where script_filename.js is the name of the JS output file) webpack is able to resolve the path correctly:

allocateUnusedWorker() {
  var worker;
  var workerOptions = {
    "type": "module",
    "name": "em-pthread"
  };
  worker = new Worker(new URL("script_filename.js", import.meta.url).href, workerOptions);
  PThread.unusedWorkers.push(worker);
},

It also works without the .href, though webpack will then complain about circular dependencies between the files breaking filename hashing (since the file now depends on itself).

I noticed that this is the same URL structure that findWasmBinary returns to be compatible with bundlers:

return new URL('{{{ WASM_BINARY_FILE }}}', import.meta.url).href;
. Should the worker import be changed to something like below (or without the href?)

worker = new Worker('{{{ JS_FILE }}}', import.meta.url).href;

The full project code is here: https://github.com/Twinklebear/webgpu-cpp-wasm/tree/threads if you want to test it, the patch step can be removed by commenting out this line in src/CMakeLists.txt or just making the patch script a noop.

Or if I'm doing something wrong with my webpack config to import these files, let me know.

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.61-git

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions