-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvite-plugin-svgmaker.js
More file actions
95 lines (84 loc) · 3.21 KB
/
Copy pathvite-plugin-svgmaker.js
File metadata and controls
95 lines (84 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { optimize } from 'svgo'
import { parseStringPromise } from 'xml2js'
import fs from 'fs'
import { resolve } from 'path'
function escapeRegex(string) {
return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&')
}
const getSvgStats = async (str) => {
const { svg: { $: attrs } } = await parseStringPromise(str)
let { width = null, height = null, viewBox = null, fill = null } = attrs
if (!viewBox && (width && height))
viewBox = `0 0 ${width} ${height}`
return { width, height, viewBox, fill }
}
export async function generateSVG(svgFolder, filename, resultFolder, withindex = true) {
const filename_without_ext = filename.replace('.svg', '')
console.log(`generating ${resultFolder}${filename.replace('.svg', '.js')}`)
let name = filename.replace('_fixcolor', '').replace('.svg', '').trim()
const content = fs.readFileSync(resolve(svgFolder, filename), 'utf8')
let { data } = optimize(content)
const stats = await getSvgStats(data)
data = data.replace(/<svg[^>]*>/i, '').replace(/<\/svg>/, '')
if (!filename.match('_fixcolor.svg')) {
const colors = [...new Set(data.match(/#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}/g))]
if (colors.length == 1) {
data = data.replace(new RegExp(escapeRegex(colors[0]), 'g'), 'currentColor')
}
else if (colors.length) {
colors.forEach((color, i) => {
data = data.replace(new RegExp(escapeRegex(color), 'g'), `var(--color${i},${color})`)
})
}
}
const ids = data.match(/url\(#[^)]+\)/g)?.map(el => el.match(/#([^)]+)/)[1]) || []
for (let id of ids) {
data = data
.replace(new RegExp(escapeRegex(`url(#${id})`), 'g'), `url(#${filename_without_ext}_${id})`)
.replace(new RegExp(escapeRegex(`id="${id}"`), 'g'), `id="${filename_without_ext}_${id}"`)
}
fs.writeFileSync(resolve(resultFolder, filename.replace('.svg', '.js')),
`export default ${JSON.stringify({ name, content: data, ...stats }, null, 2)}`
)
if (withindex) {
const allfiles = fs.readdirSync(resultFolder)
.filter(file => file.endsWith('.js') && file !== 'index.js')
fs.writeFileSync(
resolve(resultFolder, 'index.js'),
allfiles.map(file => `export { default as ${file.replace('_fixcolor', '').replace('.js', '')} } from './${file}'`).join('\n')
)
}
}
let watcher
export function svgWatcherPlugin(svgFolder, resultFolder) {
const svgPath = resolve(__dirname, svgFolder)
const resultPath = resolve(__dirname, resultFolder)
return {
name: 'svg-watcher-plugin',
buildStart() {
const files = fs.readdirSync(svgPath).filter(file => file.endsWith('.svg'))
const resultFiles = fs.readdirSync(resultPath).filter(file => file.endsWith('.js'))
for (let file of resultFiles) {
fs.unlinkSync(resolve(resultPath, file))
}
for (let file of files) {
generateSVG(svgPath, file, resultPath, file === files[files.length - 1])
}
},
configureServer() {
watcher = fs.watch(svgPath, (eventType, filename) => {
if (filename?.endsWith('.svg')) {
if (eventType === 'change') {
generateSVG(svgPath, filename, resultPath, true)
}
}
})
},
closeBundle() {
if (watcher) {
watcher.close()
watcher = null
}
},
}
}