Skip to content

Jest SyntaxError: Cannot use import statement outside a module

Problem Overview

When testing JavaScript/TypeScript applications with Jest, you might encounter the error: SyntaxError: Cannot use import statement outside a module. This typically occurs when Jest encounters ES module syntax (import/export) in files that aren't being properly transformed to CommonJS format.

Common Causes

  • Modules in node_modules not being transformed by Jest
  • Incorrect Jest configuration for TypeScript/ES modules
  • Missing or misconfigured Babel/TypeScript transformation
  • Mixed module systems in your project

Solutions

Solution 1: Configure Jest to Transform ES Modules

The most effective solution is to configure Jest to properly transform the problematic modules:

javascript
// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  transform: {
    'node_modules/variables/.+\\.(j|t)sx?$': 'ts-jest'
  },
  transformIgnorePatterns: [
    'node_modules/(?!variables/.*)'
  ]
};

This configuration:

  • Uses ts-jest as the preset for TypeScript
  • Specifically transforms files in the variables package
  • Prevents Jest from ignoring the variables package during transformation

Solution 2: Using ts-jest with ESM Support

If you're using ES modules in your project:

  1. Ensure your package.json has:
json
{
  "type": "module"
}
  1. Configure Jest for ESM support:
javascript
// jest.config.ts
import type { JestConfigWithTsJest } from 'ts-jest'

const jestConfig: JestConfigWithTsJest = {
  preset: 'ts-jest/presets/default-esm',
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  },
  transform: {
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        useESM: true,
      },
    ],
  },
}

export default jestConfig

Solution 3: Enable JavaScript Processing in TypeScript

If you have JavaScript files that need processing:

javascript
// jest.config.js
module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  globals: {
    'ts-jest': {
      tsconfig: '<rootDir>/test/tsconfig.json',
    },
  },
  transformIgnorePatterns: [
    'node_modules/(?!troublesome-dependency/.*)',
  ],
}

Create a separate tsconfig.json for Jest with:

json
{
  "compilerOptions": {
    "allowJs": true
  }
}

WARNING

This approach can significantly slow down your tests as it processes all node_modules.

javascript
// jest.config.js
module.exports = {
  transformIgnorePatterns: [
    '//node_modules'  // Hack to transform all node_modules
  ]
}

Solution 5: Module Name Mapping

For specific packages that need transformation:

javascript
// jest.config.js
module.exports = {
  moduleNameMapper: {
    '^variables$': 'variables/dist/cjs',
    '^antd/es/(.*)$': 'antd/lib/$1',
  }
}

Alternative Testing Solutions

Using Vitest

If Jest configuration becomes too complex, consider using Vitest as an alternative:

bash
npm remove jest ts-jest @types/jest
npm install -D vite vitest

Create vite.config.ts:

typescript
/// <reference types="vitest" />
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    // Your test configuration
  },
})

Update package.json:

json
{
  "scripts": {
    "test": "vitest"
  }
}

Troubleshooting Tips

  1. Clear cache: Run npx jest --clearCache to clear Jest's cache
  2. Delete compiled JS files: Remove any previously generated JavaScript files from your test directory
  3. Check Babel configuration: Ensure you're using babel.config.js instead of .babelrc.js for project-wide configuration
  4. Verify preset configuration: Ensure your Jest preset matches your project's needs

Common Pitfalls

  • Mixed presets: Using both babel-jest and ts-jest without proper configuration
  • Incorrect transform patterns: Regular expressions that don't match the intended files
  • Cache issues: Old transformed files causing conflicts
  • Module resolution: Incorrect path mappings in moduleNameMapper

Best Practices

  1. Use a consistent module system throughout your project
  2. Keep your Jest configuration as simple as possible
  3. Test your configuration with a simple test case first
  4. Consider using Vitest for newer projects with extensive ESM usage
  5. Regularly update your testing dependencies to benefit from bug fixes

By following these solutions and best practices, you should be able to resolve the "Cannot use import statement outside a module" error and ensure your Jest tests run smoothly with ES modules and TypeScript.