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_modulesnot 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:
// 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-jestas the preset for TypeScript - Specifically transforms files in the
variablespackage - Prevents Jest from ignoring the
variablespackage during transformation
Solution 2: Using ts-jest with ESM Support
If you're using ES modules in your project:
- Ensure your
package.jsonhas:
{
"type": "module"
}- Configure Jest for ESM support:
// 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 jestConfigSolution 3: Enable JavaScript Processing in TypeScript
If you have JavaScript files that need processing:
// 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:
{
"compilerOptions": {
"allowJs": true
}
}Solution 4: Transform All Node Modules (Not Recommended)
WARNING
This approach can significantly slow down your tests as it processes all node_modules.
// 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:
// 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:
npm remove jest ts-jest @types/jest
npm install -D vite vitestCreate vite.config.ts:
/// <reference types="vitest" />
import { defineConfig } from 'vite'
export default defineConfig({
test: {
// Your test configuration
},
})Update package.json:
{
"scripts": {
"test": "vitest"
}
}Troubleshooting Tips
- Clear cache: Run
npx jest --clearCacheto clear Jest's cache - Delete compiled JS files: Remove any previously generated JavaScript files from your test directory
- Check Babel configuration: Ensure you're using
babel.config.jsinstead of.babelrc.jsfor project-wide configuration - Verify preset configuration: Ensure your Jest preset matches your project's needs
Common Pitfalls
- Mixed presets: Using both
babel-jestandts-jestwithout 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
- Use a consistent module system throughout your project
- Keep your Jest configuration as simple as possible
- Test your configuration with a simple test case first
- Consider using Vitest for newer projects with extensive ESM usage
- 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.