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

Jest加载SVG失败致React组件类型无效问题求助

问题描述

在React+TypeScript项目中运行Jest测试时出现警告:

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

经排查问题源于Jest无法加载SVG文件,已安装jest-transformer-svg模块并配置Jest规则,但错误仍未消除。

错误详情

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `TagInput`.
    at TagInput (/Users/newin/Desktop/homeCoding/deopjibhoeui/src/components/Input/TagInput.tsx:14:3)
  34 |                 onClick={() => removeTags(index)}
  35 |               >
> 36 |                 <RemoveIcon />
     |                 ^
  37 |               </span>
  38 |             </li>
  39 |           ))}

涉及代码

TagInput组件代码

import React from 'react';
import styles from './TagInput.css';
import { ReactComponent as RemoveIcon } from '../../assets/svg/RemoveIcon.svg';
import { InputTag } from '../../core/hooks/types/useTagInput';

export interface TagInputProps {
  tags: InputTag[];
  addTags: (event: React.KeyboardEvent<HTMLInputElement>) => void;
  removeTags: (index: number) => void;
  placeholder?: string;
}

const TagInput = ({
  tags,
  addTags,
  removeTags,
  placeholder
}: TagInputProps) => {
  return (
    <div className={styles}>
      <div className="tags-input">
        <input
          className="tags-input-field"
          type="text"
          onKeyUp={(event) => (event.key === 'Enter' ? addTags(event) : null)}
          placeholder={placeholder}
        />
        <ul id="tags">
          {tags.map((tag, index) => (
            <li key={index} className="tag">
              <span className="tag-title">{tag}</span>
              <span
                className="tag-close-icon"
                onClick={() => removeTags(index)}
              >
                <RemoveIcon />
              </span>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
};

export default TagInput;

Jest配置(jest-config.json)

{
  "preset": "ts-jest",
  "testEnvironment": "jsdom",
  "setupFilesAfterEnv": ["<rootDir>/src/setupTests.ts"],
  "moduleNameMapper": {
    "^.+\\.svg$": "jest-transformer-svg"
  },
  "transform": {
    "^.+\\.svg$": "jest-transformer-svg",
    "^.+\\.(ts|tsx)?$": "ts-jest",
    "^.+\\.(js|jsx)$": "babel-jest",
    "^.+\\.css$": ["jest-transform-css", { "modules": true }]
  }
}

package.json中的devDependencies

"devDependencies": {
    "@babel/core": "^7.24.9",
    "@babel/preset-env": "^7.25.3",
    "@babel/preset-typescript": "^7.24.7",
    "babel-jest": "27.5.1",
    "jest": "27.5.1",
    "jest-environment-jsdom": "27.5.1",
    "jest-svg-transformer": "^1.0.0",
    "jest-transform-css": "^6.0.1",
    "jest-transformer-svg": "^2.0.2",
    "ts-jest": "^27.1.4"
}

执行yarn install后运行yarn test即可触发错误。


解决方法

问题核心是jest-transformer-svg默认仅支持SVG的默认导入,无法匹配你代码中{ ReactComponent as RemoveIcon }的命名导入方式,导致Jest解析后拿到undefined。

方案1:自定义SVG Mock文件(推荐)

  1. 在项目根目录创建__mocks__/svgMock.tsx文件,内容如下:
import React from 'react';

const MockSVG = ({ children, ...props }: React.SVGProps<SVGSVGElement>) => (
  <svg {...props}>{children}</svg>
);

// 支持命名导出的ReactComponent
export const ReactComponent = MockSVG;
// 同时支持默认导入
export default MockSVG;
  1. 修改Jest配置(jest-config.json):
    • 将moduleNameMapper中的SVG映射指向自定义mock文件
    • 移除transform中针对SVG的配置项
      修改后的配置片段:
"moduleNameMapper": {
  "^.+\\.svg$": "<rootDir>/__mocks__/svgMock.tsx"
},
"transform": {
  "^.+\\.(ts|tsx)?$": "ts-jest",
  "^.+\\.(js|jsx)$": "babel-jest",
  "^.+\\.css$": ["jest-transform-css", { "modules": true }]
}

方案2:调整SVG导入方式

如果不想新增mock文件,可以把代码中的SVG导入改为默认导入:

// 替换原命名导入
import RemoveIcon from '../../assets/svg/RemoveIcon.svg';

这种方式无需修改Jest配置,但需要调整所有使用SVG组件的导入代码,适合小型项目。

方案3:升级Jest依赖(可选)

当前使用的Jest 27.x版本较老旧,升级到29.x版本配合最新的jest-transformer-svg可能解决兼容性问题,但升级可能需要同步调整其他配置(如babel、ts-jest版本),需谨慎操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:05:55