1
0

build-svg.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /**
  2. * 转换svg元素成React组件
  3. */
  4. const svgr = require('@svgr/core').default;
  5. const { optimize } = require('svgo');
  6. const fs = require('fs');
  7. const { resolve, basename, extname } = require('path');
  8. const camelCase = require('camelcase');
  9. const prettier = require('prettier');
  10. /**
  11. *
  12. * @param {*} entryDir 存放svg文件夹
  13. * @param {*} outDir 输出React组件文件夹
  14. * @param {*} decolorize 是否去色
  15. * @param {*} prefix 图标前缀
  16. * @param {*} suffix 图标后缀
  17. */
  18. async function build(entryDir, outDir, prefix, suffix, svgoPlugins = [], svgrOptions = {}) {
  19. const prettierConfig = require(resolve(__dirname, '../.prettierrc.js'));
  20. fs.rmdirSync(outDir, { recursive: true });
  21. fs.mkdirSync(outDir);
  22. // 读取svg文件夹下的文件,转译成React组件,并输出
  23. const files = fs.readdirSync(entryDir, 'utf-8');
  24. const indexFileName = 'index.ts';
  25. const batches = files.filter(f => extname(f) === '.svg').map(async file => {
  26. try {
  27. const svgFileName = basename(file, '.svg');
  28. const componentName = `${prefix}${camelCase(svgFileName, { pascalCase: true })}${suffix}`;
  29. const reactFileName = `${componentName}.tsx`;
  30. const svgContent = fs.readFileSync(resolve(entryDir, file), 'utf-8');
  31. const svgProps = {
  32. focusable: '{false}',
  33. 'aria-hidden': true
  34. };
  35. const result = optimize(svgContent, {
  36. plugins: svgoPlugins,
  37. });
  38. const jsxCode = await svgr(result.data, {
  39. plugins: ['@svgr/plugin-jsx'],
  40. svgProps,
  41. iconType: svgFileName,
  42. ...svgrOptions,
  43. });
  44. const formattedCode = prettier.format(jsxCode, prettierConfig);
  45. fs.writeFileSync(resolve(outDir, reactFileName), formattedCode, 'utf-8');
  46. return { fileName: reactFileName, componentName };
  47. } catch (error) {
  48. console.error(error);
  49. throw error;
  50. }
  51. });
  52. const arr = await Promise.all(batches);
  53. const indexFileContent = arr.map(a => `export { default as ${a.componentName} } from './${a.componentName}';`).join('\n');
  54. fs.writeFileSync(resolve(outDir, indexFileName), indexFileContent, 'utf-8');
  55. return arr;
  56. }
  57. module.exports = build;