如何使用 vue-eslint-parser 识别功能组件

How to identify functional component with vue-eslint-parser

我正在使用 vue-eslint-parser 编写我的 eslint 规则。需要 来防止 功能组件使用 vue template 语法。

我已经写了一个规则来禁止语法 <template functional> :

create(context) {
    return context.parserServices.defineDocumentVisitor(
      {
        VDocumentFragment(node) {
          const template = node.children.find(item => item.type === 'VElement' && item.name === 'template');

          if (!template) return;

          const functionalAttr = template.startTag.attributes.find(item => !item.directive && item.key.name === 'functional');


          if (functionalAttr) {
            context.report({
              message: "Don't use vue templates with functional components",
              loc: node.loc
            });
          }
        }
      }
    );
  }

问题: 如何使以下代码也 invalid ? (换句话说,如何检查script标签和里面的代码)。

<template>

</template>

<script>
export default {
  functional: true,
};
</script>

谢谢!

Link 到我找到解决方案的(不是很清楚的)文档:

create(context: Rule.RuleContext) {
    return context.parserServices.defineTemplateBodyVisitor(
      {
        VElement(node: VElement): void {
          if (node.name !== 'template') return;

          const functionalAttr = node.startTag.attributes.find(item => !item.directive && item.key.name === 'functional');

          if (functionalAttr) {
            context.report({
              message: "Don't use 'functional' attribute in vue templates. Use render function instead of vue templates for functional components.",
              loc: node.loc
            });
          }
        }
      },
      {
        Program(node: ESLintProgram): void {
          if (!node.templateBody) return;

          const targetNode = node.body.find(item => item.type === 'ExportDefaultDeclaration') as ExportDefaultDeclaration || undefined;

          if (!targetNode) return;

          const functionalOption = (targetNode.declaration as ObjectExpression).properties.find(item => item.type === 'Property' && (item.key as Identifier).name === 'functional');

          if (functionalOption) {
            context.report({
              message: "Don't use 'functional' property along with vue templates. Use render function instead of vue templates for functional components.",
              loc: node.loc
            });
          }
        }
      }
    );
  }