Next.js中Jest测试报错:Cannot use import statement outside a module 求助
解决Next.js+Jest+Babel单元测试中github-slugger的"Cannot use import statement outside a module"错误
问题场景
使用Next.js框架,结合Jest与Babel进行单元测试时,执行npm test出现「Cannot use import statement outside a module」错误,报错根源是依赖包github-slugger中的import语句。项目文件以.js后缀为主,少量.jsx。尝试过在package.json添加type:module、修改文件后缀为.mjs、多次调整jest.config.js和.babelrc配置,均未解决问题。
报错信息
Jest encountered an unexpected token Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. By default "node_modules" folder is ignored by transformers. Here's what you can do: • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript • 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/configuration For information about custom transformations, see: https://jestjs.io/docs/code-transformation Details: /Users/alex/Desktop/test/tech-blog-web/node_modules/github-slugger/index.js:1 ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { regex } from './regex.js' ^^^^^^ SyntaxError: Cannot use import statement outside a module 1 | import React from 'react'; > 2 | import { slug } from "github-slugger"; | ^
原配置文件
jest.config.js
module.exports = { collectCoverage: true, coverageProvider: 'v8', coverageReporters: ['json', 'html'], coverageDirectory: 'coverage', collectCoverageFrom: [ '**/*.{js,jsx,ts,tsx}', '!**/*.d.ts', '!**/node_modules/**', '!<rootDir>/out/**', '!<rootDir>/.next/**', '!<rootDir>/*.config.js', '!<rootDir>/coverage/**', ], testEnvironment: "jest-environment-jsdom", moduleNameMapper: { "\\.(css|less|scss|sass)$": "identity-obj-proxy", '^@layouts/(.*)$': '<rootDir>/layouts/$1', '^@components/(.*)$': '<rootDir>/layouts/components/$1', '^@partials/(.*)$': '<rootDir>/layouts/partials/$1', '^@shortcodes/(.*)$': '<rootDir>/layouts/shortcodes/$1', '^@config/(.*)$': '<rootDir>/config/$1', '^@json/(.*)$': '<rootDir>/json/$1', '^@hooks/(.*)$': '<rootDir>/hooks/$1', '^@lib/(.*)$': '<rootDir>/lib/$1', }, transform: { '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }], }, moduleFileExtensions: ["js", "jsx", "json", "node", "md"], setupFilesAfterEnv: ['./setupTests.js'], testPathIgnorePatterns: [ "<rootDir>/node_modules/(?!(github-slugger)/)", ], };
.babelrc
"presets": [ "@babel/preset-env", "@babel/preset-react" ]
解决方案
1. 修正transformIgnorePatterns配置
原配置错误使用了testPathIgnorePatterns(用于忽略测试文件路径),应替换为transformIgnorePatterns来指定需要转译的node_modules包:
// jest.config.js中替换原有testPathIgnorePatterns为: transformIgnorePatterns: [ '/node_modules/(?!github-slugger)/', ],
2. 统一Babel配置
使用Next.js时,直接采用next/babel预设即可,无需额外添加@babel/preset-env和@babel/preset-react,避免配置冲突:
// 修改.babelrc为: { "presets": ["next/babel"] }
也可以直接删除.babelrc,因为Next.js的Jest预设已包含必要的Babel配置
3. 移除package.json中的type:module
Jest对ESM的兼容存在局限性,尤其是与Next.js的CommonJS模块混合使用时,移除type:module可避免模块系统冲突。
4. 验证转译规则
确保jest.config.js中的transform规则覆盖.js文件(当前规则^.+\\.(js|jsx|ts|tsx)$已满足),配合transformIgnorePatterns让github-slugger被Babel转译为Jest可识别的CommonJS模块。
测试步骤
- 保存所有配置修改
- 删除
node_modules和package-lock.json(或yarn.lock) - 重新执行
npm install - 运行
npm test验证问题是否解决
内容的提问来源于stack exchange,提问作者yan deru
相关产品推荐
相关产品推荐

