Skip to content

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-expots-jest
  • 测试环境配置错误(如使用jsdom代替React Native环境)

错误的核心原因是Jest无法解析JSX/TSX语法,主要由于错误的配置导致node_modules中的相关依赖未被正确转换。

解决方案

推荐方案:更新Jest配置(遵循Expo官方建议)

  1. 修改jest.config.js文件:

    js
    module.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']
    };
  2. 移除ts-jest依赖
    如果你在项目中安装了ts-jest,请通过npm或yarn移除:

    bash
    npm uninstall ts-jest
    # 或
    yarn remove ts-jest
  3. 确保使用正确的测试环境
    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))'
        ],
      },
    },
  },
  // 其余配置与上方案相同
};

辅助配置

  1. Babel配置检查
    确保babel.config.js包含Expo预设:

    js
    module.exports = function(api) {
      api.cache(true);
      return {
        presets: ['babel-preset-expo'],
      };
    };
  2. 清除Jest缓存
    在修改配置后运行:

    bash
    npx jest --clearCache

原理解析

为何出现此错误?

  • JSX未转换:Jest默认不会处理JSX语法,需要Babel/ts-jest转换
  • node_modules忽略逻辑:Jest默认忽略node_modules转换,但React Native依赖需要处理
  • 混合预设冲突jest-expots-jest的转换规则可能冲突
  • 环境错误jsdom环境无法解析React Native特有语法

transformIgnorePatterns关键作用

regex
node_modules/(?!((jest-)?react-native|@react-native(-community)?|expo(nent)?|...)

此正则表达式的含义:

  • (?!...): 否定前瞻 - 排除特定模块
  • |: 逻辑或 - 匹配多个模块模式
  • 最终效果:包含react-nativeexpo等关键库进行转换处理

不同方案的适用场景

方案适用场景优点注意事项
标准方案大部分Expo项目配置简单,官方推荐需删除ts-jest
ts-jest方案需要高级类型检查的项目支持TypeScript特性配置复杂

扩展建议

常见陷阱

  1. 版本兼容问题:确保所有测试相关库版本兼容
    bash
    npm install --save-dev jest-expo@^48.0.0 @testing-library/react-native@^11.0.0
  2. 缓存问题:每次调整配置后清除Jest缓存
  3. 路径错误:检查setupFiles等路径的实际位置是否正确

最佳实践

  1. 简化transformIgnorePatterns:可先设定为空数组测试依赖问题
    js
    transformIgnorePatterns: [] // 临时测试
  2. 分离测试配置:大型项目可使用projects配置多个测试环境
  3. 定期更新配置:关注Expo测试文档最新建议

按照上述方案配置后,Jest应能正确解析JSX/TSX语法,解决Unexpected token '<'错误,并成功运行React Native组件测试。