Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest: node_module dependency uses import statement and crashes the test

TL;DR

My Jest test crashes with

    SyntaxError: Cannot use import statement outside a module

because a node_module uses an import statement. How can I fix this error?

Context

I'm writing a Next.js app, use Jest as my test runner and Magic for authentication. I have ts-node installed to run my Jest tests in TypeScript.

I want to test a serverless function that uses the @magic-sdk/admin package, which in turn uses ethereum-cryptography for its keccak hash algorithm.

When I run the test it crashes because the ethereum-cryptography package uses an import statement.

 FAIL  src/features/user-authentication/login-handler.test.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/my-computer/dev/my-app/node_modules/ethereum-cryptography/src/keccak.ts:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { createHashFunction } from "./hash-utils";
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (node_modules/ethereum-cryptography/src/keccak.ts:3:26)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        2.292 s
Ran all test suites related to changed files.

My tsconfig.json is

{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "./src",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "es5"
  },
  "exclude": ["node_modules"],
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

My jest.config.ts looks like this.

export default {
  moduleDirectories: ['node_modules', 'src'],
  moduleNameMapper: {
    '\\.(css|less)$': '<rootDir>/src/tests/mocks/style-mock.js',
  },
  setupFilesAfterEnv: ['./jest.setup.ts'],
  setupFiles: ['<rootDir>/src/tests/setup-environment-variables.js'],
};

What I Tried

It looks like this is a common error with tons of Google results, but none of them worked. Here is what I tried.

I tried including the folder in transformIgnorePatterns.

const esModules = ['ethereum-cryptography', '@magic-sdk/admin'].join('|');

export default {
  moduleDirectories: ['node_modules', 'src'],
  moduleNameMapper: {
    '\\.(css|less)$': '<rootDir>/src/tests/mocks/style-mock.js',
  },
  setupFilesAfterEnv: ['./jest.setup.ts'],
  setupFiles: ['<rootDir>/src/tests/setup-environment-variables.js'],
  transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
};

It did not work.

I tried explicitly transforming it using transform and ts-jest.

transform: { '^.+\\.(ts|tsx|js|jsx)?$': 'ts-jest' },

I also tried changing the module to commonjs in the tsconfig.json, which didn't work either.

How can I fix this and get the test to run?

like image 259
J. Hesters Avatar asked Jun 17 '26 17:06

J. Hesters


1 Answers

I found my error. My jest.config.ts had src in the moduleDirectories because I configured Next.js to support absolute imports.

  moduleDirectories: ['node_modules', 'src'], // 🔴 fails

When I changed it to be explicitly from the rootDir it worked 👇

export default {
  moduleDirectories: ['node_modules', '<rootDir>/src'],
  moduleNameMapper: {
    '\\.(css|less)$': '<rootDir>/src/tests/mocks/style-mock.js',
  },
  setupFilesAfterEnv: ['./jest.setup.ts'],
  setupFiles: ['<rootDir>/src/tests/setup-environment-variables.js'],
};
like image 116
J. Hesters Avatar answered Jun 21 '26 13:06

J. Hesters