Preact + Vite动态导入SVG组件失败,报错无效标签名
解决Preact+Vite中按需加载SVG组件渲染报错的问题
你遇到的核心问题是Vite默认将SVG作为资源URL导入,而非可渲染的Preact组件,所以直接把导入结果当组件用会报标签名无效的错误。以下是具体解决步骤:
1. 安装并配置SVG转组件的Vite插件
Vite本身不支持将SVG直接转为组件,需要借助vite-plugin-svgr插件实现这个转换:
首先安装依赖:
npm install vite-plugin-svgr --save-dev
然后修改vite.config.js,添加插件配置:
import { defineConfig } from 'vite'; import preact from '@preact/preset-vite'; import svgr from 'vite-plugin-svgr'; export default defineConfig({ plugins: [ preact(), svgr({ // 可选:限定只处理指定目录下的SVG图标,避免全局影响 include: 'src/assets/icons/**/*.svg', }), ], });
2. 调整动态导入逻辑与Icon组件
现在需要修改动态导入的代码,通过添加?react后缀告诉Vite把当前SVG转成Preact组件:
动态导入Hook(useDynamicIcon)
import { useState, useEffect } from 'preact/hooks'; export function useDynamicIcon(name) { const [IconComponent, setIconComponent] = useState(null); useEffect(() => { const loadIcon = async () => { try { // 关键:添加?react后缀触发svgr的组件转换 const module = await import(`../assets/icons/${name}.svg?react`); // 取默认导出的组件 setIconComponent(module.default); } catch (err) { console.error(`加载图标${name}失败:`, err); } }; loadIcon(); }, [name]); return IconComponent; }
Icon组件
import { useDynamicIcon } from './useDynamicIcon'; export function Icon({ name, ...props }) { const IconComponent = useDynamicIcon(name); // 加载完成前可以返回占位符(比如一个小加载动画)或者null if (!IconComponent) return null; // 将props(比如class、width、height)传递给SVG组件 return <IconComponent {...props} />; }
为什么用img的src能正常显示?
因为Vite默认导入SVG时返回的是该资源的URL路径,这个路径可以直接作为img标签的src属性值使用,但它本质是字符串,不是Preact组件,所以不能直接当作标签渲染。
内容的提问来源于stack exchange,提问作者Walter Monecke
相关产品推荐
相关产品推荐

