You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决CommonJS环境下Jest测试时的import语句语法错误?

解决Jest测试时「SyntaxError: Cannot use import statement outside a module」报错

问题说明

项目纯JS编写,正常运行无任何报错,但用Jest启动单元测试时,会弹出SyntaxError: Cannot use import statement outside a module错误,Stack Overflow现有方案未解决该问题。相关配置文件如下:

babel.config.js

module.exports = {
  retainLines: true,
  plugins: [
    'react-hot-loader/babel',
    '@babel/plugin-proposal-class-properties',
    '@babel/plugin-transform-modules-commonjs',
    'babel-plugin-styled-components',
  ],
  presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-flow'],
  env: {
    test: {
      presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-flow'],
    },
    development: {
      presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-flow'],
    },
  },
};

jest.config.js

module.exports = {
  verbose: true,
  transform: {
    '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
    '^.+\\.jsx$': '<rootDir>/node_modules/babel-jest',
  },
  globals: {
    NODE_ENV: 'development',
  },
  setupFiles: ['@babel/polyfill', './jest.setup.js'],
  moduleDirectories: ['node_modules', 'src', 'src/client', 'src/client/components'],
  moduleNameMapper: {
    '^uuid$': require.resolve('uuid'),
  },
  transformIgnorePatterns: [
    '!node_modules/(?!@src/*.)',
  ],
  testEnvironment: 'jsdom',
  clearMocks: true,
  collectCoverage: true,
  collectCoverageFrom: [
    'src/**/*.js',
    '!**/node_modules/**',
    '!**/dist/**',
    '!**/coverage/**',
  ],
  coverageReporters: ['text-summary', 'lcov', 'cobertura'],
  reporters: ['default', 'jest-junit'],
  notify: true,
};

package.json 测试脚本

"test": "NODE_ENV=development jest src --coverage -u --detectOpenHandles --verbose=true --forceExit"

问题根源

  1. Jest的transform配置中,<rootDir>被错误转译为&lt;rootDir&gt;,导致babel-jest路径无效,ES模块语法未被转译
  2. 测试脚本设置NODE_ENV=development,导致Babel加载开发环境配置,而非专门的test环境配置
  3. Babel全局配置硬加了@babel/plugin-transform-modules-commonjs,可能与preset-env冲突,且test环境未针对性配置转译规则
  4. transformIgnorePatterns规则匹配错误,可能导致需要转译的模块被Jest跳过

修复步骤

1. 修正Jest的transform配置

将jest.config.js中的&lt;rootDir&gt;改回<rootDir>,同时简化规则:

module.exports = {
  // 其他配置保持不变
  transform: {
    '^.+\\.(js|jsx)$': '<rootDir>/node_modules/babel-jest',
  },
  // 其他配置保持不变
};

或者更简洁,直接使用babel-jest(Jest会自动查找对应依赖):

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

2. 调整测试脚本的NODE_ENV为test

修改package.json中的测试命令,让Babel加载test环境专属配置:

"test": "NODE_ENV=test jest src --coverage -u --detectOpenHandles --verbose=true --forceExit"

3. 优化Babel的test环境配置

删除babel.config.js全局plugins中的@babel/plugin-transform-modules-commonjs,在test环境中让preset-env自动转译为CommonJS:

module.exports = {
  retainLines: true,
  plugins: [
    'react-hot-loader/babel',
    '@babel/plugin-proposal-class-properties',
    'babel-plugin-styled-components',
  ],
  presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-flow'],
  env: {
    test: {
      presets: [
        ['@babel/preset-env', { modules: 'commonjs' }],
        '@babel/preset-react',
        '@babel/preset-flow'
      ],
    },
    development: {
      presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-flow'],
    },
  },
};

这样开发环境保留ES模块语法,测试环境转成CommonJS,避免环境冲突。

4. 修正transformIgnorePatterns规则

如果项目中没有@src开头的依赖包,直接删除原有规则;如果有需要转译的第三方模块(比如uuid),调整为:

transformIgnorePatterns: [
  '/node_modules/(?!uuid)',
],

确保需要转译的模块不会被Jest忽略。


验证步骤

  1. 删除node_modules和package-lock.json,重新执行npm install
  2. 运行测试命令,检查错误是否消失

内容的提问来源于stack exchange,提问作者John Glabb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:05:24