使用Jest+Yarn运行测试遇SyntaxError: Unexpected token 'export'求助
解决Jest运行测试时的ECMAScript模块语法错误
问题场景
添加date-holidays包后,执行Jest测试时触发语法错误,提示无法解析export关键字,错误来自依赖包astronomia的ES模块代码。Jest默认会忽略node_modules目录下文件的语法转换,但该包使用了未转译的ES模块语法,导致解析失败。
错误详情
Test suite failed to run 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/username/system/.yarn/cache/astronomia-npm-4.1.1-364d12a189-ec80faf6e0.zip/node_modules/astronomia/data/vsop87Bearth.js:2611 export default m; ^^^^^^ SyntaxError: Unexpected token 'export' at Runtime.createScriptFromCode (../.yarn/cache/jest-runtime-npm-27.4.6-d1229253b6-64d833c7d7.zip/node_modules/jest-runtime/build/index.js:1728:14) at Object.<anonymous> (../.yarn/cache/date-holidays-parser-npm-3.4.3-ff1621004b-c5c8f51b62.zip/node_modules/date-holidays-parser/lib/vsop87Bearth.cjs:5:21)
尝试过的无效配置
曾在jest.config.js中配置transformIgnorePatterns,但由于路径匹配规则错误,未生效:
module.exports = { preset: "ts-jest", testEnvironment: "node", projects: ["<rootDir>/inventory", "<rootDir>/backoffice/api"], transformIgnorePatterns: [ "<rootDir>/.yarn/cache/astronomia-npm-4.1.1-364d12a189-ec80faf6e0.zip/node_modules/(?!astronomia)", ], };
可行解决方法
方法1:修正transformIgnorePatterns匹配规则
transformIgnorePatterns的作用是指定不需要Jest转译的路径,因此需要将astronomia包排除在忽略列表外,让Jest对其进行转译。针对Yarn缓存的路径结构,使用更灵活的正则匹配:
module.exports = { preset: "ts-jest", testEnvironment: "node", projects: ["<rootDir>/inventory", "<rootDir>/backoffice/api"], // 排除所有以astronomia-npm-开头的缓存包,允许Jest转译它们 transformIgnorePatterns: [ "<rootDir>/.yarn/cache/(?!astronomia-npm-)" ], // 确保ts-jest能处理JS文件的转译 transform: { "^.+\\.(ts|js)$": "ts-jest" } };
方法2:全局排除ES模块类型的依赖包
如果后续还有其他类似的ES模块依赖出现同样问题,可以使用更通用的规则,匹配所有未转译的ES模块:
module.exports = { preset: "ts-jest", testEnvironment: "node", projects: ["<rootDir>/inventory", "<rootDir>/backoffice/api"], transformIgnorePatterns: [ "/node_modules/(?!astronomia|其他需要转译的包名)" ], transform: { "^.+\\.(ts|js)$": "ts-jest" } };
方法3:使用Jest的ES模块支持(适用于Jest 28+)
如果项目本身使用ES模块,可以直接启用Jest的ES模块支持,修改package.json添加:
{ "type": "module", "jest": { "preset": "ts-jest/presets/default-esm", "testEnvironment": "node", "extensionsToTreatAsEsm": [".ts"], "moduleNameMapper": { "^(\\.{1,2}/.*)\\.js$": "$1" } } }
同时将jest.config.js重命名为jest.config.mjs以支持ES模块配置。
内容的提问来源于stack exchange,提问作者GoWithTheFlow
相关产品推荐
相关产品推荐

