ts-jest icon indicating copy to clipboard operation
ts-jest copied to clipboard

[Bug]: When test code that use Worker or ChildProcess throw SyntaxError: Cannot use import statement outside a module

Open MiniSuperDev opened this issue 1 year ago • 4 comments

Version

29.0.3

Steps to reproduce

  1. Test this file for see the Worker error

worker.test.ts

import {isMainThread, parentPort, Worker} from 'worker_threads';

if (isMainThread) {
  class WorkerExample {
    constructor() {
      const worker = new Worker(__filename);
      worker.postMessage('hi');
    }
  }
  test('worker', () => {
    const example = new WorkerExample();
  });
} else {
  parentPort?.on('message', (message: string) => {
    console.log(message);
  });
}
  1. Test this file for see the ChildProcess error

child-process.test.ts

import {fork} from 'child_process';

if (process.argv[2] === 'child') {
  process.on('message', (message: string) => {
    console.log(message);
  });
} else {
  class ChildProcessExample {
    constructor() {
      const childProcess = fork(__filename, ['child']);
      childProcess.send('hi');
    }
  }
  test('child process', () => {
    const example = new ChildProcessExample();
  });
}

jest.config.js

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

Expected behavior

Not throw an error.

Actual behavior

Worker error:

C:\bug-ts-jest\src\worker.test.ts:1
import {isMainThread, parentPort, Worker} from 'worker_threads';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1031:15)
    at Module._compile (node:internal/modules/cjs/loader:1065:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at MessagePort.<anonymous> (node:internal/main/worker_thread:187:24)
    at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:562:20)
    at MessagePort.exports.emitMessage (node:internal/per_context/messageport:23:28)

ChildProcess error:

C:\bug-ts-jest\src\child-process.test.ts:1
import {fork} from 'child_process';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1031:15)
    at Module._compile (node:internal/modules/cjs/loader:1065:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at MessagePort.<anonymous> (node:internal/main/worker_thread:187:24)
    at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:562:20)
    at MessagePort.exports.emitMessage (node:internal/per_context/messageport:23:28)

Debug log

None

Additional context

No response

Environment

System:
    OS: Windows 10
  Binaries:
    Node: 16.13
    npm: 8.1.2
  npmPackages:
    "jest": "29.3.1",
    "ts-jest": "29.0.3",

MiniSuperDev avatar Nov 20 '22 04:11 MiniSuperDev

Hi, any update on this? I don't know how to proceed :(

MiniSuperDev avatar Jul 30 '23 12:07 MiniSuperDev

right now, you have to register a ts-node or other transpilation require hook in your thread/child process worker entry point to work around this. I would love for ts-jest to handle this as well though.

forivall avatar Sep 12 '23 19:09 forivall

right now, you have to register a ts-node or other transpilation require hook in your thread/child process worker entry point to work around this. I would love for ts-jest to handle this as well though.

Hi, can you give me an example please, thanks.

MiniSuperDev avatar Sep 19 '23 17:09 MiniSuperDev

@MiniSuperDev For some context, I have previously ran into a related issue with mocks in jest, and i left the following comment: https://github.com/jestjs/jest/issues/9467#issuecomment-1590411367 . So, just like how I register the module mocks there, you can use one of the methods describe in ts-node, when launching your child process or in the entry of your worker thread.

forivall avatar Sep 23 '23 00:09 forivall