如何使用Vitest测试引入SVG作为组件的Next.js应用?
解决Vitest测试Next.js 13应用时SVG组件导入的InvalidCharacterError问题
方案一:正确配置vite-plugin-svgr并添加类型声明
- 确认已安装
vite-plugin-svgr:
npm install vite-plugin-svgr --save-dev # 或 yarn add vite-plugin-svgr --dev # 或 pnpm add vite-plugin-svgr -D
- 修改
vitest.config.ts,明确配置svgr插件的转换选项,对齐Next.js的@svgr/webpack行为:
import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; import tsconfigPaths from "vite-tsconfig-paths"; import svgr from "vite-plugin-svgr"; export default defineConfig({ plugins: [ react(), tsconfigPaths(), svgr({ // 设为true让SVG默认导出为React组件,和@svgr/webpack逻辑一致 exportAsDefault: true, // 可选:添加svgr额外配置,比如将SVG处理为图标 svgrOptions: { icon: true, }, }), ], test: { environment: "jsdom", }, });
- 添加TypeScript类型声明,确保TS能识别SVG组件导入:
在项目根目录或src文件夹下创建svg.d.ts文件:
declare module "*.svg" { import React from "react"; const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>; export default ReactComponent; }
然后在tsconfig.json的include字段中包含这个类型文件:
{ "include": ["src/**/*", "svg.d.ts"] }
方案二:Mock SVG文件跳过解析
如果配置插件仍未生效,可以直接在测试中Mock所有SVG导入,避免实际解析SVG文件:
- 修改
vitest.config.ts,添加全局Mock规则:
import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; import tsconfigPaths from "vite-tsconfig-paths"; export default defineConfig({ plugins: [react(), tsconfigPaths()], test: { environment: "jsdom", // 配置全局SVG Mock mock: { "*.svg": () => ({ default: () => <div>Mocked SVG</div>, }), }, }, });
- 或者通过单独的测试setup文件实现:
创建vitest.setup.ts文件:
import { vi } from "vitest"; import React from "react"; // Mock所有SVG导入为一个简单的React组件 vi.mock(/\.svg$/, () => ({ default: React.memo(() => <span>Mocked SVG</span>), }));
然后在vitest.config.ts中指定这个setup文件:
export default defineConfig({ // ...其他配置 test: { environment: "jsdom", setupFiles: ["./vitest.setup.ts"], }, });
方案三:对齐Next.js与Vite的SVG处理逻辑
确保Next.js中@svgr/webpack的配置和Vite插件的逻辑一致:
- 检查
next.config.js中的SVG配置:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack(config) { config.module.rules.push({ test: /\.svg$/i, // 只处理jsx/tsx文件导入的SVG issuer: /\.[jt]sx?$/, use: ["@svgr/webpack"], }); return config; }, }; module.exports = nextConfig;
- 在
vitest.config.ts的svgr插件中添加相同的匹配规则:
svgr({ include: "**/*.svg", // 仅处理来自jsx/tsx文件的导入 issuer: /\.[jt]sx?$/, })
最后,尝试重启Vitest服务或清除项目缓存(删除node_modules/.cache文件夹),确保配置生效。
内容的提问来源于stack exchange,提问作者Mayank Kumar Chaudhari
相关产品推荐
相关产品推荐

