‘liusuyi’
2023-10-21 94023628bd9c5e6bf724c37371a19b60d338b291
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
 * @author tyankatsu <https://github.com/tyankatsu0105>
 * See LICENSE file in root directory for full license.
 */
'use strict'
 
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
 
const { isVElement } = require('../utils')
 
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
 
/**
 * check whether has attribute `src`
 * @param {VElement} componentBlock
 */
function hasAttributeSrc(componentBlock) {
  const hasAttribute = componentBlock.startTag.attributes.length > 0
 
  const hasSrc =
    componentBlock.startTag.attributes.filter(
      (attribute) =>
        !attribute.directive &&
        attribute.key.name === 'src' &&
        attribute.value &&
        attribute.value.value !== ''
    ).length > 0
 
  return hasAttribute && hasSrc
}
 
/**
 * check whether value under the component block is only whitespaces or break lines
 * @param {VElement} componentBlock
 */
function isValueOnlyWhiteSpacesOrLineBreaks(componentBlock) {
  return (
    componentBlock.children.length === 1 &&
    componentBlock.children[0].type === 'VText' &&
    !componentBlock.children[0].value.trim()
  )
}
 
module.exports = {
  meta: {
    type: 'suggestion',
    docs: {
      description:
        'disallow the `<template>` `<script>` `<style>` block to be empty',
      categories: undefined,
      url: 'https://eslint.vuejs.org/rules/no-empty-component-block.html'
    },
    fixable: null,
    schema: [],
    messages: {
      unexpected: '`<{{ blockName }}>` is empty. Empty block is not allowed.'
    }
  },
 
  /**
   * @param {RuleContext} context - The rule context.
   * @returns {RuleListener} AST event handlers.
   */
  create(context) {
    if (!context.parserServices.getDocumentFragment) {
      return {}
    }
    const documentFragment = context.parserServices.getDocumentFragment()
    if (!documentFragment) {
      return {}
    }
 
    const componentBlocks = documentFragment.children.filter(isVElement)
 
    return {
      Program() {
        for (const componentBlock of componentBlocks) {
          if (
            componentBlock.name !== 'template' &&
            componentBlock.name !== 'script' &&
            componentBlock.name !== 'style'
          )
            continue
 
          // https://vue-loader.vuejs.org/spec.html#src-imports
          if (hasAttributeSrc(componentBlock)) continue
 
          if (
            isValueOnlyWhiteSpacesOrLineBreaks(componentBlock) ||
            componentBlock.children.length === 0
          ) {
            context.report({
              node: componentBlock,
              loc: componentBlock.loc,
              messageId: 'unexpected',
              data: {
                blockName: componentBlock.name
              }
            })
          }
        }
      }
    }
  }
}