You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native项目中Jest与TypeScript配置失败求助

React Native + Jest + TypeScript 配置故障排查

我正在给React Native项目配置Jest和TypeScript,但一直无法正常运行。已经按照jest/ts-jest官方文档配置,但修改配置文件后会出现两种错误:

错误1:Unexpected token '<'

\Development\stories\__tests__\App.test.tsx:14
    (0, react_native_1.render)(<App_1.default />);
                               ^

SyntaxError: Unexpected token '<'

  at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1678:14)

错误2:Cannot use import statement outside a module

SyntaxError: Cannot use import statement outside a module

> 1 | import { getStorybookUI } from '@storybook/react-native';
    | ^
  2 |
  3 | import './storybook.requires';
  4 |

项目配置文件

package.json

{
  "name": "stories",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "update-stories": "sb-rn-get-stories --config-path .storybook/.ondevice",
    "prestart": "yarn update-stories",
    "storybook-watcher": "sb-rn-watcher --config-path .storybook/.ondevice",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  },
  "dependencies": {
    "@react-native-async-storage/async-storage": "^1.17.10",
    "@react-native-community/datetimepicker": "^6.5.0",
    "@react-native-community/slider": "^4.3.2",
    "react": "18.1.0",
    "react-native": "0.70.2"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/runtime": "^7.12.5",
    "@react-native-community/eslint-config": "^2.0.0",
    "@storybook/addon-actions": "^6.5.12",
    "@storybook/addon-controls": "^6.5.12",
    "@storybook/addon-essentials": "^6.5.12",
    "@storybook/addon-links": "^6.5.12",
    "@storybook/addon-ondevice-actions": "^6.0.1-beta.8",
    "@storybook/addon-ondevice-backgrounds": "^6.0.1-beta.8",
    "@storybook/addon-ondevice-controls": "^6.0.1-beta.8",
    "@storybook/addon-ondevice-notes": "^6.0.1-beta.8",
    "@storybook/addon-react-native-web": "^0.0.18",
    "@storybook/react": "6.3",
    "@storybook/react-native": "^6.0.1-beta.8",
    "@storybook/testing-library": "^0.0.13",
    "@testing-library/jest-native": "^5.0.0",
    "@testing-library/react-native": "^11.2.0",
    "@tsconfig/react-native": "^2.0.2",
    "@types/jest": "^29.1.1",
    "@types/react-native": "^0.70.4",
    "@types/react-test-renderer": "^18.0.0",
    "@typescript-eslint/eslint-plugin": "^5.37.0",
    "@typescript-eslint/parser": "^5.37.0",
    "babel-jest": "^29.1.2",
    "babel-loader": "^8.2.5",
    "babel-plugin-react-native-web": "^0.18.9",
    "eslint": "^7.32.0",
    "jest": "^29.1.2",
    "metro-react-native-babel-preset": "0.72.3",
    "react-dom": "18.2.0",
    "react-native-safe-area-context": "^4.4.1",
    "react-native-web": "^0.18.9",
    "react-test-renderer": "18.1.0",
    "ts-jest": "^29.0.3",
    "typescript": "^4.8.3"
  },
  "resolutions": {
    "@types/react": "^17"
  }
}

tsconfig.json

// prettier-ignore
{
  "extends": "@tsconfig/react-native/tsconfig.json",     /* Recommended React Native TSConfig base */
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Completeness */
    "skipLibCheck": true,                                 /* Skip type checking all .d.ts files. */
    "allowSyntheticDefaultImports": true,
  }
}

tsconfig.spec.json

// tsconfig.spec.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "jsx": "react-native", // Switching to "react" throws "SyntaxError: Cannot use import statement outside a module"
  }
}

jest.config.js

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'react-native',
  transform: {
    '^.+\\.jsx$': 'babel-jest',
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        tsconfig: 'tsconfig.spec.json',
      },
    ],
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],

  transformIgnorePatterns: [
    'node_modules/(?!(jest-)?@react-native|react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base)',
  ],
  setupFilesAfterEnv: [
    '@testing-library/jest-native/extend-expect',
    '<rootDir>/__mocks__/globalMock.js',
  ],
};

babel.config.js

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
};

App.test.tsx

/**
 * @format
 */

import 'react-native';
import React from 'react';
import App from '../App';

import { render } from '@testing-library/react-native';

test('renders correctly', () => {
  render(<App />);
});

解决方案

修复「Unexpected token '<'」错误

该错误是TSX文件的JSX语法未被正确转译,调整以下配置:

  1. 修改tsconfig.spec.json的jsx选项为react-jsx(适配React 18自动JSX转换):
// tsconfig.spec.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "jsx": "react-jsx"
  }
}
  1. 简化jest.config.js的transform规则,确保TS/TSX文件被ts-jest正确处理:
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'react-native',
  transform: {
    '^.+\\.(js|jsx)$': 'babel-jest',
    '^.+\\.(ts|tsx)$': 'ts-jest'
  },
  // 其余配置保持不变
};

修复「Cannot use import statement outside a module」错误

该错误是Storybook相关文件未被Jest转译,将@storybook/react-native加入transformIgnorePatterns白名单:

transformIgnorePatterns: [
  'node_modules/(?!(jest-)?@react-native|react-native|react-clone-referenced-element|@react-native-community|@storybook/react-native|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base)',
],

额外优化

  1. 修正babel.config.js的错误注释(它不是Jest配置文件):
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
};
  1. 清除Jest缓存,避免旧配置残留:
jest --clearCache
  1. 确认App.tsx(若为TSX文件)导出默认组件,保证测试导入路径正确。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:25:25