GoogleChromeLabs / comlink

Comlink makes WebWorkers enjoyable.
Apache License 2.0
11.37k stars 390 forks source link

Worker call to main ("the other way around") doesn't work in node? #557

Open kurt1288 opened 3 years ago

kurt1288 commented 3 years ago

I've tried to implement the solution in https://github.com/GoogleChromeLabs/comlink/issues/506#issuecomment-753457080, but that doesn't seem to work in node.

Because nodejs doesn't have a "self" context, I've tried using "globalThis" instead, but when I run it it still throws a "self is not defined" error (from the expose function in comlink).

In my main.ts file I've tried:

const worker = new Worker(filename);
const obj = Comlink.wrap(nodeEndpoint(worker)) as unknown as Engine;

Comlink.expose(this.engine, nodeEndpoint(worker));

and in my worker file I have tried:

Comlink.wrap(globalThis) as unknown as Engine;

I suspect the issue is with Comlink.expose(this.engine, nodeEndpoint(worker)); and the nodeEndpoint part but I can't figure it out.

surma commented 3 years ago

Comlink.wrap(globalThis) is most likely not correct here. That should probably be Comlink.wrap(nodeEndpoint(require('worker_threads').parentPort)).

If that doesn’t work, can you put your example in a gist or something?

kurt1288 commented 3 years ago

Gist: https://gist.github.com/kurt1288/88036897d5cefffc470b3418d0119061. That's a basic example of how I'm trying to use it.

Explanation for the worker.js file (instead of just calling new Worker('./engine.js')). Short version is "because of webpack". Longer version: My webpack configuration bundles both the main and engine files together. Since new Worker() needs a file and not just a class object, I created the worker.js file.

celluj34 commented 2 years ago

In your webpack you can define extra entry points, this will create separate files based on the key:

  const entry = {
    polyfill: ["core-js/stable", "regenerator-runtime/runtime"],
    functions: "./src/functions/functions.ts",
    helpers: "./src/functions/helpers.ts",
  };

This results in functions.js and helpers.js in your dist folder. In webpack 5 you can also do just const worker = wrap<WorkerService>(new Worker(new URL("./worker.service.ts", import.meta.url))); which will link/import correctly without any other fussing.