@@ -22,20 +22,44 @@ const kebabCaseElements = [
22
22
'missing-glyph'
23
23
]
24
24
25
+ // https://vuejs.org/v2/api/index.html#Built-In-Components
26
+ const vueBuiltInComponents = [
27
+ 'component' ,
28
+ 'transition' ,
29
+ 'transition-group' ,
30
+ 'keep-alive' ,
31
+ 'slot'
32
+ ]
33
+
34
+ const vue3BuiltInComponents = [
35
+ 'teleport' ,
36
+ 'suspense'
37
+ ]
38
+
25
39
const isLowercase = ( word ) => / ^ [ a - z ] * $ / . test ( word )
26
40
const capitalizeFirstLetter = ( word ) => word [ 0 ] . toUpperCase ( ) + word . substring ( 1 , word . length )
27
41
28
- const RESERVED_NAMES = new Set (
29
- [
30
- ...kebabCaseElements ,
31
- ...kebabCaseElements . map ( casing . pascalCase ) ,
32
- ...htmlElements ,
33
- ...htmlElements . map ( capitalizeFirstLetter ) ,
34
- ...deprecatedHtmlElements ,
35
- ...deprecatedHtmlElements . map ( capitalizeFirstLetter ) ,
36
- ...svgElements ,
37
- ...svgElements . filter ( isLowercase ) . map ( capitalizeFirstLetter )
38
- ] )
42
+ const RESERVED_NAMES_IN_HTML = new Set ( [
43
+ ...htmlElements ,
44
+ ...htmlElements . map ( capitalizeFirstLetter )
45
+ ] )
46
+ const RESERVED_NAMES_IN_VUE = new Set ( [
47
+ ...vueBuiltInComponents ,
48
+ ...vueBuiltInComponents . map ( casing . pascalCase )
49
+ ] )
50
+ const RESERVED_NAMES_IN_VUE3 = new Set ( [
51
+ ...RESERVED_NAMES_IN_VUE ,
52
+ ...vue3BuiltInComponents ,
53
+ ...vue3BuiltInComponents . map ( casing . pascalCase )
54
+ ] )
55
+ const RESERVED_NAMES_IN_OTHERS = new Set ( [
56
+ ...deprecatedHtmlElements ,
57
+ ...deprecatedHtmlElements . map ( capitalizeFirstLetter ) ,
58
+ ...kebabCaseElements ,
59
+ ...kebabCaseElements . map ( casing . pascalCase ) ,
60
+ ...svgElements ,
61
+ ...svgElements . filter ( isLowercase ) . map ( capitalizeFirstLetter )
62
+ ] )
39
63
40
64
// ------------------------------------------------------------------------------
41
65
// Rule Definition
@@ -46,14 +70,41 @@ module.exports = {
46
70
type : 'suggestion' ,
47
71
docs : {
48
72
description : 'disallow the use of reserved names in component definitions' ,
49
- categories : undefined , // 'essential'
73
+ categories : undefined ,
50
74
url : 'https://eslint.vuejs.org/rules/no-reserved-component-names.html'
51
75
} ,
52
76
fixable : null ,
53
- schema : [ ]
77
+ schema : [ {
78
+ type : 'object' ,
79
+ properties : {
80
+ disallowVueBuiltInComponents : {
81
+ type : 'boolean'
82
+ } ,
83
+ disallowVue3BuiltInComponents : {
84
+ type : 'boolean'
85
+ }
86
+ }
87
+ } ] ,
88
+ messages : {
89
+ reserved : 'Name "{{name}}" is reserved.' ,
90
+ reservedInHtml : 'Name "{{name}}" is reserved in HTML.' ,
91
+ reservedInVue : 'Name "{{name}}" is reserved in Vue.js.' ,
92
+ reservedInVue3 : 'Name "{{name}}" is reserved in Vue.js 3.x.'
93
+ }
54
94
} ,
55
95
56
96
create ( context ) {
97
+ const options = context . options [ 0 ] || { }
98
+ const disallowVueBuiltInComponents = options . disallowVueBuiltInComponents === true
99
+ const disallowVue3BuiltInComponents = options . disallowVue3BuiltInComponents === true
100
+
101
+ const reservedNames = new Set ( [
102
+ ...RESERVED_NAMES_IN_HTML ,
103
+ ...( disallowVueBuiltInComponents ? RESERVED_NAMES_IN_VUE : [ ] ) ,
104
+ ...( disallowVue3BuiltInComponents ? RESERVED_NAMES_IN_VUE3 : [ ] ) ,
105
+ ...RESERVED_NAMES_IN_OTHERS
106
+ ] )
107
+
57
108
function canVerify ( node ) {
58
109
return node . type === 'Literal' || (
59
110
node . type === 'TemplateLiteral' &&
@@ -70,15 +121,17 @@ module.exports = {
70
121
} else {
71
122
name = node . value
72
123
}
73
- if ( RESERVED_NAMES . has ( name ) ) {
124
+ if ( reservedNames . has ( name ) ) {
74
125
report ( node , name )
75
126
}
76
127
}
77
128
78
129
function report ( node , name ) {
79
130
context . report ( {
80
131
node : node ,
81
- message : 'Name "{{name}}" is reserved.' ,
132
+ messageId : RESERVED_NAMES_IN_HTML . has ( name ) ? 'reservedInHtml'
133
+ : RESERVED_NAMES_IN_VUE . has ( name ) ? 'reservedInVue'
134
+ : RESERVED_NAMES_IN_VUE3 . has ( name ) ? 'reservedInVue3' : 'reserved' ,
82
135
data : {
83
136
name : name
84
137
}
@@ -98,7 +151,7 @@ module.exports = {
98
151
utils . executeOnVue ( context , ( obj ) => {
99
152
// Report if a component has been registered locally with a reserved name.
100
153
utils . getRegisteredComponents ( obj )
101
- . filter ( ( { name } ) => RESERVED_NAMES . has ( name ) )
154
+ . filter ( ( { name } ) => reservedNames . has ( name ) )
102
155
. forEach ( ( { node, name } ) => report ( node , name ) )
103
156
104
157
const node = obj . properties
0 commit comments