已安装Babel插件仍报错:Jest无法解析JSX提示‘支持未启用’的问题排查求助
咱们先拆解你遇到的核心问题:首次用Jest测试React的App组件时,触发了SyntaxError: Support for the experimental syntax 'jsx' isn't currently enabled错误,即便安装了@babel/plugin-transform-react-jsx、配置了babel.config.json,问题依然存在。下面是具体的分析和解决步骤:
一、核心原因:Babel配置缺少React专属预设
你的babel.config.json仅配置了@babel/preset-env,但遗漏了处理React JSX的@babel/preset-react——这个预设已经内置了@babel/plugin-transform-react-jsx的功能,单独安装插件反而可能和预设冲突,导致转译失效。
修正Babel配置
更新项目根目录的babel.config.json,加入React预设:
{ "presets": [ ["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/preset-react" ] }
二、清理冲突依赖,安装正确依赖
先卸载单独安装的@babel/plugin-transform-react-jsx(避免和预设冲突),再安装必要的开发依赖:
yarn remove @babel/plugin-transform-react-jsx yarn add -D @babel/preset-react @babel/preset-env babel-jest
三、修正测试代码的语法与逻辑错误
你的测试代码存在两处明显问题,也可能干扰测试执行:
props对象末尾多了一个多余逗号,属于语法错误:// 错误写法 var props = { now: new Date(), // Current date and time } // 修正后 const props = { now: new Date() }; // 去掉多余逗号,用const代替var更规范expect(App).toHaveBeenCalledWith(props)断言逻辑错误:App是React组件,不是mock函数,不能直接用toHaveBeenCalledWith。如果要验证组件是否接收了正确props,推荐用@testing-library/react来渲染并断言,或者用jest.spyOn跟踪组件调用。
修正后的测试代码示例(使用@testing-library/react)
先安装测试库:
yarn add -D @testing-library/react
再修改测试代码:
// External deps import React from "react"; import { render, screen } from "@testing-library/react"; // Project-specific deps import App from "../../App"; describe("Pass props properly", () => { test("Check each props mapping.", () => { const testDate = new Date(); render(<App now={testDate} />); // 这里根据App组件实际渲染的内容断言,比如组件显示了日期就检查对应文本 // 示例:expect(screen.getByText(testDate.toLocaleString())).toBeInTheDocument(); // 如果要直接验证组件接收的props,类组件可以用jest.spyOn(函数组件需配合React.memo) const spy = jest.spyOn(App.prototype, 'render'); render(<App now={testDate} />); expect(spy).toHaveBeenCalledWith(expect.objectContaining({ now: testDate })); spy.mockRestore(); }); });
四、验证Babel是否正常工作的方法
创建一个简单的测试文件test-jsx.js:
import React from 'react'; const TestComponent = () => <div>Hello</div>;
用Babel CLI转译它:
npx babel test-jsx.js --out-file test-jsx-transpiled.js
打开转译后的文件,如果JSX被转换成了React.createElement的形式,说明Babel配置已经生效。
五、检查Jest配置是否正确
确保你的Jest配置(比如jest.config.js)没有禁用Babel转换,默认情况下Jest会用babel-jest转译文件,但如果手动配置了transform选项,需确保包含.jsx文件的转译规则:
module.exports = { transform: { '^.+\\.(js|jsx)$': 'babel-jest', }, };
内容的提问来源于stack exchange,提问作者Jackalakalaka

