运行Vitest测试时出现「ReferenceError: React is not defined」,求排查
Vitest测试报错排查:ReferenceError: React is not defined
问题现象
执行Vitest测试时,src/tests/home.test.ts中的「Home page」测试用例抛出ReferenceError: React is not defined错误,报错指向src/app/page.tsx的JSX代码行。
测试报错信息
✓ src/tests/unit.test.ts (1) ❯ src/tests/home.test.ts (1) × Home page ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ FAIL src/tests/home.test.ts > Home page ReferenceError: React is not defined ❯ Home src/app/page.tsx:2:3 1| export default function Home() { 2| return <div>Home of Next</div>; | ^ 3| } 4| ❯ src/tests/home.test.ts:27:10
相关文件代码
src/app/page.tsx
export default function Home() { return <div>Home of Next</div>; }
src/tests/home.test.tsx
import { render, screen } from "@testing-library/react"; import { vi, test } from "vitest"; import Home from "../app/page"; vi.mock("@frontegg/nextjs", () => { const mockedFunctions = { auth: () => new Promise((resolve) => resolve({ userId: "1" })), useUser: () => ({ isSignedIn: true, user: { id: "1", fullName: "Fake Name", }, }), }; return mockedFunctions; }); vi.mock("next/font/google", () => { return { Inter: () => ({ className: "inter" }), }; }); test("Home page", () => { render(Home()); expect(screen.getByText("Home of Coach-Next")).toBeTruthy(); });
vitest.config.ts
import { defineConfig } from "vite"; export default defineConfig({ test: { exclude: [ "**/node_modules/**", "**/dist/**", "**/.{git,cache,output,temp}/**", "**/{vite,vitest}.config.*", ".*/**", ], }, });
vite.config.ts
import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react-swc"; export default defineConfig({ plugins: [react()], test: { include: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"], globals: true, environment: "jsdom", setupFiles: "setupTests", mockReset: true, }, });
tsconfig.json
{ "compilerOptions": { "target": "ES2017", "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", "incremental": true, "plugins": [ { "name": "next" } ], "paths": { "@/*": ["./src/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"], "references": [{ "path": "./tsconfig.node.json" }] }
tsconfig.node.json
{ "compilerOptions": { "composite": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] }
报错原因分析
- 重复配置导致React插件未加载:项目同时存在
vitest.config.ts和vite.config.ts,Vitest会优先读取vitest.config.ts,但该配置中没有引入@vitejs/plugin-react-swc插件。JSX代码需要被编译为React.createElement调用,没有插件的话测试环境无法自动注入React引用,从而抛出React is not defined错误。 - 测试组件调用方式错误:测试中使用
render(Home())直接调用组件函数,正确的做法应该是传递JSX元素render(<Home />),不过这不是引发当前报错的核心原因,但会导致后续测试断言异常。 - 断言文本不匹配:组件返回的文本是
Home of Next,但测试断言中查找的是Home of Coach-Next,即使解决React引用问题,测试依然会失败。
解决方案
- 删除多余的Vitest配置文件:删除
vitest.config.ts,让Vitest使用vite.config.ts中的配置,确保@vitejs/plugin-react-swc插件在测试环境中生效,自动处理JSX编译并注入React引用。 - 修正测试中的组件渲染方式:将测试代码中的
render(Home())修改为render(<Home />)。 - 修正断言文本:将断言中的
"Home of Coach-Next"改为"Home of Next",保证与组件输出一致。
修改后的测试代码片段:
test("Home page", () => { render(<Home />); expect(screen.getByText("Home of Next")).toBeTruthy(); });
- 验证配置生效:重新运行测试,确认React引用错误消失,测试用例正常通过。
内容的提问来源于stack exchange,提问作者Sandra Schlichting
相关产品推荐
相关产品推荐

