import { parseArgs } from 'node:util'
import { readFile, writeFile, glob } from 'node:fs/promises'
import { optimize as svgoOptimize } from 'svgo'
import svgoConfig from '../svgo.config.mjs'
const filesWithSvgs = {
'src/globals.ts': [
/(const mdi\S+ = ')([^']*)'/g
],
'src/plugins/afcIcons.ts': [
/(const afc\S+ =\s+')([^']*)'/g
]
}
const writeFileIfContentChanged = async (path, before, after) => {
if (before === after) {
return
}
console.log(`Optimized SVG paths in ${path}
Before: ${before.length} bytes
After: ${after.length} bytes
Saved: ${before.length - after.length} bytes, ${(after.length / before.length * 100).toFixed(2)}%`)
await writeFile(path, after, { encoding: 'utf8' })
}
const optimizeSvgPath = (inputSvgPath) => {
const { data } = svgoOptimize(``, svgoConfig)
const startIndex = data.indexOf('d="') + 3
const endIndex = data.lastIndexOf('"')
const outputSvgPath = data.slice(startIndex, endIndex)
return outputSvgPath
}
const optimizeSvgFile = async (file) => {
const contentBefore = await readFile(file, { encoding: 'utf8' })
const { data: contentAfter } = svgoOptimize(contentBefore, svgoConfig)
await writeFileIfContentChanged(file, contentBefore, contentAfter)
}
const optimizeVueFile = async (file) => {
const contentBefore = await readFile(file, { encoding: 'utf8' })
const contentAfter = contentBefore.replaceAll(/(]* d=")([^"]*)"/g, (match, head, inputSvgPath) => {
const outputSvgPath = optimizeSvgPath(inputSvgPath)
return `${head}${outputSvgPath}"`
})
await writeFileIfContentChanged(file, contentBefore, contentAfter)
}
const optimizeFileWithSvgs = async (file) => {
const contentBefore = await readFile(file, { encoding: 'utf8' })
let contentAfter = contentBefore
for (const regexp of filesWithSvgs[file]) {
contentAfter = contentAfter.replaceAll(regexp, (match, head, inputSvgPath) => {
const outputSvgPath = optimizeSvgPath(inputSvgPath)
return `${head}${outputSvgPath}'`
})
}
await writeFileIfContentChanged(file, contentBefore, contentAfter)
}
(async () => {
const { positionals: patterns } = parseArgs({
args: process.argv.slice(2),
allowPositionals: true
})
for await (const filename of glob(patterns)) {
if (filename.endsWith('.svg')) {
await optimizeSvgFile(filename)
} else if (filename.endsWith('.vue')) {
await optimizeVueFile(filename)
} else if (filename in filesWithSvgs) {
await optimizeFileWithSvgs(filename)
}
}
})()