Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ts-node using worker_thread cause `cannot use import statement outside a module`

I have this simple code to try worker threads.

// thread.ts
import { Worker, isMainThread } from 'worker_threads';

if (isMainThread) {
    const worker = new Worker(__filename);
} else {
    console.log('hello from worker');
}

Apparently when I try to run the file with ts-node thread.ts, i got this error:

(node:13200) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

SyntaxError: Cannot use import statement outside a module

But if I compile & invoke the file manually tsc && dist/thread.js, it worked just fine

I try to experiment further, if I put the code that I want to run inside worker thread in an external file, then it worked just fine too

// thread.ts
import { Worker, isMainThread } from 'worker_threads';
const worker = new Worker('./src/worker.ts');

Here is my tsconfig.json

{
    "compilerOptions": {
        "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
        "module": "commonjs", /* Specify what module code is generated. */
         "rootDir": "./src", /* Specify the root folder within your source files. */
         "outDir": "./dist", /* Specify an output folder for all emitted files. */
         "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
        "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
        "strict": true, /* Enable all strict type-checking options. */
        "skipLibCheck": true /* Skip type checking all .d.ts files. */
    }
}

Can anybody enlighten me?

like image 335
slier Avatar asked Apr 22 '26 07:04

slier


1 Answers

For me what really helped was adding:

execArgv: ["--require", "ts-node/register"]

...to the worker options. But since in my case I transpile TS into JS for production and I don't want to have ts-node as a production dependency, so I wrote this function:

import { Worker, WorkerOptions } from "worker_threads";

function importWorker(path: string, options: WorkerOptions) {
  const resolvedPath = require.resolve(path);
  return new Worker(resolvedPath, {
    ...options,
    execArgv: /\.ts$/.test(resolvedPath) ? ["--require", "ts-node/register"] : undefined,
  });
}

And when I call this function I don't add an extension, just as we do in regular imports.

like image 96
Mateus Lage Avatar answered Apr 28 '26 15:04

Mateus Lage



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!