vite的svg插件,svgo优化svg代码

该文章介绍了一个使用Vite插件创建SVG精灵图的过程,通过SVGO库进行代码优化,合并多个SVG图标为一个单独的精灵。插件包括读取SVG文件,使用svgstore处理,并在文档加载完成后注入到DOM中,同时应用样式使其不可见。
摘要由CSDN通过智能技术生成

我制作了一款svg精灵图的vite插件,它通过SVGO库对其代码进行优化,将多个svg合并在一个单独的svg精灵中

预下载
npm i svgo//用来优化svg
npm i svgstore//用来制作svg sprites

1、导入pathfsstoreoptimize模块。

import path from 'path'
import fs from 'fs'
import store from 'svgstore'
import { optimize } from 'svgo'

2、定义一个名为svgstore的函数,它接受一个选项对象作为参数。

export const svgstore = (options = {}) => {

}

3、在选项对象中设置输入文件夹的路径,如果没有提供,则默认为src/assets/icons

const inputFolder = options.inputFolder || 'src/assets/icons'; //存放svg的路径

4、返回一个Rollup插件对象,该插件对象具有nameresolveIdload属性。

return {
  name: 'svgstore',
  resolveId(id) {

  },
  load(id) {

  }

5、在resolveId方法中,如果请求的ID为**@svgstore**,则返回svg_bundle.js的ID。

if (id === '@svgstore') {
  return 'svg_bundle.js'
}
//这也就是为了适配编译器,在main.ts中引入(import "@svgstore")

6、在load方法中,如果请求的ID为svg_bundle.js,则执行以下步骤:

  • 创建一个空的store对象,用于保存SVG图标代码。
if (id === 'svg_bundle.js') {
        const sprites = store(options);  
}
  • 获取输入文件夹中的所有文件,并为每个文件创建一个SVG ID,然后将SVG代码添加到store对象中。
 const iconsDir = path.resolve(inputFolder);
    for (const file of fs.readdirSync(iconsDir)) {
      const filepath = path.join(iconsDir, file);
      //单独的svgid
      const svgid = path.parse(file).name
      //code 就是svg内的代码
      let code = fs.readFileSync(filepath, { encoding: 'utf-8' });
      sprites.add(svgid, code)
    }
  • 使用optimize函数对store对象中的所有SVG代码进行优化,并生成优化后的SVG精灵代码。
  const { data: code } = optimize(sprites.toString({ inline: options.inline }), {
    plugins: [
      'cleanupAttrs', 'removeDoctype', 'removeComments', 'removeTitle', 'removeDesc',
      'removeEmptyAttrs',
      { name: "removeAttrs", params: { attrs: "(data-name|data-xxx)" } }//svg代码里有许多无用的属性
    ]
  })
  • 将生成的JavaScript代码作为字符串返回,该字符串将SVG精灵代码注入到文档中,并添加一些样式,使SVG元素不可见。
return `const div = document.createElement('div')
div.innerHTML = \`${code}\`
const svg = div.getElementsByTagName('svg')[0]
if (svg) {
  svg.style.position = 'absolute'
  svg.style.width = 0
  svg.style.height = 0
  svg.style.overflow = 'hidden'
  svg.setAttribute("aria-hidden", "true")
}
// listen dom ready event
document.addEventListener('DOMContentLoaded', () => {
  if (document.body.firstChild) {
    document.body.insertBefore(div, document.body.firstChild)
  } else {
    document.body.appendChild(div)
  }
})`
//将加载svg通过设置width、height为0、overflow:hidden、绝对定位来实现隐藏

全部代码

import path from 'path'
import fs from 'fs'
import store from 'svgstore'
import { optimize } from 'svgo'

export const svgstore = (options = {}) => {
  const inputFolder = options.inputFolder || 'src/assets/icons'; //存放svg的路径
  return {
    name: 'svgstore',
    resolveId(id) {
      if (id === '@svgstore') {
        return 'svg_bundle.js'
      }
    },
    load(id) {
      if (id === 'svg_bundle.js') {
        const sprites = store(options);
        const iconsDir = path.resolve(inputFolder);
        for (const file of fs.readdirSync(iconsDir)) {
          const filepath = path.join(iconsDir, file);
          const svgid = path.parse(file).name
          let code = fs.readFileSync(filepath, { encoding: 'utf-8' });
          sprites.add(svgid, code)
        }
        const { data: code } = optimize(sprites.toString({ inline: options.inline }), {
          plugins: [
            'cleanupAttrs', 'removeDoctype', 'removeComments', 'removeTitle', 'removeDesc',
            'removeEmptyAttrs',
            { name: "removeAttrs", params: { attrs: "(data-name|data-xxx)" } }
          ]
        })
        return `const div = document.createElement('div')
div.innerHTML = \`${code}\`
const svg = div.getElementsByTagName('svg')[0]
if (svg) {
  svg.style.position = 'absolute'
  svg.style.width = 0
  svg.style.height = 0
  svg.style.overflow = 'hidden'
  svg.setAttribute("aria-hidden", "true")
}
// listen dom ready event
document.addEventListener('DOMContentLoaded', () => {
  if (document.body.firstChild) {
    document.body.insertBefore(div, document.body.firstChild)
  } else {
    document.body.appendChild(div)
  }
})`
      }
    }
  }
}

还需要的配置

1、main.ts文件中
import "@svgstore"
2、vite.config.ts文件中
import { svgstore } from './src/vite_plugins/svgstore'

plugins: [
  vue(), svgstore()
]

3、组件中使用

<svg>
  <use xlinhref="#文件名"></use> 
</svg>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值