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

Next.js配置Jest运行测试时出现import语法报错问题

问题描述

近几日排查问题时遇到一类常见报错,对应错误信息如下:

Jest encountered an unexpected token
/__tests__/index.test.js:16
    import React from "react";
    ^^^^^^
SyntaxError: Cannot use import statement outside a module

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

报错定位到的import React from "react";语句疑似Next.js自动追加到index.test.js文件末尾,直接触发了「无法在模块外使用import语句」的语法错误。已查阅相关技术帖子和Next.js、Jest官方文档,当前项目配置如下。


现有项目配置

package.json

{
  "name": "some-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest --watch"
  },
  "dependencies": {
    "next": "12.1.6",
    "react": "18.1.0",
    "react-dom": "18.1.0"
  },
  "devDependencies": {
    "@babel/plugin-syntax-jsx": "^7.17.12",
    "@babel/preset-env": "^7.18.2",
    "@babel/preset-react": "^7.17.12",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@types/jest": "^28.1.3",
    "@types/node-fetch": "^2.6.2",
    "babel-jest": "^28.1.1",
    "eslint": "8.16.0",
    "eslint-config-next": "12.1.6",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^28.1.1",
    "jest-environment-jsdom": "^28.1.1",
    "node-fetch": "^3.2.6",
    "ts-jest": "^28.0.5",
    "typescript": "^4.7.4"
  },
  "description": "This is a Next.js project bootstrapped with create-next-app.",
  "main": "jest.config.js",
  "repository": {
    "type": "git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {}
}

测试文件 /__tests__/index.test.js

import { render, screen } from '@testing-library/react'
import Home from '../pages/index'
import '@testing-library/jest-dom'
import React from "react";

describe('Home', () => {
  it('renders a h', () => {
    render(<Home />)

    const link = screen.getByRole('link', {
      name: "Library",
    })

    expect(link).toHaveAttribute('href', '/storage-area')
  })
});

jest.config.js

module.exports = {
  collectCoverage: true,
  // node 14.x版本下v8覆盖率提供工具备较好速度与可用的报告效果
  coverageProvider: 'v8',
  collectCoverageFrom: [
    '**/*.{js,jsx,ts,tsx}',
    '!**/*.d.ts',
    '!**/node_modules/**',
    '!<rootDir>/out/**',
    '!<rootDir>/.next/**',
    '!<rootDir>/*.config.js',
    '!<rootDir>/coverage/**',
  ],
  moduleNameMapper: {
    // 处理CSS Modules导入
    '^.+\.module\.(css|sass|scss)$': 'identity-obj-proxy',

    // 处理普通CSS导入
    '^.+\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',

    // 处理图片等静态资源导入
    '^.+\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$/i': `<rootDir>/__mocks__/fileMock.js`,

    // 处理路径别名
    '^@/components/(.*)$': '<rootDir>/components/$1',
  },
  // 测试运行前的初始化配置
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
  testEnvironment: 'jsdom',
  transform: {
    // 使用babel-jest配合预设转译测试文件
    '^.+\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel', '@babel/preset-react',"@babel/preset-env" ]}],
  },
  transformIgnorePatterns: [
    '/node_modules/',
    '^.+\.module\.(css|sass|scss)$',
  ],
}

排查解决思路

按优先级依次尝试以下方案:

  • 修正babel配置冲突
    手动配置@babel/preset-env和@babel/preset-react会和Next.js内置的next/babel预设冲突,导致转译失效。把jest.config.js里transform项的preset配置改成仅保留next/babel即可,修改后配置为:

    transform: {
      '^.+\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
    },
    

    Next.js的babel预设已经内置了react、env相关转译规则,不需要额外叠加其他预设。

  • 调整测试文件存放位置
    不要把测试文件放在根目录的__tests__文件夹下,Next.js 12.x会默认对根目录下的文件做特殊处理,自动注入React import语句。把测试文件移到对应页面/组件的同级目录,命名为index.test.js和页面文件同存,或者新建src/__tests__目录存放测试用例,避开Next.js的根目录文件扫描规则。

  • 修正transformIgnorePatterns配置
    当前配置会跳过所有node_modules下的文件转译,部分ESM格式的依赖(比如安装的node-fetch v3是纯ESM包)不会被babel转译,会触发同类import报错。把配置修改为:

    transformIgnorePatterns: [
      '/node_modules/(?!(next|react|react-dom|@testing-library)/)',
      '^.+\.module\.(css|sass|scss)$',
    ],
    

    强制babel转译node_modules下Next.js、React、testing-library相关的ESM格式代码。

  • 清理缓存重试
    执行以下命令清除Jest和Next.js的缓存后重新运行测试:

    rm -rf node_modules/.cache
    npx jest --clearCache
    

    旧的转译缓存经常会导致配置修改后不生效的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:09:21