合同小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.4 KiB

3 months ago
  1. const { readFileSync, existsSync } = require('fs');
  2. const path = require('path');
  3. const {generate} = require('./utils/generate')
  4. // 插件的名称
  5. const pluginName = 'vite-plugin-limeIcon';
  6. // 要监听的组件的名称
  7. const targetComponent = 'l-icon';
  8. function parseAttributes(attributesStr) {
  9. if (!attributesStr.includes("'")) {
  10. return [attributesStr]
  11. }
  12. const regex = /'([^']+)'/g;
  13. const matches = attributesStr.match(regex);
  14. if (matches) {
  15. const targetContent = matches.map(item => item.replace(/'/g, ''));
  16. return targetContent
  17. } else {
  18. return [attributesStr]
  19. }
  20. }
  21. function extractAttributes(content) {
  22. const regex = /<l-icon\s*[^>]*(:?)name=["]([^"]+)["][^>]*>/g; // /<l-icon\s+(.*?)\s*\/?>/g //<l-icon\s+([^>]+)\s*\/?>/g;
  23. let attributes = [];
  24. const attributesSet = new Set(attributes);
  25. let match;
  26. while ((match = regex.exec(content)) !== null) {
  27. const attributesStr = match[2];
  28. const attributesList = parseAttributes(attributesStr);
  29. for (const attribute of attributesList) {
  30. attributesSet.add(attribute); // 添加新属性到Set中
  31. }
  32. }
  33. attributes = [...attributesSet];
  34. return attributes;
  35. }
  36. // 遍历每个文件并检查是否使用了目标组件
  37. let iconCollections = {}
  38. let files = {}
  39. let timer = null
  40. function processFile(file, options) {
  41. const filePath = path.resolve(file);
  42. const content = readFileSync(filePath, 'utf-8');
  43. // 检查文件是否包含目标组件
  44. if (content.includes(targetComponent) && (!file.includes('l-icon.vue') || !file.includes('l-icon.uvue')) && files[file] !== content) {
  45. const icons = extractAttributes(content)
  46. if(icons && icons.length) {
  47. files[file] = content
  48. iconCollections[file] = icons
  49. }
  50. Object.values(iconCollections).forEach(icons => {
  51. if(options.icons) {
  52. options.icons = options.icons.concat(icons);
  53. } else {
  54. options.icons = icons
  55. }
  56. })
  57. clearTimeout(timer)
  58. timer = setTimeout(() => {
  59. options.icons = Array.from(new Set(options.icons))
  60. generate(options)
  61. },500)
  62. }
  63. }
  64. // 插件的钩子函数
  65. function vitePlugin(options = {}) {
  66. const {useInDevelopment = false} = options
  67. const isDev = process.env.NODE_ENV === 'development'
  68. return {
  69. name: pluginName,
  70. transform(code, id) {
  71. if (id.endsWith('.vue') && (useInDevelopment && isDev || !useInDevelopment && !isDev)) {
  72. // 处理Vue文件
  73. processFile(id, options);
  74. }
  75. },
  76. };
  77. }
  78. module.exports = vitePlugin;