index.ts 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { readFileSync, readdirSync } from 'fs';
  2. let idPerfix = '';
  3. const iconNames: string[] = [];
  4. const svgTitle = /<svg([^>+].*?)>/;
  5. const clearHeightWidth = /(width|height)="([^>+].*?)"/g;
  6. const hasViewBox = /(viewBox="[^>+].*?")/g;
  7. const clearReturn = /(\r)|(\n)/g;
  8. // 清理 svg 的 fill
  9. const clearFill = /(fill="[^>+].*?")/g;
  10. function findSvgFile(dir: string): string[] {
  11. const svgRes = [] as any;
  12. const dirents = readdirSync(dir, {
  13. withFileTypes: true,
  14. });
  15. for (const dirent of dirents) {
  16. iconNames.push(`${idPerfix}-${dirent.name.replace('.svg', '')}`);
  17. if (dirent.isDirectory()) {
  18. svgRes.push(...findSvgFile(dir + dirent.name + '/'));
  19. } else {
  20. const svg = readFileSync(dir + dirent.name)
  21. .toString()
  22. .replace(clearReturn, '')
  23. .replace(clearFill, 'fill=""')
  24. .replace(svgTitle, ($1, $2) => {
  25. let width = 0;
  26. let height = 0;
  27. let content = $2.replace(clearHeightWidth, (s1: string, s2: string, s3: number) => {
  28. if (s2 === 'width') {
  29. width = s3;
  30. } else if (s2 === 'height') {
  31. height = s3;
  32. }
  33. return '';
  34. });
  35. if (!hasViewBox.test($2)) {
  36. content += `viewBox="0 0 ${width} ${height}"`;
  37. }
  38. return `<symbol id="${idPerfix}-${dirent.name.replace('.svg', '')}" ${content}>`;
  39. })
  40. .replace('</svg>', '</symbol>');
  41. svgRes.push(svg);
  42. }
  43. }
  44. return svgRes;
  45. }
  46. export const svgBuilder = (path: string, perfix = 'local') => {
  47. if (path === '') return;
  48. idPerfix = perfix;
  49. const res = findSvgFile(path);
  50. return {
  51. name: 'svg-transform',
  52. transformIndexHtml(html: string) {
  53. /* eslint-disable */
  54. return html.replace(
  55. '<body>',
  56. `
  57. <body>
  58. <svg id="local-icon" data-icon-name="${iconNames.join(
  59. ','
  60. )}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
  61. ${res.join('')}
  62. </svg>
  63. `
  64. );
  65. /* eslint-enable */
  66. },
  67. };
  68. };