svg 文件自动化转组件
这是介于之前发布的《 使用 svg 后如何改变颜色》 的第四种解决方案。
由于方案三使用的是 CSS 解决,总的来说在部分场景下会不太方便,并且 transform: translate(-1000px);
的值始终不好控制,以至于在某些场景下会导致图片“消失”,就比较诡异。
方案四
避免使用 <img>
标签,而是直接使用脚本自动化解析 svg 文件,通过规律生成一个新的 JSX 组件子集,以此来解决问题。
首先,我们的 svg 文件来自 iconfont ,也以此为例子。
可以看到 svg 文件格式规律如下:
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">/* svg content */</svg>
由此来扫描 svg 文件夹:
const fs = require('fs-extra')
const path = require('path')
const svgs = path.resolve(__dirname, './svgs') // 存放 svg 文件夹
const files = fs.readdirSync(svgs) // svg 下的 svg 文件
那么我们现在可以获得到 svg 文件,接下来我们需要设计一下生成的 JSX 组件子集:
export const svgname = <>/* svg content */</>
我们再来设计一下所需的 svg 组件(以 Vue 为例):
import * as svgMap from './svgs'
export default defineComponent({
props: {
name: {
type: String,
required: true,
},
},
setup(props) {
return () => <svg
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
{ svgMap[props.name] }
</svg>
},
})
到此,我们的 svg 组件已设计完成,那么我们只需要实现脚本,自动扫描 svg 文件夹即可实现我们的组件。
const fs = require('fs-extra')
const path = require('path')
const svgs = path.resolve(__dirname, './svgs') // 存放 svg 文件夹
const newFilePath = path.resolve(__dirname, './svgs.tsx') // JSX 组件子集文件位置
const files = fs.readdirSync(svgs) // svg 下的 svg 文件
const svgContentReg = /<svg([\s\S]*?)>([\s\S]*?)<\/svg>/ // 正则分析 svg 文件内容,可以自行换成其他库,如 magic-string 之类的
const newFileContent = [] // JSX 组件子集内容,如需要避开 eslint ,可设置初始值为 ['/* eslint-disable */']
for (const file of files) {
const filePath = path.resolve(svgs, './', file)
const res = fs.readFileSync(filePath) // 读取 svg 文件内容
const content = res.toString()
const svgContent = content.match(svgContentReg).pop() // 获取 svg 中 svg 标签内的内容
newFileContent.push(`export const ${file.replace(/-/, '').replace('.svg', '')} = <>${svgContent}</>`)
// 文件名的解析这边只做了简单处理,可以根据自己的规范调整文件名到命名的转换, 同理 svg 文件内容
}
fs.writeFileSync(newFilePath, newFileContent.join('\n'))
到此,我们可以快乐的执行自动化脚本,无惧 svg 文件的变更,畅快更新 svg 组件资源,也能更好的改变 svg 的颜色咯~
但是,目前唯一的缺点就是手动执行的自动化脚本,如果有需要可以更抽象化成 webpack vite rollup 插件。
- 本文链接: https://zongzi531.com/2022/11/11/svg%E6%96%87%E4%BB%B6%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BD%AC%E7%BB%84%E4%BB%B6/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!