我正在使用开发环境Vite开发一个React APP。由于 Vite 得到了很好的支持,我添加了几个可以很好地配合它的插件,特别是一个让我有机会创建直接导入特定格式的 *.svg 的组件的插件。它称为
vite-plugin-svgr
,您可以通过以下方式创建一个组件,只需在末尾包含 ?react
:
import Lock from '../assets/icons/lock.svg?react'
一旦我这样做了,我就开始使用 Jest 和testing-library/react 开发一些测试,看起来testing-library/react 中的“渲染”方法不喜欢使用插件创建组件的方式。
基本上它会抛出以下错误: `控制台.错误 警告:React.jsx:类型无效 - 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:对象。
Check the render method of `Widget`.
at repositoryData (/Users/joscormir/Dev/dashboard_project/src/components/Widget.jsx:13:26)
at section
at Dashboard (/Users/joscormir/Dev/dashboard_project/src/components/Dashboard.jsx:9:61)
24 | {repositoryData.organization.login}/{repositoryData.name}
25 | </a>
> 26 | {repositoryData.private ? <Lock /> : <UnLock />}
| ^
27 | </header>
28 |
29 | <div className={styles.widget__body}>`
考虑到
<UnLock />
是按照之前解释的方式创建的组件:
import UnLock from '../assets/icons/unlock.svg?react'
和 Widget.jsx
是包含 <UnLock />
组件的组件。
渲染该组件显然遇到了麻烦。
因为这非常简单,所以我考虑使用一个名为 jest-transformer-svg
的 Jest 插件import React from 'react';
import MySvg from '../images/an-image.svg';
function MyComponent() {
return (
<div>
<MySvg style={{ color: 'blue' }} />
</div>
);
}
然后,由于我的文件的扩展名有点不同,我尝试使用 Jest 转换扩展名
\*.svg?react
以满足上面示例的要求,包括我的jest.config.js\
文件中的以下句子。
'^.+\\.(svg\\?react)$': 'jest-transformer-svg'
但是没有成功。整个测试套件无法工作,因为它说现在找不到带有
*.svg\?react
扩展声明的模块,这意味着 jest-transformer-svg
根据我的理解不太工作
我找到了一种方法来完成这项工作。它就像一个魅力,我发现它阅读了vite-plugin-svgr中的问题。这里的关键点是用
.svg?react
扩展名替换 .svg
。这可以修改我们包含在 vite.config.js
插件调用中的方式。
我们需要按如下方式修改:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import svgr from 'vite-plugin-svgr'
export default defineConfig({
plugins: [react(), svgr({ include: '**/*.svg' })],
})
关键是我们包含 svg 文件的方式,通过此修改,我们可以将导入组件的方式从使用
UnLock from '../assets/icons/unlock.svg?react'
更改为使用 UnLock from '../assets/icons/unlock.svg'
通过此修改,我们现在可以正确使用
jest-transformer-svg
,因为它将正确解释 .svg
文件,包括 jest.config.js
文件中的转换规则,告诉笑话转换器转换具有该扩展名的所有文件 '^.+\\.svg$': 'jest-transformer-svg'
:
module.exports = {
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/tests/setupTests.js'],
testMatch: ['<rootDir>/tests/**/*.(test).(js|jsx)'],
testPathIgnorePatterns: ['<rootDir>/tests/e2e/'],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': [
'@swc/jest',
{
sourceMaps: true,
jsc: {
parser: {
syntax: 'ecmascript',
jsx: true,
},
transform: {
react: {
runtime: 'automatic',
},
},
},
},
],
'^.+\\.svg$': 'jest-transformer-svg',
},
moduleNameMapper: {
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'jest-transform-stub',
},
}
以上是我共享的配置文件,只是为了澄清必须放置转换规则的位置,其他所有内容都可以根据您自己的笑话配置进行更改。