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

运行单元测试时出现React.jsx: type is invalid错误

解决单元测试中自定义组件库导入的React类型无效警告

问题场景

从自定义维护的Storybook组件库导入Button、Modal等组件时,UI渲染完全正常,但运行基于React Testing Library + Webpack的单元测试时,测试虽能通过,控制台却抛出以下警告:

console.error
    Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

    > 1 | import { Button, Modal } from 'components-library';
        | ^

尝试改用默认导入import Button, Modal from 'components-library';无效,因为组件库未导出默认内容。组件库基于Material UI,其中Button的导出代码如下:

import {
  Button as MuiButton,
  ButtonProps as MuiButtonProps,
} from '@mui/material';

export const Button = ({ children, ...rest }: ButtonProps) => {
  return (
    <MuiButton variant='text'>
      {children}
    </MuiButton>
  );
};

其类型信息为:

(alias) const Button: ({ children, ...rest }: ButtonProps) => react_jsx_runtime.JSX.Element
export Button

核心原因

这类问题基本是测试环境与开发/生产环境的模块解析策略不一致导致的:

  • 测试Webpack配置可能强制将组件库按CommonJS模块解析,而组件库实际输出的是ES模块,导致导入的是整个模块对象而非组件本身
  • 组件库的打包输出格式未适配测试环境的解析规则

解决方案

1. 调整测试Webpack的模块解析规则

在测试环境的Webpack配置中,优先读取组件库的ES模块入口:

module.exports = {
  // ...其他配置
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    mainFields: ['module', 'main'], // 先找module字段对应的ES模块文件
  },
};

这会让Webpack优先加载组件库package.json中module字段指向的ES模块文件,而非main字段的CommonJS文件,避免解析偏差。

2. 确保组件库打包输出双格式

在组件库的package.json中同时声明ES模块和CommonJS入口,让不同环境按需选择:

{
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "types": "dist/index.d.ts"
}

如果用Rollup或Vite打包组件库,配置同时输出两种格式即可。

3. 给组件库添加Webpack别名(临时方案)

如果前两种方法无效,可直接在测试Webpack配置中指定组件库的ES模块路径:

const path = require('path');

module.exports = {
  resolve: {
    alias: {
      'components-library': path.resolve(__dirname, '../path/to/components-library/dist/index.esm.js'),
    },
  },
};

4. 检查测试环境的Babel配置

若用Babel处理测试代码,确保@babel/preset-env不转换ES模块:

{
  "presets": [
    ["@babel/preset-env", { "modules": false }], // 保留ES模块结构,让Webpack处理
    "@babel/preset-react",
    "@babel/preset-typescript"
  ]
}

如果modules设为commonjs,Babel会把ES模块转成CommonJS,可能导致组件导入异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:43:25