V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
theprimone
V2EX  ›  前端开发

尝试开发了一个支持多打包器的 SVG 雪碧图插件

  •  
  •   theprimone ·
    yunsii · 2023-07-23 13:48:18 +08:00 · 953 次点击
    这是一个创建于 518 天前的主题,其中的信息可能已经有所发展或是发生改变。

    尝试在站内搜了一下 SVG 雪碧图的相关话题,有很多说法,比如直接导入 SVG 使用不做任何优化,还有使用 HTTP/2 协议部署服务。我的看法是如果项目没有 SEO 的需求的话,直接导入没啥毛病,不过就是可能会出现同样的一个 SVG 在各处都得渲染全部节点,DOM 节点增长速度可能有点快。另外使用 HTTP/2 通过 img 标签引入外部资源的方式不能改变颜色,这也不够灵活。

    因此,个人感觉雪碧图还是个很好的方案,但是一直没找到一个好用的方式,因为现在主要的开发时间都在 Next.js 上,只能找找 webpack 插件,多次尝试最后选择了 svg-sprite-loader,但是很久没维护了,使用体验欠佳。svg-sprite 看起来很强大,但是没有提供插件集成,对于想伸手即用的我来说,还是麻烦了些。

    一上头 😦 打算手搓一个 SVG 雪碧图插件,刚好之前就了解过 unplugin,但是一直没实操过,直接找个模板开始折腾。经过两天的折腾,目前初步的功能是有了,学习了 svg-sprite 之后才知道 SVG 雪碧图有很多种类型,目前支持了个人觉得比较合适两个类型:symbolstack,其中 symbol 的使用时最简单的,开发上直接引入即可,目前的主要功能有:

    • 可配置 content 指定扫描的相关 SVG 文件夹,类似 tailwind css 的配置
    • ~svg-sprite/symbol/**/* 前缀使用 SVG ,需要配置 itemGenerator
    • ~svg-sprite/symbol 引入 SVG 雪碧图本体,需要配置 spriteGenerator

    因为是框架无关的,所以需要配置相关的生成函数,目前测试 Vite/Next.js/Nuxt 都没啥问题。这里需要补充几点:

    • 如果将雪碧图通过外链引入,有些 SVG 特殊的功能是不会生效的,比如线性渐变,所以需要通过 HTML 内嵌的方式
    • 自行实现的 spriteGenerator 对应的组件内可实现内嵌的功能
    • 另外目前是通过前缀处理的 SVG 雪碧图,看起来插件好像不能像 loader 一样使用 resourceQuery ,如果可以的话还是通过查询参数的引入方式更好,用户使用上方便引入时做路径推导

    stack 因为是 CSS 中使用的,插件上好像不太好处理,比如 vite 对于引入 CSS 文件根本不走插件 Hooks,所以暂时只是基于 svg-sprite 做了生成逻辑,没有更多的定制功能了,可以借助 svg-sprite 提供的 example.html 查阅选择。

    活儿整完了,欢迎各位大佬试用反馈 😄 当然,这只是起了个步,后续还得继续优化,比如支持 SVGO 配置。最后附上链接:

    https://github.com/yunsii/unplugin-svg-sprite

    2 条回复    2023-07-23 16:03:01 +08:00
    churchill
        1
    churchill  
       2023-07-23 14:56:57 +08:00
    可口可乐可真强啊,在大洋彼岸将一个常见的英文单词变成了品牌名
    theprimone
        2
    theprimone  
    OP
       2023-07-23 16:03:01 +08:00
    @churchill 跑偏了?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2629 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 07:15 · PVG 15:15 · LAX 23:15 · JFK 02:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.