eslint规则 处理未定义的组件(自动注册)

Posted on 2024-05-25 22:29  生之不止,思之不息  阅读(27)  评论(0)    收藏  举报

要创建一个 ESLint 插件以处理 Vue 2 项目中的 Vue 文件,您需要遵循以下步骤:

  1. 创建插件目录和文件:创建一个目录来存放您的 ESLint 插件文件。比如 eslint-plugin-vue-components,然后在该目录中创建一个规则文件 lib/rules/register-components.js

  2. 编写规则逻辑:在 register-components.js 中实现您的规则逻辑。

  3. 配置插件:在 index.js 中配置插件并导出规则。

以下是一个示例实现:

目录结构

eslint-plugin-vue-components
├── lib
│   └── rules
│       └── register-components.js
├── index.js
└── package.json

package.json

{
  "name": "eslint-plugin-vue-components",
  "version": "1.0.0",
  "main": "index.js",
  "peerDependencies": {
    "eslint": "^7.0.0",
    "vue-eslint-parser": "^7.0.0"
  }
}

index.js

module.exports = {
  rules: {
    'register-components': require('./lib/rules/register-components')
  }
};

lib/rules/register-components.js

const componentMap = [
  {
    tags: ['base-icon', 'BaseIcon'],
    import: 'import BaseIcon from "@/components/BaseIcon.vue"'
  },
  // Add more components as needed
];

module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Auto import and register components used in template',
      category: 'Possible Errors',
      recommended: false
    },
    fixable: 'code',
    schema: []
  },
  create(context) {
    const sourceCode = context.getSourceCode();
    let hasTemplate = false;
    let registeredComponents = [];

    return {
      'Program:exit'(node) {
        const templateBody = node.templateBody;
        if (!templateBody) return;

        templateBody.children.forEach(child => {
          if (child.type === 'VElement') {
            const tagName = child.rawName;
            componentMap.forEach(component => {
              if (component.tags.includes(tagName) && !registeredComponents.includes(tagName)) {
                const script = node.body.find(n => n.type === 'ExportDefaultDeclaration');
                if (script) {
                  const componentsProperty = script.declaration.properties.find(p => p.key.name === 'components');
                  if (componentsProperty) {
                    if (!componentsProperty.value.properties.find(p => p.key.name === tagName)) {
                      context.report({
                        node: child,
                        message: `Component '${tagName}' is used but not registered in components.`,
                        fix(fixer) {
                          const importStatement = component.import;
                          const componentsText = `${tagName}: ${tagName}`;
                          return [
                            fixer.insertTextBefore(script, importStatement + '\n'),
                            fixer.insertTextAfterRange([componentsProperty.value.range[0] + 1, componentsProperty.value.range[0] + 1], componentsText + ',')
                          ];
                        }
                      });
                      registeredComponents.push(tagName);
                    }
                  } else {
                    context.report({
                      node: child,
                      message: `Component '${tagName}' is used but not registered in components.`,
                      fix(fixer) {
                        const importStatement = component.import;
                        const componentsText = `components: { ${tagName}: ${tagName} }`;
                        return [
                          fixer.insertTextBefore(script, importStatement + '\n'),
                          fixer.insertTextAfter(script.declaration.properties[0], `, ${componentsText}`)
                        ];
                      }
                    });
                    registeredComponents.push(tagName);
                  }
                }
              }
            });
          }
        });
      }
    };
  }
};

使用说明

  1. 安装插件:在您的 Vue 项目中安装该插件。
npm install eslint-plugin-vue-components
  1. 配置 ESLint:在 ESLint 配置文件(如 .eslintrc.js)中添加该插件和规则。
module.exports = {
  plugins: [
    'vue-components'
  ],
  rules: {
    'vue-components/register-components': 'error'
  },
  parserOptions: {
    parser: 'vue-eslint-parser'
  }
};

这个 ESLint 插件会检查 template 块中的标签,并根据 componentMap 自动引入和注册未引入的组件。您可以根据需要扩展 componentMap 以支持更多的自定义组件。

博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3