Open llushikang opened 3 years ago
by myself, i write a vite plugin to do it
https://vitejs.dev/guide/api-plugin.html
ceater ts file and write
import { Plugin } from 'vite'
import { readFileSync, readdirSync } from 'fs'
let idPerfix = ''
const svgTitle = /<svg([^>+].*?)>/
const clearHeightWidth = /(width|height)="([^>+].*?)"/g
const hasViewBox = /(viewBox="[^>+].*?")/g
const clearReturn = /(\r)|(\n)/g
function findSvgFile(dir): string[] {
const svgRes = []
const dirents = readdirSync(dir, {
withFileTypes: true
})
for (const dirent of dirents) {
if (dirent.isDirectory()) {
svgRes.push(...findSvgFile(dir + dirent.name + '/'))
} else {
const svg = readFileSync(dir + dirent.name)
.toString()
.replace(clearReturn, '')
.replace(svgTitle, ($1, $2) => {
// console.log(++i)
// console.log(dirent.name)
let width = 0
let height = 0
let content = $2.replace(
clearHeightWidth,
(s1, s2, s3) => {
if (s2 === 'width') {
width = s3
} else if (s2 === 'height') {
height = s3
}
return ''
}
)
if (!hasViewBox.test($2)) {
content += `viewBox="0 0 ${width} ${height}"`
}
return `<symbol id="${idPerfix}-${dirent.name.replace(
'.svg',
''
)}" ${content}>`
})
.replace('</svg>', '</symbol>')
svgRes.push(svg)
}
}
return svgRes
}
export const svgBuilder = (
path: string,
perfix = 'icon'
): Plugin => {
if (path === '') return
idPerfix = perfix
const res = findSvgFile(path)
// console.log(res.length)
// const res = []
return {
name: 'svg-transform',
transformIndexHtml(html): string {
return html.replace(
'<body>',
`
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
${res.join('')}
</svg>
`
)
}
}
}
import this file in vite.config and add it in the plugin array
...
import { svgBuilder } from './build/svg/svgBuilder'
...
export default (
mode: 'development' | 'production'
): UserConfig => {
// const env = loadEnv(mode, root)
return {
plugins: [
...
svgBuilder('./src/icons/svg/')],
}
}
多谢大佬!
多谢
There is a plugin vite-plugin-svg-icons - Fast creating SVG sprites.
@Lstmxx svg 可以正常展示了,但是有乱码
@Lstmxx svg 可以正常展示了,但是有乱码 问题已经解决,如果有遇到相同情况的朋友可以查看这个 https://github.com/Tyh2001/the-bug-svgBuilder/pull/1
by myself, i write a vite plugin to do it
https://vitejs.dev/guide/api-plugin.html
ceater ts file and write
import { Plugin } from 'vite' import { readFileSync, readdirSync } from 'fs' let idPerfix = '' const svgTitle = /<svg([^>+].*?)>/ const clearHeightWidth = /(width|height)="([^>+].*?)"/g const hasViewBox = /(viewBox="[^>+].*?")/g const clearReturn = /(\r)|(\n)/g function findSvgFile(dir): string[] { const svgRes = [] const dirents = readdirSync(dir, { withFileTypes: true }) for (const dirent of dirents) { if (dirent.isDirectory()) { svgRes.push(...findSvgFile(dir + dirent.name + '/')) } else { const svg = readFileSync(dir + dirent.name) .toString() .replace(clearReturn, '') .replace(svgTitle, ($1, $2) => { // console.log(++i) // console.log(dirent.name) let width = 0 let height = 0 let content = $2.replace( clearHeightWidth, (s1, s2, s3) => { if (s2 === 'width') { width = s3 } else if (s2 === 'height') { height = s3 } return '' } ) if (!hasViewBox.test($2)) { content += `viewBox="0 0 ${width} ${height}"` } return `<symbol id="${idPerfix}-${dirent.name.replace( '.svg', '' )}" ${content}>` }) .replace('</svg>', '</symbol>') svgRes.push(svg) } } return svgRes } export const svgBuilder = ( path: string, perfix = 'icon' ): Plugin => { if (path === '') return idPerfix = perfix const res = findSvgFile(path) // console.log(res.length) // const res = [] return { name: 'svg-transform', transformIndexHtml(html): string { return html.replace( '<body>', ` <body> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0"> ${res.join('')} </svg> ` ) } } }
import this file in vite.config and add it in the plugin array
... import { svgBuilder } from './build/svg/svgBuilder' ... export default ( mode: 'development' | 'production' ): UserConfig => { // const env = loadEnv(mode, root) return { plugins: [ ... svgBuilder('./src/icons/svg/')], } }
I refactor the code and publish to https://github.com/Lstmxx/vite-svg-plugin. If you are interested, you can check the code.
how to use this plugin with vite with extract mode ?
I found this https://github.com/StagnantIce/sveltekit_svg_sprite
https://www.npmjs.com/package/rollup-plugin-svg-sprites 搭配vite这个可以用,但是收藏比较少,直接在vite.config.ts中
import { basename } from 'path';
plugins: [
vue({
reactivityTransform: true,
}),
// svg
svgSprites({
exclude: ['node_modules/**'],
symbolId(path, query) {
const fileName = basename(path).replace('.svg', '');
return `icon-${fileName}`;
},
}),
]
I am using vite but vite does not seem to have webpack.