npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vite-plugin-cus-svg-icon

v0.1.0

Published

A lightweight Vite plugin for generating CSS icons from local SVG files only.

Readme

vite-plugin-svg-icon

一个轻量的 Vite 插件,只处理本地 SVG 图标,并尽量对齐 UnoCSS preset-icons 的使用方式与输出风格。

特性

  • 仅处理本地 SVG,不依赖 UnoCSS
  • 支持 UnoCSS 风格的 prefixcollectionsFileSystemIconLoaderaddCurrentFill
  • 内部已集成 @iconify/utils,无需在业务项目中额外单独安装和导入
  • 默认类名前缀为 i-,支持自定义和多前缀
  • 支持 safelist
  • 支持 extraProperties
  • 支持 scaleunit
  • 支持 mode: 'mask' | 'bg' | 'auto'
  • 支持 SVG 大小阈值控制,默认超过 10KB 不注入 CSS,并输出警告
  • 开发环境按 Vite 已加载模块增量扫描
  • 构建阶段按配置范围全量扫描源码文本,不做 AST 解析

安装

npm install vite-plugin-svg-icon

使用方式

import { defineConfig } from "vite";
import { svgIconPlugin } from "vite-plugin-svg-icon";

export default defineConfig({
  plugins: [
    svgIconPlugin({
      // 必填:定义本地图标集合
      collections: {
        // 简洁写法:仅配置 path 即可
        svg: {
          path: "src/assets/icons",
        },
        // 目录级 safelist,适合动态拼接类名的目录
        svgDy: {
          path: "src/assets/icons-dynamic",
          safelist: true,
        },
      },
    }),
  ],
});

在应用入口引入虚拟样式:

import "virtual:svg-icon.css";

然后在模板或字符串中直接使用类名:

<span class="i-svg:home"></span>
<span class="i-svg:user-add"></span>
<span class="i-svgDy:logo"></span>
<span class="i-svgDy:rainbow"></span>
<span class="i-svgDy:rainbow?mask"></span>

如果图标目录下存在 home.svguser/add.svg,就会分别生成对应的 CSS。

本地 Collections

推荐简洁的 collection 对象写法:

import { svgIconPlugin } from "vite-plugin-svg-icon";

svgIconPlugin({
  collections: {
    svg: {
      path: "src/assets/icons",
    },
    svgDy: {
      path: "src/assets/icons-dynamic",
      safelist: true,
    },
  },
});
  • path:本地图标目录
  • transform / fn:可选 SVG 处理函数
  • autoFillCurrentColor:默认 true,会自动在根 <svg> 上补 fill="currentColor",若已有 fill 则保持不变
  • safelist: true:自动保留该目录下所有图标,适合动态图标目录

也支持与 UnoCSS 接近的写法:

import {
  FileSystemIconLoader,
  addCurrentFill,
  svgIconPlugin,
} from "vite-plugin-svg-icon";

svgIconPlugin({
  collections: {
    svg: FileSystemIconLoader("src/assets/icons", addCurrentFill),
    svgDy: FileSystemIconLoader("src/assets/icons-dynamic", addCurrentFill),
  },
});
  • FileSystemIconLoader(dir, transform?):从本地目录懒加载 SVG
  • addCurrentFill(svg):给未声明 fill 的根 <svg> 注入 fill="currentColor",适合单色图标
  • 目录中的 user/add.svg 会映射为 user-add

Demo

仓库根目录提供了一个基于最新 create-vite 生成的 demo 项目,用于真实验证插件行为:

cd demo
npm install
npm run dev

如果你希望直接在仓库根目录执行完整验证,可以运行:

npm run verify

这个命令会自动完成:

  • 插件源码类型检查
  • 插件单元测试
  • 插件构建
  • demo 构建验证
  • demo 开发服务器启动与虚拟 CSS 内容校验
  • 超过 10KB 的 SVG 警告校验

配置项

interface SvgIconPluginOptions {
  collections: Record<string, IconCollection>; // 必填:图标集合定义
  prefix?: string | string[]; // 类名前缀,默认 'i-'
  virtualModuleId?: string; // 虚拟 CSS 模块 ID,默认 'virtual:svg-icon.css'
  scale?: number; // 图标尺寸缩放,默认 1
  unit?: string; // 尺寸单位,默认 'em'
  mode?: "mask" | "bg" | "auto"; // 默认渲染模式,默认 'auto'
  maxSvgSize?: number; // SVG 大小上限(字节),默认 10 * 1024
  contentInclude?: string[]; // 构建期扫描包含范围(glob)
  contentExclude?: string[]; // 构建期扫描排除范围(glob)
  safelist?: string[]; // 顶层保留类名(仍然有效)
  extraProperties?: Record<string, string>; // 追加到所有图标规则的公共 CSS
}

其中 collections 支持三种形式:

collections: {
  svg: FileSystemIconLoader('src/icons', addCurrentFill),
  svgDy: {
    path: 'src/icons-dynamic',
    safelist: true,
  },
  inline: {
    home: '<svg viewBox="0 0 24 24"><path fill="currentColor" d="..." /></svg>',
  },
}

scale

  • 类型:number
  • 默认值:1
  • 含义:按当前字体大小 1em 缩放图标
  • 输出方式:直接作用于生成 CSS 的 widthheight,不会额外引入尺寸变量

mode

  • mask:单色图标,使用 mask / -webkit-mask
  • bg:背景图模式,保留 SVG 原始颜色
  • auto:默认值;检测到多色、渐变、pattern、image 等复杂着色时自动退化为背景图模式

extraProperties

与 UnoCSS 一样,可以给所有图标附加公共 CSS 属性,例如:

extraProperties: {
  display: 'inline-block',
  'vertical-align': 'middle',
}

扫描策略

  • 开发环境:在 transform / transformIndexHtml 中扫描当前被 Vite 处理的源码文本,只更新受影响文件的图标集合
  • 生产构建:在虚拟 CSS 模块加载时,对 contentInclude 范围进行并发全量扫描
  • 提取方式:直接把源码当纯文本处理,通过前缀和 collection 解析候选类名,不解析 AST
  • 兼容类似 hover:i-svg:homedark:i-svgDy:bell?bg 的变体写法
  • safelist: true 的文件系统 collection,插件会直接基于目录索引生成保留项,不需要用户手写 readdirSync()
  • 开发环境会监听文件系统 collection 目录中的 SVG 新增、删除与修改,并自动刷新虚拟 CSS

性能设计

  • 增量扫描:开发环境只处理当前被 Vite 触达或变更的源码文件,不在启动时扫描整个项目
  • 轻量指纹:源码变更判断使用内容指纹而不是热路径上的 fs.stat(),这不仅在超大项目里有意义,在中小项目的高频 HMR 场景下同样能减少系统调用
  • 快速失败:源码文本在进入正则提取前,会先检查是否包含任一图标前缀,避免大量无关文件进入完整扫描
  • 并发去重:文件系统 collection 使用 refreshPromise 合并并发刷新;单个图标加载也会做 in-flight 去重,避免重复读取同一个 SVG
  • 原子替换:collection 刷新时先构建新索引,再一次性替换旧索引,避免并发读取时看到 clear() 后的中间态
  • 增量 usage 索引:源码图标使用关系按文件差量维护,虚拟 CSS 重建时直接消费当前活跃 usage,而不是每次重新合并全部扫描结果

生成样式

生成结果参考 UnoCSS 的图标输出结构:

.i-svg\:home {
  --svg-c-icon: url("data:image/svg+xml;utf8,...");
}

.i-svg\:home {
  -webkit-mask: var(--svg-c-icon) no-repeat;
  mask: var(--svg-c-icon) no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  background-color: currentColor;
  color: inherit;
  width: 1em;
  height: 1em;
}

限制

  • 当前只处理本地 collections,不处理第三方图标集下载
  • 嵌套目录会被展开为连字符,例如 user/add.svg -> i-svg:user-add
  • auto 模式采用启发式判断多色 SVG,极少数边缘 SVG 仍建议手动使用 ?mask / ?bg