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

TypeScript+React项目Jest测试遇Unexpected token '<'错误求解

解决TypeScript+React项目中Jest解析JSX时的SyntaxError: Unexpected token '<'问题

问题背景

在TypeScript和React项目中运行Jest测试用例时,触发SyntaxError: Unexpected token '<'错误,该错误发生在Jest尝试解析包含JSX语法的文件时。

项目配置信息

package.json

{
  "name": "ignite-mentorship",
  "version": "1.0.20",
  "private": true,
  "scripts": {
    "prepare": "husky install",
    "dev": "next dev --experimental-https --experimental-https-key local.blueprint.com.key --experimental-https-cert local.blueprint.com.crt",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest --config ./jest.config.js"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["prettier --write", "eslint --fix", "git add"],
    "*.{md,mdx,css,json}": ["prettier --write"]
  },
  "dependencies": {
    "@apollo/client": "^3.10.8",
    "@apollo/experimental-nextjs-app-support": "^0.11.2",
    "@azure/msal-browser": "^3.25.0",
    "axios": "^1.7.3",
    "next": "^14.2.13",
    "next-auth": "^5.0.0-beta.19",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.53.0",
    "react-select": "^5.8.0",
    "styled-components": "^6.1.13"
  },
  "devDependencies": {
    "@babel/core": "^7.25.7",
    "@babel/plugin-syntax-jsx": "^7.25.7",
    "@babel/preset-env": "^7.25.7",
    "@babel/preset-react": "^7.25.7",
    "@babel/preset-typescript": "^7.25.7",
    "@changesets/changelog-github": "^0.4.8",
    "@changesets/cli": "^2.27.1",
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^16.0.1",
    "@testing-library/user-event": "^14.5.2",
    "@types/jest": "^29.5.13",
    "@types/node": "18.11.19",
    "@types/react": "18.0.27",
    "@types/styled-components": "^5.1.34",
    "@typescript-eslint/eslint-plugin": "5.50.0",
    "@typescript-eslint/parser": "5.50.0",
    "babel-jest": "^29.7.0",
    "eslint": "8.33.0",
    "eslint-config-next": "13.1.6",
    "eslint-config-prettier": "^9.1.0",
    "husky": "8.0.3",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "lint-staged": "13.1.0",
    "ts-jest": "^29.2.5",
    "typescript": "4.9.5"
  }
}

jest.config.js

module.exports = {
  roots: ["<rootDir>"],
  transform: {
    "^.+\\.tsx?$": "ts-jest",
    // Update to include .tsx files
  },
  // Ensure this pattern matches your test files moduleFileExtensions: ['ts', 'tsx', 'js', 'json', 'node'],
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
  // Include .tsx
  collectCoverage: true,
  clearMocks: true,
  coverageDirectory: "coverage",
};

babel.config.js

module.exports = {
  presets: [
    "@babel/preset-env",
    "@babel/preset-typescript",
    ["@babel/preset-react", { runtime: "automatic" }],
  ],
};

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "types": ["node", "jest", "@testing-library/jest-dom"],
    "paths": {
      "@/components/*": ["./components/*"],
      "@/lib/*": ["./lib/*"],
      "@/hooks/*": ["./hooks/*"],
      "@/types/*": ["./types/*"],
      "@/shared/*": ["./shared/*"],
      "@/auth": ["./auth"],
      "@/public/*": ["./public/*"]
    },
    "incremental": true,
    "plugins": [{ "name": "next" }]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts",
    "src",
    "__tests__"
  ],
  "exclude": ["node_modules", "cypress"]
}

jest.setup.js

import '@testing-library/jest-dom';

错误详情

执行npx jest --verbose时,触发SyntaxError: Unexpected token '<'错误。

已尝试的解决步骤

  • 确认Babel和Jest配置正确
  • 检查文件扩展名
  • 清除Jest缓存
  • 启用详细调试模式运行Jest

解决方案

1. 修复Jest配置的完整性

当前jest.config.js存在注释导致的配置缺失,补充关键配置项:

module.exports = {
  roots: ["<rootDir>"],
  transform: {
    "^.+\\.(ts|tsx)$": "ts-jest"
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'json', 'node'],
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
  collectCoverage: true,
  clearMocks: true,
  coverageDirectory: "coverage",
  testEnvironment: "jsdom", // 明确指定React组件测试环境
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"] // 确保全局测试配置加载
};

2. 让ts-jest复用Babel配置

修改jest.config.js,配置ts-jest使用项目的Babel预设处理JSX:

module.exports = {
  // ...其他配置
  transform: {
    "^.+\\.(ts|tsx)$": [
      "ts-jest",
      {
        babelConfig: true,
        tsconfig: "tsconfig.json"
      }
    ]
  },
  // ...其他配置
};

3. 调整TypeScript的JSX编译选项

在tsconfig.json中,将jsx选项改为适配React 17+自动转换的react-jsx:

{
  "compilerOptions": {
    // ...其他配置
    "jsx": "react-jsx"
  }
}

4. 处理第三方包的JSX转换(可选)

如果有第三方包包含未编译的JSX,在jest.config.js中添加忽略规则:

module.exports = {
  // ...其他配置
  transformIgnorePatterns: ["/node_modules/(?!(需要转换的包名))/"]
};

5. 重置依赖与缓存

执行以下命令确保依赖和缓存无问题:

rm -rf node_modules package-lock.json
npm install
npx jest --clearCache

验证

修改配置后,重新运行npx jest --verbose,确认JSX文件能被正确解析,错误不再出现。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:45:54