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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:42:42