index.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import fs from 'fs-extra';
  2. import { optimize } from 'svgo';
  3. // @ts-expect-error svgstore no declaration file
  4. import svgstore from 'svgstore';
  5. interface StdfIconOptions {
  6. inFile?: string;
  7. outFile?: string;
  8. fileName?: string;
  9. simple?: boolean;
  10. }
  11. export default function svgSprite(datas: StdfIconOptions[] = []) {
  12. // 可接收多组参数,处理多个文件夹内的文件
  13. // Multiple parameters can be accepted to process files in multiple folders
  14. const data = datas ? datas : [{ inFile: 'src/lib/symbol', outFile: 'static/fonts', fileName: '', simple: true }];
  15. // 循环处理每一组参数
  16. // Loop through each set of parameters
  17. if (Array.isArray(data)) {
  18. // 给出提示,开始处理几个文件夹
  19. // Give a prompt, how many folders are being processed
  20. console.log(`[rollup-plugin-stdf-icon]: ⌛ Start processing ${data.length} folders...`);
  21. data.forEach((item: any) => {
  22. const { inFile, outFile, fileName, simple = true } = item;
  23. // 如果 fileName 为默认 '',则将 inFile 的最后一个文件夹作为 fileName,注意不同操作系统的路径分隔符
  24. // If fileName is the default '', then the last folder of inFile is used as fileName, pay attention to the path separator of different operating systems
  25. const fileNameInner = fileName ? fileName : inFile.split('/').pop();
  26. handleFile(inFile, outFile, fileNameInner, simple);
  27. });
  28. }
  29. return { name: 'rollup-plugin-stdf-icon' };
  30. }
  31. // 处理一个文件夹内的文件
  32. // Process files in a folder
  33. function handleFile(inFile: string, outFile: string, fileName: string, simple = true) {
  34. // 如果 outFile 不存在, 则创建
  35. // If outFile does not exist, create it
  36. if (!fs.existsSync(outFile)) {
  37. fs.mkdirSync(outFile);
  38. }
  39. // 创建一个空的 svgstore
  40. // Create an empty svgstore
  41. const sprites = svgstore({ cleanDefs: true });
  42. // 循环 icons 目录下的所有 svg 文件
  43. // Loop through all svg files in the icons directory
  44. const svgs = fs.readdirSync(inFile);
  45. svgs.forEach((svg: string) => {
  46. if (!svg.endsWith('.svg')) {
  47. // 读取 svg 文件内容, 如果文件不是 svg 文件, 则给出提示并跳过
  48. // Read the contents of the svg file, if the file is not an svg file, give a prompt and skip
  49. console.warn(`[rollup-plugin-stdf-icon]: ⏭️ ${inFile}/${svg} is not a svg file, skip it!`);
  50. } else {
  51. const code = fs.readFileSync(`${inFile}/${svg}`, 'utf8');
  52. // 使用 SVGO 进行优化
  53. // Use SVGO for optimization
  54. const result = optimize(code);
  55. // 删除 result 中的 p-id class 等属性
  56. // Delete p-id class and other attributes in result
  57. result.data = result.data.replace(/p-id="[^"]*"/g, '').replace(/class="[^"]*"/g, '');
  58. // 如果 result 中有 fill 属性,属性值不为 none, 则将 fill 属性值设置为 currentColor
  59. // If there is a fill attribute in result, the attribute value is not none, then set the fill attribute value to currentColor
  60. if (simple && result.data.indexOf('fill=') > -1 && result.data.indexOf('fill="none"') === -1) {
  61. result.data = result.data.replace(/fill="[^"]*"/g, 'fill="currentColor"');
  62. }
  63. // 如果 result 中有 stroke 属性,属性值不为 none, 则将 stroke 属性值设置为 currentColor
  64. // If there is a stroke attribute in result, the attribute value is not none, then set the stroke attribute value to currentColor
  65. if (simple && result.data.indexOf('stroke=') > -1 && result.data.indexOf('stroke="none"') === -1) {
  66. result.data = result.data.replace(/stroke="[^"]*"/g, 'stroke="currentColor"');
  67. }
  68. // 将优化后的 svg 添加到 sprites 中
  69. // Add the optimized svg to sprites
  70. sprites.add(svg.replace('.svg', ''), result.data, { copyAttrs: ['fill', 'stroke'] });
  71. }
  72. });
  73. // 已完成合并(inFile)中的多少个 svg 文件至 outFile/fileName.svg
  74. // Have merged how many svg files in (inFile) to outFile/fileName.svg
  75. console.log(`[rollup-plugin-stdf-icon]: ✅ ${inFile} has merged ${svgs.length} svg files to ${outFile}/${fileName}.svg`);
  76. // 删除 sprites 的 <?xml...?> 标签和 <!DOCTYPE...> 标签 和 <defs/> 标签
  77. // Delete the <?xml...?> tag and <!DOCTYPE...> tag of sprites
  78. const spritesStr = sprites
  79. .toString()
  80. .replace(/<\?xml[^>]*>/g, '')
  81. .replace(/<!DOCTYPE[^>]*>/g, '')
  82. .replace(/<defs\/>/g, '');
  83. // 写入到指定的文件中
  84. // Write to the specified file
  85. fs.writeFileSync(outFile + '/' + fileName + '.svg', spritesStr);
  86. }