如何用Jest测试@mdx-js/mdx?transformIgnorePatterns对develop包失效
背景
目标是在Jest中编写可导入ESM模块@mdx-js/mdx的测试用例,当前开发的库包为CommonJS配置,通过jest.config.ts中的transform和transformIgnorePatterns处理ESM依赖转译。
当前Jest配置
/* eslint-disable */ import { readFileSync } from 'fs'; import type { Config } from 'jest'; // Reading the SWC compilation config and remove the "exclude" // for the test files to be compiled by SWC const { exclude: _, ...swcJestConfig } = JSON.parse(readFileSync(`${__dirname}/.swcrc`, 'utf-8')); // disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves. // If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude" if (swcJestConfig.swcrc === undefined) { swcJestConfig.swcrc = false; } // Uncomment if using global setup/teardown files being transformed via swc // jest needs EsModule Interop to find the default exported setup/teardown functions // swcJestConfig.module.noInterop = false; export default { displayName: 'jest-mdx-transformer', preset: '../../jest.preset.js', transform: { '^.+\\.[tj]s$': ['@swc/jest', swcJestConfig], }, transformIgnorePatterns: [ '/node_modules/(?!(@mdx-js/mdx|develop|markdown-extensions|unist-util-stringify-position|vfile|vfile-message)/)', ], moduleFileExtensions: ['ts', 'js', 'json', 'mdx', 'html'], testEnvironment: 'node', coverageDirectory: '../../coverage/libs/jest-mdx-transformer', } satisfies Config;
问题现象
此前通过扩展transformIgnorePatterns正则让Jest转译指定node_modules包的方法一直有效,但添加develop包后,无论是否将其加入正则,都会触发如下错误:
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-transformationDetails:
/workspace/perpetual-cabbage/node_modules/devlop/lib/default.js:1
({"Object.":function(module,exports,require,__dirname,__filename,jest){export function deprecate(fn) {
^^^^^^SyntaxError: Unexpected token 'export'
3 | describe('watheia.cabbage/jest-mdx-transformer', () => {
4 | it('should render mdx in jest', async () => {5 | const result = await compile('# Hello, World!');
| ^
6 | expect(result).toBeDefined();
7 | });
8 | });at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1505:14)
at Object.(../../node_modules/@mdx-js/mdx/lib/core.js:136:17)
at Object.(../../node_modules/@mdx-js/mdx/lib/compile.js:40:15)
at Object.(../../node_modules/@mdx-js/mdx/index.js:46:18)
at Object.(test/jest-mdx-transformer.spec.ts:5:14)
问题原因
从错误路径可以看到,实际出问题的包是devlop(拼写为d-e-v-l-o-p,仅一个e),但你的transformIgnorePatterns正则里写的是develop(两个e),拼写不匹配导致这个包没有被纳入转译范围,Jest依旧忽略了它,所以遇到ESM语法时抛出错误。
解决办法
修正transformIgnorePatterns里的包名拼写,把develop改成devlop:
transformIgnorePatterns: [ '/node_modules/(?!(@mdx-js/mdx|devlop|markdown-extensions|unist-util-stringify-position|vfile|vfile-message)/)', ],
重新运行测试即可解决该问题。
内容的提问来源于stack exchange,提问作者drkstr101

