33

I'm writing my first package and I just converted it to be TypeScript compatible, but this somehow affected my GitHub workflow. When I run my tests using Jest locally, they work just fine. When my tests are run on GitHub, it succeeds for 10.x, but not 12.x or 14.x, giving me the following error:

(node:2397) ExperimentalWarning: The ESM module loader is experimental.
ReferenceError: module is not defined
    at file:///home/runner/work/enhancedMathJS/enhancedMathJS/jest.config.js:1:1
    at ModuleJob.run (internal/modules/esm/module_job.js:146:37)
    at async Loader.import (internal/modules/esm/loader.js:182:24)
    at async readConfigFileAndSetRootDir (/home/runner/work/enhancedMathJS/enhancedMathJS/node_modules/jest-config/build/readConfigFileAndSetRootDir.js:126:32)
    at async readConfig (/home/runner/work/enhancedMathJS/enhancedMathJS/node_modules/jest-config/build/index.js:217:18)
    at async readConfigs (/home/runner/work/enhancedMathJS/enhancedMathJS/node_modules/jest-config/build/index.js:406:26)
    at async runCLI (/home/runner/work/enhancedMathJS/enhancedMathJS/node_modules/@jest/core/build/cli/index.js:230:59)
    at async Object.run (/home/runner/work/enhancedMathJS/enhancedMathJS/node_modules/jest/node_modules/jest-cli/build/cli/index.js:163:37)
npm ERR! Test failed.  See above for more details.
enhancedmath@2.0.0 test /home/runner/work/enhancedMathJS/enhancedMathJS
jest

File jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['<rootDir>/**/__tests__/**/*.spec.ts'],
  testPathIgnorePatterns: ['/node_modules/'],
  coverageDirectory: './test-reports',
  coveragePathIgnorePatterns: ['node_modules', 'src/database', 'src/test', 'src/types'],
  reporters: ['default', 'jest-junit'],
  globals: { 'ts-jest': { diagnostics: false } },
};

Workflow

name: Node.js CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [10.x, 12.x, 14.x]

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - run: npm test

I don't understand what the problem is, since everything works locally, but not for every version of Node.js on GitHub.

If you want to check out the files and errors for yourself, you can find my repository here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mout Pessemier
  • 1,665
  • 3
  • 19
  • 33
  • 1
    Thought 1: if you have ESM code, it has to be a real ESM, not "a mix of ESM and legacy code that also tries to use node's CJS `module` namespace". And if you don't have mixed code (but it sure sounds like you do), thought 2: https://jestjs.io/docs/en/ecmascript-modules, point 2? – Mike 'Pomax' Kamermans Nov 21 '20 at 17:58
  • 1
    No, I still get module not defined as the main error, and with version `12.x`, it's still considered experimental – Mout Pessemier Nov 21 '20 at 18:07
  • it was, which is why you need that runtime flag passed through if you're still on the previous LTS version (the current LTS is 14). That said: start reducing until you have a single file left that still generates that error: now you have a [mcve] to show folks here, so they can meaningfully comment on why. Without code, there's just too many details missing. – Mike 'Pomax' Kamermans Nov 21 '20 at 18:10

3 Answers3

49

I got it working by installing ts-node and updating my jest.config.js file to a jest.config.ts file:

npm i --save-dev ts-node

Jest config

export default {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['<rootDir>/**/__tests__/**/*.spec.ts'],
  testPathIgnorePatterns: ['/node_modules/'],
  coverageDirectory: './coverage',
  coveragePathIgnorePatterns: ['node_modules', 'src/database', 'src/test', 'src/types'],
  reporters: ['default', 'jest-junit'],
  globals: { 'ts-jest': { diagnostics: false } },
  transform: {},
};
Mout Pessemier
  • 1,665
  • 3
  • 19
  • 33
  • 1
    A simple rename fixed me!!! Thank you – Zymotik Nov 01 '22 at 15:20
  • `globals: { 'ts-jest': { diagnostics: false } },` worked for me, but received the following warning `ts-jest[ts-jest-transformer] (WARN) Define ts-jest config under globals is deprecated. Please do transform: {: ['ts-jest', { /* ts-jest config goes here in Jest */ }]},`. I removed the globals key and added `diagnostics: false,` to transform, but that didn't work. `transform: {'^.+\\.tsx?$': ['ts-jest',{tsconfig: __dirname + '/tsconfig.json',diagnostics: false}]}` – Bhavik Aug 10 '23 at 12:33
45

I use esm in my project. And config { type: "module" } in file package.json. So just change module.exports = to export default.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paprika.W
  • 451
  • 4
  • 4
  • 3
    +1, The other answer is suggesting you might need `ts-node` when very likely all you are doing is having a commonjs VS esModules type of issue – Cameron Oct 26 '21 at 15:29
  • Any way to achieve this with an existing [esbuild](https://www.npmjs.com/package/esbuild) setup? – Ingo Steinke Aug 28 '23 at 12:16
14

I got the very similar error ReferenceError: module is not defined in ES module scope when running Jest in ESM context.

This did the trick for me:

In jest.config.js, change

module.exports = {
  /* config here */
}

to

export default {
  /* config here */ 
}

Most tutorials and the config scaffolding that comes with Jest make the config a CJS module which will lead to the above error if you use it in ESM context.

Fred
  • 1,103
  • 2
  • 14
  • 35