Solvedts node Worker Threads flag (node v10.5+)

Hi,

Thanks for all the work you've done with ts-node!

I'm currently trying to pass the --experimental-worker flag for Worker Threads support but it doesn't seem to be respecting the flag.

I've tried:

  • ts-node ./file.ts --experimental-worker
  • node --experimental-worker --require ts-node/register ./file.ts

And I get the following error:

  • error TS2307: Cannot find module 'worker_threads'.

Any ideas?

16 Answers

✔️Accepted Answer

If somebody wants to write thread workers as .ts files, it's possible by having an intermediate .js file that only acts as the importer. It also requires option allowJs: true in tsconfig.json

worker.import.js

require('ts-node').register();
require(path.resolve(__dirname, 'worker.ts'));

worker.ts

// regular ts file 

Other Answers:

@marcpearson not sure what exactly might be the issue in your build, but to expand on what I wrote previosuly:

I run the app using ts-node src/index.ts and in index.ts I initialize worker

const workerFile = process.env.NODE_ENV === 'production'
  ? 'worker.js'
  : 'worker.import.js';

  new Worker(path.resolve(__dirname, workerFile), { workerData });

In production the app will be compiled to js, so I just import worker.js file that will be there. In development on the other hand I need an intermediate file, that has .js file extension and just imports worker.ts

worker.import.js file

const path = require('path');

require('ts-node').register();
require(path.resolve(__dirname, './worker.ts'));

And the last file is worker.ts itself, where you have the worker logic.

I made a different solution with a dynamic approach, I create an a function with a eval worker whos import the TS file.

check the code below:

import {
    Worker,
    isMainThread,
    parentPort,
    workerData,
    WorkerOptions
} from "worker_threads";

//
// WORKAROUND (GAMBIARRA)
//
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
    );
}

//
// MAIN FUNCTION
//
const main = () => {
    setInterval(() => console.log('main'), 1000);
    let wk = workerTs(__filename, {
        workerData: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    });
    wk.on("online", () => console.log('Worker UP'));
    wk.on("message", (msg) => console.log('message:', msg));
    wk.on("exit", (code) => console.warn('exit', code));
    wk.on("error", (err) => console.error('error', err));
}

//
// THREAD FUNCTION
//
const thread = () => {
    if (!parentPort) return;
    console.log(workerData)
    parentPort.postMessage('asdas')
}

//
// RUN MAIN OR THREAD
//
isMainThread ? main() : thread();

ps: sorry for the bad english.

More Issues: