Skip to content

Commit 227ff77

Browse files
armano2ota-meshi
authored andcommitted
Add component-definition-name-casing rule. (#646)
1 parent c360057 commit 227ff77

5 files changed

+501
-0
lines changed

Diff for: docs/rules/component-definition-name-casing.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# enforce specific casing for component definition name (vue/component-definition-name-casing)
2+
3+
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
4+
5+
Define a style for component definition name casing for consistency purposes.
6+
7+
## :book: Rule Details
8+
9+
:+1: Examples of **correct** code for `PascalCase`:
10+
11+
```js
12+
export default {
13+
name: 'MyComponent'
14+
}
15+
```
16+
```js
17+
Vue.component('MyComponent', {
18+
19+
})
20+
```
21+
22+
:+1: Examples of **correct** code for `kebab-case`:
23+
24+
```js
25+
export default {
26+
name: 'my-component'
27+
}
28+
```
29+
```js
30+
Vue.component('my-component', {
31+
32+
})
33+
```
34+
35+
## :wrench: Options
36+
37+
Default casing is set to `PascalCase`.
38+
39+
```json
40+
{
41+
"vue/component-definition-name-casing": ["error", "PascalCase|kebab-case"]
42+
}
43+
```
44+
45+
## Related links
46+
47+
- [Style guide - Component name casing in JS/JSX](https://vuejs.org/v2/style-guide/#Component-name-casing-in-JS-JSX-strongly-recommended)

Diff for: docs/rules/name-property-casing.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ description: enforce specific casing for the name property in Vue components
99
1010
- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
1111
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
12+
- :warning: This rule was **deprecated** and replaced by [vue/component-definition-name-casing](component-definition-name-casing.md) rule.
1213

1314
## :book: Rule Details
1415

Diff for: lib/rules/component-definition-name-casing.js

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* @fileoverview enforce specific casing for component definition name
3+
* @author Armano
4+
*/
5+
'use strict'
6+
7+
const utils = require('../utils')
8+
const casing = require('../utils/casing')
9+
const allowedCaseOptions = ['PascalCase', 'kebab-case']
10+
11+
// ------------------------------------------------------------------------------
12+
// Rule Definition
13+
// ------------------------------------------------------------------------------
14+
15+
module.exports = {
16+
meta: {
17+
type: 'suggestion',
18+
docs: {
19+
description: 'enforce specific casing for component definition name',
20+
category: undefined,
21+
url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v5.0.0-beta.5/docs/rules/component-definition-name-casing.md'
22+
},
23+
fixable: 'code', // or "code" or "whitespace"
24+
schema: [
25+
{
26+
enum: allowedCaseOptions
27+
}
28+
]
29+
},
30+
31+
create (context) {
32+
const options = context.options[0]
33+
const caseType = allowedCaseOptions.indexOf(options) !== -1 ? options : 'PascalCase'
34+
35+
// ----------------------------------------------------------------------
36+
// Public
37+
// ----------------------------------------------------------------------
38+
39+
function convertName (node) {
40+
let nodeValue
41+
let range
42+
if (node.type === 'TemplateLiteral') {
43+
const quasis = node.quasis[0]
44+
nodeValue = quasis.value.cooked
45+
range = quasis.range
46+
} else {
47+
nodeValue = node.value
48+
range = node.range
49+
}
50+
51+
const value = casing.getConverter(caseType)(nodeValue)
52+
if (value !== nodeValue) {
53+
context.report({
54+
node: node,
55+
message: 'Property name "{{value}}" is not {{caseType}}.',
56+
data: {
57+
value: nodeValue,
58+
caseType: caseType
59+
},
60+
fix: fixer => fixer.replaceTextRange([range[0] + 1, range[1] - 1], value)
61+
})
62+
}
63+
}
64+
65+
function canConvert (node) {
66+
return node.type === 'Literal' || (
67+
node.type === 'TemplateLiteral' &&
68+
node.expressions.length === 0 &&
69+
node.quasis.length === 1
70+
)
71+
}
72+
73+
return Object.assign({},
74+
{
75+
"CallExpression > MemberExpression > Identifier[name='component']" (node) {
76+
const parent = node.parent.parent
77+
const calleeObject = utils.unwrapTypes(parent.callee.object)
78+
79+
if (calleeObject.type === 'Identifier' && calleeObject.name === 'Vue') {
80+
if (parent.arguments && parent.arguments.length === 2) {
81+
const argument = parent.arguments[0]
82+
if (canConvert(argument)) {
83+
convertName(argument)
84+
}
85+
}
86+
}
87+
}
88+
},
89+
utils.executeOnVue(context, (obj) => {
90+
const node = obj.properties
91+
.find(item => (
92+
item.type === 'Property' &&
93+
item.key.name === 'name' &&
94+
canConvert(item.value)
95+
))
96+
97+
if (!node) return
98+
convertName(node.value)
99+
})
100+
)
101+
}
102+
}

Diff for: lib/rules/name-property-casing.js

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ module.exports = {
2020
category: 'strongly-recommended',
2121
url: 'https://eslint.vuejs.org/rules/name-property-casing.html'
2222
},
23+
deprecated: true,
24+
replacedBy: ['component-definition-name-casing'],
2325
fixable: 'code', // or "code" or "whitespace"
2426
schema: [
2527
{

0 commit comments

Comments
 (0)