comlink icon indicating copy to clipboard operation
comlink copied to clipboard

MessageChannel not defined in nodejs

Open micaelmbagira opened this issue 5 years ago • 6 comments

(node:9929) UnhandledPromiseRejectionWarning: ReferenceError: MessageChannel is not defined

MessageChannel comes from worker_threads package but comlink is using the global one.

micaelmbagira avatar May 25 '20 15:05 micaelmbagira

This is probably an oversight since in the examples folder there is a node example. This mostly occurs when using the proxy function which does not allow an argument for setting the endpoint.

Tried fixing this in my project by exposing MessageChannel on the global object and wrapping each MessagePort with the nodeEndpoint() (Can this get any dirtier). But that would get stuck on the objects not being transferable. I haven't looked in too much why this happens but at this point, I'm just better of working with raw workers.

FranklinWaller avatar Jun 12 '20 13:06 FranklinWaller

I have the same issue. Functions and static exports (as in example) work fine unlike classes with a constructor... I tried the same approach as @FranklinWaller but obviously no success... Really need this feature in my project :(

Looking forward to fix.

Azarattum avatar Jun 26 '20 09:06 Azarattum

In order to fix an error with proxying functions, you can try to re-define proxy handler:


const { MessageChannel } = require('worker_threads');
const Comlink = require('comlink');
const nodeEndpoint = require('comlink/dist/umd/node-adapter');

const proxyEventEmitter = {
  ...Comlink.transferHandlers.get('proxy'),
  serialize(obj) {
    const { port1, port2 } = new MessageChannel();

    Comlink.expose(obj, nodeEndpoint(port1));

    return [port2, [port2]];
  },
  deserialize(port) {
    port.start();

    return Comlink.wrap(nodeEndpoint(port));
  },
};

Comlink.transferHandlers.set('proxy', proxyTransferHandler);

The original handler is declared here:

https://github.com/GoogleChromeLabs/comlink/blob/master/src/comlink.ts#L215-L227

You can also re-define canHandle and for example allow automatic proxy for all the callback without wraping it in Comlink.proxy()

SleepWalker avatar Oct 16 '20 09:10 SleepWalker

If someone is interested, I actually solved the problem for my project. I did something similar to what @SleepWalker suggested. However I was using comlink-loader, so I had to put yet another loader on top to fix the problem. The solution is quite messy, but it works: https://github.com/Azarattum/TheFramework/commit/a77ba4aca5d513503515147a98ac9b0afe925208

Azarattum avatar Nov 18 '20 16:11 Azarattum

In order to fix an error with proxying functions, you can try to re-define proxy handler:

const { MessageChannel } = require('worker_threads');
const Comlink = require('comlink');
const nodeEndpoint = require('comlink/dist/umd/node-adapter');

const proxyEventEmitter = {
  ...Comlink.transferHandlers.get('proxy'),
  serialize(obj) {
    const { port1, port2 } = new MessageChannel();

    Comlink.expose(obj, nodeEndpoint(port1));

    return [port2, [port2]];
  },
  deserialize(port) {
    port.start();

    return Comlink.wrap(nodeEndpoint(port));
  },
};

Comlink.transferHandlers.set('proxy', proxyTransferHandler);

The original handler is declared here:

https://github.com/GoogleChromeLabs/comlink/blob/master/src/comlink.ts#L215-L227

You can also re-define canHandle and for example allow automatic proxy for all the callback without wraping it in Comlink.proxy()

@SleepWalker any chance this fix can be put for PR? I also just ran into this for my project.
Thank you!

afbarbaro avatar Mar 31 '21 04:03 afbarbaro

ok, it's a pretty easy fix. I'll open a PR tomorrow.

afbarbaro avatar Mar 31 '21 05:03 afbarbaro