Jest测试Preact组件时遇JSX意外令牌错误求助
我帮你排查下这个问题——你遇到的Jest生成覆盖率时的意外令牌错误,核心原因是JSX语法没有被Babel正确转译,导致Jest无法解析<Gallery>这类标签。结合你提供的配置和代码,我整理了几个关键修复步骤:
1. 修复Babel配置的语法错误
你的.babelrc里presets的写法有问题:把@babel/preset-env和@babel/preset-react塞进了同一个数组项,这会让Babel无法正确识别React/Preact的JSX转译规则。
原错误配置:
"presets": [ [ "@babel/preset-env", { "targets": { "node": "current" } }, "@babel/preset-react" ] ]
修正为:
每个Preset要单独作为数组项:
"presets": [ ["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/preset-react" ]
另外,你同时安装了新旧两套React预设(@babel/preset-react和旧版babel-preset-react),容易引发冲突,建议卸载旧版:
npm uninstall babel-preset-react babel-preset-es2015
2. 让Babel适配Preact的JSX转译
因为你用的是Preact而非React,需要确保Babel把JSX转译为Preact的h函数,而不是React的createElement。有两种方式可选:
方式一:使用Preact专属Babel预设
安装@babel/preset-preact:
npm install --save-dev @babel/preset-preact
然后更新.babelrc的presets:
"presets": [ ["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/preset-preact" ]
方式二:全局配置JSX编译的pragma
如果你想保留现有预设,可在Babel配置里全局指定JSX编译用Preact的h函数,这样就不用在每个JSX文件顶部加/** @jsx h */注释了:
在.babelrc的plugins中添加:
"plugins": [ ["@babel/plugin-transform-react-jsx", { "pragma": "h" }], // 你的其他插件... ]
3. 优化Jest配置
你的Jest配置可以进一步完善,确保它能正确处理DOM测试和Preact的模块映射:
更新package.json中的jest配置:
"jest": { "verbose": true, "testEnvironment": "jsdom", // 测试DOM组件需要jsdom环境 "transform": { "^.+\\.jsx?$": "babel-jest" }, "collectCoverageFrom": [ "**/*.{js,jsx}", "!**/node_modules/**", "!**/dist/**" // 排除打包后的产物目录 ], "moduleNameMapper": { // 如果代码里有react导入,自动映射到preact兼容层 "^react$": "preact/compat", "^react-dom$": "preact/compat" } }
4. 清理依赖缓存,避免冲突
有时候旧的依赖缓存会导致Babel和Jest协同异常,建议执行以下步骤重置依赖:
rm -rf node_modules package-lock.json npm install npm cache clean --force
验证修复
最后运行测试命令:
npm test
现在Jest应该能正常转译JSX并生成覆盖率报告了。
内容的提问来源于stack exchange,提问作者Eli Nathan

