8

Is there any way to use ts-node with WebWorkers but without using webpack?

When I do:

const worker = new Worker('path-to/workerFile.ts', { // ... });

I get:

TypeError [ERR_WORKER_UNSUPPORTED_EXTENSION]: The worker script extension must be ".js" or ".mjs". Received ".ts" at new Worker (internal/worker.js:272:15) // ....

Any ideas?

Tomer

kutomer
  • 734
  • 8
  • 17
  • That's unfortunate; one would hope that web workers would accept any registered module extension. You could try writing a JavaScript file that just `require`s your TypeScript file. – Matt McCutchen Oct 25 '18 at 14:44
  • Thanks, I tried, but when you `require` a typescript file from a js file you're getting runtime exceptions about typescript annotations, I guess that ts-node doesn't compile nested ts files or something. – kutomer Oct 25 '18 at 15:27
  • Hm, maybe the worker isn't inheriting the require hooks from the main thread. Does it work if you add `require("ts-node/register");` to the top of the JavaScript file? (I would try it myself but my version of Node doesn't support workers.) – Matt McCutchen Oct 25 '18 at 15:33
  • nope, tried it at as well :( – kutomer Oct 25 '18 at 16:03
  • It seems like the only solution will be to create some sort of ts-node plugin (https://github.com/TypeStrong/ts-node/issues/711#issuecomment-433104488) – kutomer Oct 25 '18 at 16:24

1 Answers1

14

You can make an function to make the magic, using eval property of WorkerOption parameter.

const workerTs = (file: string, wkOpts: WorkerOptions) => {
    wkOpts.eval = true;
    if (!wkOpts.workerData) {
        wkOpts.workerData = {};
    }
    wkOpts.workerData.__filename = file;
    return new Worker(`
            const wk = require('worker_threads');
            require('ts-node').register();
            let file = wk.workerData.__filename;
            delete wk.workerData.__filename;
            require(file);
        `,
        wkOpts
    );
}

so you can create the thread like this:

let wk = workerTs('./file.ts', {});

Hope it can help.