Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bed816b

Browse files
waynzhFloEdelmann
andauthored
feat: add restricted-component-names rule (#2611)
Co-authored-by: Flo Edelmann <git@flo-edelmann.de>
1 parent 9ddf3e5 commit bed816b

File tree

6 files changed

+230
-0
lines changed

6 files changed

+230
-0
lines changed

‎docs/rules/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ For example:
281281
| [vue/require-prop-comment](./require-prop-comment.md) | require props to have a comment | | :hammer: |
282282
| [vue/require-typed-object-prop](./require-typed-object-prop.md) | enforce adding type declarations to object props | :bulb: | :hammer: |
283283
| [vue/require-typed-ref](./require-typed-ref.md) | require `ref` and `shallowRef` functions to be strongly typed | | :hammer: |
284+
| [vue/restricted-component-names](./restricted-component-names.md) | enforce using only specific in component names | | :warning: |
284285
| [vue/script-indent](./script-indent.md) | enforce consistent indentation in `<script>` | :wrench: | :lipstick: |
285286
| [vue/sort-keys](./sort-keys.md) | enforce sort-keys in a manner that is compatible with order-in-components | | :hammer: |
286287
| [vue/static-class-names-order](./static-class-names-order.md) | enforce static class names order | :wrench: | :hammer: |

‎docs/rules/no-restricted-component-names.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ export default {
8484

8585
</eslint-code-block>
8686

87+
## :couple: Related Rules
88+
89+
- [vue/restricted-component-names](./restricted-component-names.md)
90+
8791
## :rocket: Version
8892

8993
This rule was introduced in eslint-plugin-vue v9.15.0
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/restricted-component-names
5+
description: enforce using only specific in component names
6+
---
7+
8+
# vue/restricted-component-names
9+
10+
> enforce using only specific in component names
11+
12+
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> _**This rule has not been released yet.**_ </badge>
13+
14+
## :book: Rule Details
15+
16+
This rule enforces consistency in component names.
17+
18+
<eslint-code-block :rules="{ 'vue/restricted-component-names': ['error'] }">
19+
20+
```vue
21+
<template>
22+
<!-- ✓ GOOD -->
23+
<button/>
24+
<keep-alive></keep-alive>
25+
26+
<!-- ✗ BAD -->
27+
<custom-component />
28+
</template>
29+
```
30+
31+
</eslint-code-block>
32+
33+
## :wrench: Options
34+
35+
```json
36+
{
37+
"vue/restricted-component-names": ["error", {
38+
"allow": []
39+
}]
40+
}
41+
```
42+
43+
### `"allow"`
44+
45+
<eslint-code-block :rules="{'vue/restricted-component-names': ['error', { 'allow': ['/^custom-/'] }]}">
46+
47+
```vue
48+
<template>
49+
<!-- ✓ GOOD -->
50+
<custom-component />
51+
52+
<!-- ✗ BAD -->
53+
<my-component />
54+
</template>
55+
```
56+
57+
</eslint-code-block>
58+
59+
## :couple: Related Rules
60+
61+
- [vue/no-restricted-component-names](./no-restricted-component-names.md)
62+
63+
## :mag: Implementation
64+
65+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/restricted-component-names.js)
66+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/restricted-component-names.js)

‎lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ const plugin = {
231231
'require-typed-ref': require('./rules/require-typed-ref'),
232232
'require-v-for-key': require('./rules/require-v-for-key'),
233233
'require-valid-default-prop': require('./rules/require-valid-default-prop'),
234+
'restricted-component-names': require('./rules/restricted-component-names'),
234235
'return-in-computed-property': require('./rules/return-in-computed-property'),
235236
'return-in-emits-validator': require('./rules/return-in-emits-validator'),
236237
'script-indent': require('./rules/script-indent'),

‎lib/rules/restricted-component-names.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @author Wayne Zhang
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
const utils = require('../utils')
8+
const { toRegExp } = require('../utils/regexp')
9+
10+
const htmlElements = require('../utils/html-elements.json')
11+
const deprecatedHtmlElements = require('../utils/deprecated-html-elements.json')
12+
const svgElements = require('../utils/svg-elements.json')
13+
const vue2builtinComponents = require('../utils/vue2-builtin-components')
14+
const vue3builtinComponents = require('../utils/vue3-builtin-components')
15+
16+
const reservedNames = new Set([
17+
...htmlElements,
18+
...deprecatedHtmlElements,
19+
...svgElements,
20+
...vue2builtinComponents,
21+
...vue3builtinComponents
22+
])
23+
24+
module.exports = {
25+
meta: {
26+
type: 'problem',
27+
docs: {
28+
description: 'enforce using only specific component names',
29+
categories: undefined,
30+
url: 'https://eslint.vuejs.org/rules/restricted-component-names.html'
31+
},
32+
fixable: null,
33+
schema: [
34+
{
35+
type: 'object',
36+
additionalProperties: false,
37+
properties: {
38+
allow: {
39+
type: 'array',
40+
items: { type: 'string' },
41+
uniqueItems: true,
42+
additionalItems: false
43+
}
44+
}
45+
}
46+
],
47+
messages: {
48+
invalidName: 'Component name "{{name}}" is not allowed.'
49+
}
50+
},
51+
/** @param {RuleContext} context */
52+
create(context) {
53+
const options = context.options[0] || {}
54+
/** @type {RegExp[]} */
55+
const allow = (options.allow || []).map(toRegExp)
56+
57+
/** @param {string} name */
58+
function isAllowedTarget(name) {
59+
return reservedNames.has(name) || allow.some((re) => re.test(name))
60+
}
61+
62+
return utils.defineTemplateBodyVisitor(context, {
63+
VElement(node) {
64+
const name = node.rawName
65+
if (isAllowedTarget(name)) {
66+
return
67+
}
68+
69+
context.report({
70+
node,
71+
loc: node.loc,
72+
messageId: 'invalidName',
73+
data: {
74+
name
75+
}
76+
})
77+
}
78+
})
79+
}
80+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @author Wayne Zhang
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
const RuleTester = require('../../eslint-compat').RuleTester
8+
const rule = require('../../../lib/rules/restricted-component-names')
9+
10+
const tester = new RuleTester({
11+
languageOptions: {
12+
parser: require('vue-eslint-parser'),
13+
ecmaVersion: 2020,
14+
sourceType: 'module'
15+
}
16+
})
17+
18+
tester.run('restricted-component-names', rule, {
19+
valid: [
20+
'<template><keep-alive></keep-alive></template>',
21+
'<template><button/></template>',
22+
{
23+
filename: 'test.vue',
24+
code: `
25+
<template>
26+
<foo-button/>
27+
<div-bar/>
28+
</template>
29+
`,
30+
options: [{ allow: ['/^foo-/', '/-bar$/'] }]
31+
}
32+
],
33+
invalid: [
34+
{
35+
filename: 'test.vue',
36+
code: `
37+
<template>
38+
<Button/>
39+
<foo-button/>
40+
</template>
41+
`,
42+
errors: [
43+
{
44+
messageId: 'invalidName',
45+
data: { name: 'Button' },
46+
line: 3
47+
},
48+
{
49+
messageId: 'invalidName',
50+
data: { name: 'foo-button' },
51+
line: 4
52+
}
53+
]
54+
},
55+
{
56+
filename: 'test.vue',
57+
code: `
58+
<template>
59+
<bar-button/>
60+
<foo/>
61+
</template>
62+
`,
63+
options: [{ allow: ['/^foo-/', 'bar'] }],
64+
errors: [
65+
{
66+
messageId: 'invalidName',
67+
data: { name: 'bar-button' },
68+
line: 3
69+
},
70+
{
71+
messageId: 'invalidName',
72+
data: { name: 'foo' },
73+
line: 4
74+
}
75+
]
76+
}
77+
]
78+
})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /