Last active
December 7, 2020 09:31
-
-
Save syrxw/5ef7c2fdcdd03694b7cbfe3451676a92 to your computer and use it in GitHub Desktop.
svg symbol合成脚本
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const program = require("commander"); | |
const fsp = require("fs").promises; | |
const path = require("path"); | |
const chalk = require("chalk"); | |
const globby = require("globby"); | |
const cheerio = require("cheerio"); | |
const css = require("css"); | |
const chokidar = require("chokidar"); | |
program | |
.version("0.0.2") | |
.description("svg图标雪碧图生成器 by syrxw") | |
.option("-g, --generate", "生成"); | |
const svgFilePath = path.resolve("src/icons/icons.svg"); // svg最终生成文件 | |
const dir = path.resolve("src/assets/image/svg_icons");// svg图标文件路径 | |
const filePaths = globby.sync(["**/*.svg"], { | |
cwd: dir, | |
}); | |
let svgFile = null; | |
function splitFileName(text) { | |
var pattern = /\.{1}[a-z]{1,}$/; | |
if (pattern.exec(text) !== null) { | |
return text.slice(0, pattern.exec(text).index); | |
} else { | |
return text; | |
} | |
} | |
// 生成css AST语法树 | |
function parseCSS(content) { | |
const obj = css.parse(content); | |
const rules = obj.stylesheet.rules; | |
return rules.map((item) => { | |
return { | |
selector: item.selectors[0], | |
declarations: item.declarations.map((kitem) => { | |
return { | |
property: kitem.property, | |
value: kitem.value, | |
}; | |
}), | |
}; | |
}); | |
} | |
// 读取svg文件 | |
async function readSvgFile() { | |
try { | |
const data = await fsp.readFile(svgFilePath); | |
svgFile = cheerio.load(data, { xmlMode: true }); | |
} catch (err) { | |
console.log(chalk.red("icons.svg文件不存在或文件损坏")); | |
return false; | |
} | |
} | |
async function readSvgIcons() { | |
try { | |
svgFile("defs").html(" "); | |
for (const file of filePaths) { | |
const data = await fsp.readFile(path.join(dir, file)); | |
const $ = cheerio.load(data, { xmlMode: true }); | |
const fileName = splitFileName(file); | |
if ($("path").length < 1) { | |
return false; | |
} else { | |
if ($("style").length > 0) { | |
const parsrCssRst = parseCSS($("style").html()); | |
parsrCssRst.forEach((item) => { | |
item.declarations.forEach((declar) => { | |
$(item.selector).attr(declar.property, declar.value); | |
}); | |
}); | |
} | |
const svgWidth = $("svg").attr("width"); | |
const svgHeight = $("svg").attr("width"); | |
const element = `<symbol id="${fileName}" viewBox="0 0 ${ | |
svgWidth ? svgWidth.replace("px", "") : 100 | |
} ${svgHeight ? svgHeight.replace("px", "") : 100}">${$( | |
"path" | |
)}</symbol>`; | |
svgFile("defs").append(element); | |
} | |
} | |
} catch (err) { | |
console.log(chalk.red(err)); | |
return false; | |
} | |
} | |
async function writeIconFile() { | |
try { | |
await fsp.writeFile(svgFilePath, svgFile.root().html()); | |
} catch (err) { | |
console.log(chalk.red(err)); | |
return false; | |
} | |
} | |
async function main() { | |
try { | |
await readSvgFile(); | |
} catch (e) { | |
console.log(chalk.red(err)); | |
} | |
try { | |
await readSvgIcons(); | |
} catch (e) { | |
console.log(chalk.red(err)); | |
} | |
try { | |
await writeIconFile(); | |
} catch (e) { | |
console.log(chalk.red(err)); | |
} | |
} | |
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="hello"> | |
<svg class="svg-icon" aria-hidden="true" v-for="n in 38" :key="n"> | |
<use :xlink:href="`#icon_0${n}`"></use> | |
</svg> | |
</div> | |
</template> | |
<script> | |
import '@/icons/icons.svg'; | |
export default { | |
name: 'HelloWorld', | |
props: { | |
msg: String | |
} | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// vue.config.js | |
const path = require('path') | |
module.exports = { | |
chainWebpack: config => { | |
const svgRule = config.module.rule('svg') | |
// 清除已有的所有 loader。 | |
// 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。 | |
svgRule.uses.clear() | |
svgRule | |
.test(/\.svg$/) | |
.include.add(path.resolve(__dirname, './src/icons')) | |
.end() | |
.use('svg-sprite-loader') | |
.loader('svg-sprite-loader') | |
.options({ | |
symbolId: 'icon' | |
}) | |
const fileRule = config.module.rule('file') | |
fileRule.uses.clear() | |
fileRule | |
.test(/\.svg$/) | |
.exclude.add(path.resolve(__dirname, './src/icons')) | |
.end() | |
.use('file-loader') | |
.loader('file-loader') | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment