const fs = require('fs').promises const util = require('util') const rimraf = util.promisify(require('rimraf')) const path = require('path') const SVGO = require('svgo') const compiler = require('vue-template-compiler') const { camelCase, upperFirst } = require('lodash') const rawDir = '../src/assets/eva-icons' const outputDir = '../src/components/EvaIcon' const prefix = 'eva-icon' const fullRawDir = path.join(__dirname, rawDir) const fullOutputDir = path.join(__dirname, outputDir) buildAllSVG(prefix, fullRawDir, fullOutputDir) const svgoConfig = { onlyMatchedOnce: false, plugins: [ { removeXMLNS: true }, { removeAttrs: { attrs: '(stroke|fill|class)' } }, { removeStyleElement: true }, { addAttributesToSVGElement: { attribute: { fill: 'currentColor', width: '1em', height: '1em' } } } ] } const svgo = new SVGO(svgoConfig) async function buildAllSVG(prefix, inputDir, outputDir) { try { await rimraf(outputDir) console.log('clear output dir') fs.mkdir(outputDir, { recursive: true }) } catch (e) { console.log('no cache') console.log(e) } const files = await collectAllSubFilePath(inputDir) for (const filePath of files) { const file = await fs.readFile(filePath) const optimizedSVG = await (await svgo.optimize(file)).data const svgRender = compiler .compile(`${optimizedSVG}`) .render.replace(/_/g, '_vm._') const fileBasename = path.basename(filePath, '.svg') const filename = upperFirst(camelCase(`${prefix}-${fileBasename}`)) fs.writeFile( path.join(outputDir, `${filename}.js`), `export default { functional: true, render(_h,_vm){ ${removeWith(svgRender)} } } ` ) fs.writeFile( path.join(outputDir, `${filename}.d.ts`), `declare const ${filename}: any; export default ${filename}; ` ) fs.appendFile( path.join(outputDir, 'index.js'), `export { default as ${filename} } from './${filename}' ` ) fs.appendFile( path.join(outputDir, 'index.d.ts'), `export { default as ${filename} } from './${filename}' ` ) } } function removeWith(str) { const regex = /^with\(this\)\{(.*)}$/ return regex.exec(str)[1] } /** * get all sub file path * @param {string} dirPath * @return {Promise} allFilePath */ async function collectAllSubFilePath(dirPath) { const fileList = await fs.readdir(dirPath) const allFiles = [] for (const filename of fileList) { const filePath = path.join(dirPath, filename) const fileStat = await fs.stat(filePath) if (fileStat.isDirectory()) { const subFileList = await collectAllSubFilePath(filePath) allFiles.push(...subFileList) } else { allFiles.push(filePath) } } return allFiles }