React Native中使用Jest遇到Unexpected token '<'错误解决指南
问题描述
在使用Expo创建的React Native应用中运行Jest测试时,开发者常常会遇到以下错误:
text
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax
...
SyntaxError: Unexpected token '<'
此错误通常发生在测试带有JSX语法的组件(如.spec.tsx
文件)时,典型场景包括:
- 使用
@testing-library/react-native
库进行组件测试 - 配置了Jest但没有正确处理JSX/TSX转换
transformIgnorePatterns
配置不正确- Jest预设混合冲突(如同时使用
jest-expo
和ts-jest
) - 测试环境配置错误(如使用
jsdom
代替React Native环境)
错误的核心原因是Jest无法解析JSX/TSX语法,主要由于错误的配置导致node_modules中的相关依赖未被正确转换。
解决方案
推荐方案:更新Jest配置(遵循Expo官方建议)
修改
jest.config.js
文件:jsmodule.exports = { preset: 'jest-expo', transformIgnorePatterns: [ 'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)' ], testPathIgnorePatterns: [ '<rootDir>/node_modules/', '<rootDir>/.maestro/', '@react-native' ], setupFiles: ['<rootDir>/test/setup.ts'], setupFilesAfterEnv: ['<rootDir>/jest-setup-after-env.js'] };
移除
ts-jest
依赖
如果你在项目中安装了ts-jest
,请通过npm或yarn移除:bashnpm uninstall ts-jest # 或 yarn remove ts-jest
确保使用正确的测试环境
jest-expo
预设会自动配置React Native测试环境,移除以下配置项:diff- testEnvironment: 'jsdom'
替代方案:为TypeScript显式配置ts-jest
如果必须使用ts-jest
进行特殊类型处理:
js
module.exports = {
preset: 'jest-expo',
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'ts-jest',
},
globals: {
'ts-jest': {
babelConfig: {
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg))'
],
},
},
},
// 其余配置与上方案相同
};
辅助配置
Babel配置检查
确保babel.config.js
包含Expo预设:jsmodule.exports = function(api) { api.cache(true); return { presets: ['babel-preset-expo'], }; };
清除Jest缓存
在修改配置后运行:bashnpx jest --clearCache
原理解析
为何出现此错误?
- JSX未转换:Jest默认不会处理JSX语法,需要Babel/ts-jest转换
- node_modules忽略逻辑:Jest默认忽略node_modules转换,但React Native依赖需要处理
- 混合预设冲突:
jest-expo
和ts-jest
的转换规则可能冲突 - 环境错误:
jsdom
环境无法解析React Native特有语法
transformIgnorePatterns关键作用
regex
node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|...)
此正则表达式的含义:
(?!...)
: 否定前瞻 - 排除特定模块|
: 逻辑或 - 匹配多个模块模式- 最终效果:包含
react-native
、expo
等关键库进行转换处理
不同方案的适用场景
方案 | 适用场景 | 优点 | 注意事项 |
---|---|---|---|
标准方案 | 大部分Expo项目 | 配置简单,官方推荐 | 需删除ts-jest |
ts-jest方案 | 需要高级类型检查的项目 | 支持TypeScript特性 | 配置复杂 |
扩展建议
常见陷阱
- 版本兼容问题:确保所有测试相关库版本兼容bash
npm install --save-dev jest-expo@^48.0.0 @testing-library/react-native@^11.0.0
- 缓存问题:每次调整配置后清除Jest缓存
- 路径错误:检查
setupFiles
等路径的实际位置是否正确
最佳实践
- 简化transformIgnorePatterns:可先设定为空数组测试依赖问题js
transformIgnorePatterns: [] // 临时测试
- 分离测试配置:大型项目可使用
projects
配置多个测试环境 - 定期更新配置:关注Expo测试文档最新建议
按照上述方案配置后,Jest应能正确解析JSX/TSX语法,解决Unexpected token '<'
错误,并成功运行React Native组件测试。