UNPKG

svg-symbol-sprite

Version:
93 lines (92 loc) 4.19 kB
#!/usr/bin/env node "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = require("fs"); const path_1 = require("path"); const cheerio_1 = require("cheerio"); const commander_1 = require("commander"); const svgo_1 = require("svgo"); const { rm, readdir, readFile, writeFile } = fs_1.promises; const cli = new commander_1.Command(); const SVG_PROPS = 'xmlns="http://www.w3.org/2000/svg" aria-hidden="true"'; const SVG_STYLE = 'width: 0; height: 0; position: absolute;'; const DEFAULT_CONFIG = (0, path_1.join)(__dirname, '..', 'config', 'svgo.config.js'); const CHEERIO_OPTIONS = { lowerCaseTags: true, lowerCaseAttributeNames: true, _useHtmlParser2: true }; cli.option('-i, --input [input]', 'Specifies input dir (current dir by default)', '.') .option('-o, --output [output]', 'Specifies output file ("./sprite.svg" by default)', 'sprite.svg') .option('-v, --viewbox [viewbox]', 'Specifies viewBox attribute (parsed by default)', '') .option('-p, --prefix [prefix]', 'Specifies prefix for id attribute ("icon-" by default)', 'icon-') .option('-c, --config [config]', 'Absolute path to the SVGO config file or "false"', './config/svgo.config.js') .option('-a, --attrs [attributes]', 'Attributes for the SVG element', SVG_PROPS) .option('-s, --style [style]', 'Inline style for the SVG element', SVG_STYLE) .parse(process.argv); const { input: INPUT, output: OUTPUT, viewbox: VIEWBOX, prefix: PREFIX, config: CONFIG, attrs: ATTRS, style: STYLE } = cli.opts(); const onEnd = () => console.log(`File ‘${OUTPUT}’ successfully generated.`); const getSvg = (content) => (0, cheerio_1.load)(content, CHEERIO_OPTIONS)('svg').first(); const filterFile = (file) => (0, path_1.extname)(file) === '.svg'; const processFiles = (files) => Promise.all(files.map(processFile)); const removeOutput = async () => ((0, fs_1.existsSync)(OUTPUT) ? await rm(OUTPUT) : undefined); const getSvgContent = (content) => getSvg(content).html(); const readSrcFolder = () => readdir(INPUT); const writeDestFile = (content) => writeFile(OUTPUT, content, 'utf8'); const getSpriteContent = (contents) => { return `<${['svg', ATTRS, `style="${STYLE}"`].join(' ').replace('style=""', '').trim()}>${contents.join('')}</svg>`; }; const getSymbol = (content, attrs) => { return `<symbol${getAttributes(attrs)}>${getSvgContent(content)}</symbol>`; }; const getAttributes = (attrs) => Object.keys(attrs).reduce((acc, key) => { const value = attrs[key]; return value ? `${acc} ${key}="${value}"` : acc; }, ''); const wrapFile = (fileName, content) => { const attrs = { id: (PREFIX + fileName).replace(/\s/g, '-'), viewBox: VIEWBOX || getSvg(content).attr('viewbox'), preserveAspectRatio: getSvg(content).attr('preserveaspectratio') }; return getSymbol(content, attrs); }; const getName = (file) => (0, path_1.basename)(file, (0, path_1.extname)(file)); const processFile = (file) => { const path = (0, path_1.resolve)(INPUT, file); const name = getName(file); const wrapContent = wrapFile.bind(null, name); return readFile(path, 'utf8').then(wrapContent); }; const onError = (err) => { throw err; }; removeOutput() .then(readSrcFolder) .then(async (files) => { const matchingFiles = files.filter(filterFile); if (CONFIG === 'false') { return processFiles(matchingFiles); } let svgoConfig = await (0, svgo_1.loadConfig)(DEFAULT_CONFIG); try { svgoConfig = await (0, svgo_1.loadConfig)(CONFIG); } catch (e) { console.log('SVG Symbol Sprite: SVGO configuration file not found. Using default SVGO configuration.'); } const processedFiles = []; for (const file of matchingFiles) { const content = await fs_1.promises.readFile((0, path_1.join)(INPUT, file), { encoding: 'utf-8' }); const name = getName(file); const optimizedSVG = (0, svgo_1.optimize)(content, svgoConfig).data; processedFiles.push(wrapFile(name, optimizedSVG)); } return processedFiles; }) .then(getSpriteContent) .then(writeDestFile) .then(onEnd) .catch(onError);