-
-
Notifications
You must be signed in to change notification settings - Fork 676
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
⭐️ New: Add rule
no-reserved-component-names
(#757)
* ⭐ add rule no-reserved-component-names * Increase test coverage * Checking elements against element lists * 🔨 Update PR with ota-meshi suggestions * 🔨 Lint locally registered components * 👌 Adding tests to validate slot and template * 🔨 Linting for deprecated elements
- Loading branch information
Showing
4 changed files
with
529 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# vue/no-reserved-component-names | ||
> disallow the use of reserved names in component definitions | ||
- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/recommended"`, and `"plugin:vue/strongly-recommended"`. | ||
|
||
## :book: Rule Details | ||
|
||
This rule prevents name collisions between vue components and standard html elements. | ||
|
||
<eslint-code-block :rules="{'vue/no-reserved-component-names': ['error']}"> | ||
|
||
```vue | ||
<script> | ||
/* ✗ BAD */ | ||
export default { | ||
name: 'div' | ||
} | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :books: Further reading | ||
|
||
- [List of html elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) | ||
- [List of SVG elements](https://developer.mozilla.org/en-US/docs/Web/SVG/Element) | ||
- [Kebab case elements](https://stackoverflow.com/questions/22545621/do-custom-elements-require-a-dash-in-their-name/22545622#22545622) | ||
- [Valid custom element name](https://w3c.github.io/webcomponents/spec/custom/#valid-custom-element-name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/** | ||
* @fileoverview disallow the use of reserved names in component definitions | ||
* @author Jake Hassel <https://github.com/shadskii> | ||
*/ | ||
'use strict' | ||
|
||
const utils = require('../utils') | ||
const casing = require('../utils/casing') | ||
|
||
const htmlElements = require('../utils/html-elements.json') | ||
const deprecatedHtmlElements = require('../utils/deprecated-html-elements.json') | ||
const svgElements = require('../utils/svg-elements.json') | ||
|
||
const kebabCaseElements = [ | ||
'annotation-xml', | ||
'color-profile', | ||
'font-face', | ||
'font-face-src', | ||
'font-face-uri', | ||
'font-face-format', | ||
'font-face-name', | ||
'missing-glyph' | ||
] | ||
|
||
const isLowercase = (word) => /^[a-z]*$/.test(word) | ||
const capitalizeFirstLetter = (word) => word[0].toUpperCase() + word.substring(1, word.length) | ||
|
||
const RESERVED_NAMES = new Set( | ||
[ | ||
...kebabCaseElements, | ||
...kebabCaseElements.map(casing.pascalCase), | ||
...htmlElements, | ||
...htmlElements.map(capitalizeFirstLetter), | ||
...deprecatedHtmlElements, | ||
...deprecatedHtmlElements.map(capitalizeFirstLetter), | ||
...svgElements, | ||
...svgElements.filter(isLowercase).map(capitalizeFirstLetter) | ||
]) | ||
|
||
// ------------------------------------------------------------------------------ | ||
// Rule Definition | ||
// ------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: { | ||
type: 'suggestion', | ||
docs: { | ||
description: 'disallow the use of reserved names in component definitions', | ||
category: undefined, // 'essential' | ||
url: 'https://eslint.vuejs.org/rules/no-reserved-component-names.html' | ||
}, | ||
fixable: null, | ||
schema: [] | ||
}, | ||
|
||
create (context) { | ||
function canVerify (node) { | ||
return node.type === 'Literal' || ( | ||
node.type === 'TemplateLiteral' && | ||
node.expressions.length === 0 && | ||
node.quasis.length === 1 | ||
) | ||
} | ||
|
||
function reportIfInvalid (node) { | ||
let name | ||
if (node.type === 'TemplateLiteral') { | ||
const quasis = node.quasis[0] | ||
name = quasis.value.cooked | ||
} else { | ||
name = node.value | ||
} | ||
if (RESERVED_NAMES.has(name)) { | ||
report(node, name) | ||
} | ||
} | ||
|
||
function report (node, name) { | ||
context.report({ | ||
node: node, | ||
message: 'Name "{{name}}" is reserved.', | ||
data: { | ||
name: name | ||
} | ||
}) | ||
} | ||
|
||
return Object.assign({}, | ||
{ | ||
"CallExpression > MemberExpression > Identifier[name='component']" (node) { | ||
const parent = node.parent.parent | ||
const calleeObject = utils.unwrapTypes(parent.callee.object) | ||
|
||
if (calleeObject.type === 'Identifier' && | ||
calleeObject.name === 'Vue' && | ||
parent.arguments && | ||
parent.arguments.length === 2 | ||
) { | ||
const argument = parent.arguments[0] | ||
|
||
if (canVerify(argument)) { | ||
reportIfInvalid(argument) | ||
} | ||
} | ||
} | ||
}, | ||
utils.executeOnVue(context, (obj) => { | ||
// Report if a component has been registered locally with a reserved name. | ||
utils.getRegisteredComponents(obj) | ||
.filter(({ name }) => RESERVED_NAMES.has(name)) | ||
.forEach(({ node, name }) => report(node, name)) | ||
|
||
const node = obj.properties | ||
.find(item => ( | ||
item.type === 'Property' && | ||
item.key.name === 'name' && | ||
canVerify(item.value) | ||
)) | ||
|
||
if (!node) return | ||
reportIfInvalid(node.value) | ||
}) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
["acronym","applet","basefont","bgsound","big","blink","center","command","content","dir","element","font","frame","frameset","image","isindex","keygen","listing","marquee","menuitem","multicol","nextid","nobr","noembed","noframes","plaintext","shadow","spacer","strike","tt","xmp"] |
Oops, something went wrong.