From b91728d97ae787e56feb773b6e72a0fc081b6f26 Mon Sep 17 00:00:00 2001 From: waynzh Date: Sun, 3 Nov 2024 01:26:13 +0800 Subject: [PATCH 1/7] feat(no-reserved-component-names): add case sensitive option --- lib/rules/no-reserved-component-names.js | 58 +++++++++++-------- .../lib/rules/no-reserved-component-names.js | 34 +++++++++++ 2 files changed, 68 insertions(+), 24 deletions(-) diff --git a/lib/rules/no-reserved-component-names.js b/lib/rules/no-reserved-component-names.js index 90e53604f..9b492c372 100644 --- a/lib/rules/no-reserved-component-names.js +++ b/lib/rules/no-reserved-component-names.js @@ -34,19 +34,6 @@ function isLowercase(word) { return /^[a-z]*$/.test(word) } -const RESERVED_NAMES_IN_HTML = new Set([ - ...htmlElements, - ...htmlElements.map(casing.capitalize) -]) -const RESERVED_NAMES_IN_OTHERS = new Set([ - ...deprecatedHtmlElements, - ...deprecatedHtmlElements.map(casing.capitalize), - ...kebabCaseElements, - ...kebabCaseElements.map(casing.pascalCase), - ...svgElements, - ...svgElements.filter(isLowercase).map(casing.capitalize) -]) - /** * @param {Expression | SpreadElement} node * @returns {node is (Literal | TemplateLiteral)} @@ -60,17 +47,6 @@ function canVerify(node) { ) } -/** - * @param {string} name - * @returns {string} - */ -function getMessageId(name) { - if (RESERVED_NAMES_IN_HTML.has(name)) return 'reservedInHtml' - if (RESERVED_NAMES_IN_VUE.has(name)) return 'reservedInVue' - if (RESERVED_NAMES_IN_VUE3.has(name)) return 'reservedInVue3' - return 'reserved' -} - module.exports = { meta: { type: 'suggestion', @@ -90,6 +66,9 @@ module.exports = { }, disallowVue3BuiltInComponents: { type: 'boolean' + }, + htmlElementCaseSensitive: { + type: 'boolean' } }, additionalProperties: false @@ -109,6 +88,26 @@ module.exports = { options.disallowVueBuiltInComponents === true const disallowVue3BuiltInComponents = options.disallowVue3BuiltInComponents === true + const htmlElementCaseSensitive = options.htmlElementCaseSensitive === true + + const RESERVED_NAMES_IN_HTML = new Set([ + ...htmlElements, + ...(htmlElementCaseSensitive ? [] : htmlElements.map(casing.capitalize)) + ]) + const RESERVED_NAMES_IN_OTHERS = new Set([ + ...deprecatedHtmlElements, + ...(htmlElementCaseSensitive + ? [] + : deprecatedHtmlElements.map(casing.capitalize)), + ...kebabCaseElements, + ...(htmlElementCaseSensitive + ? [] + : kebabCaseElements.map(casing.pascalCase)), + ...svgElements, + ...(htmlElementCaseSensitive + ? [] + : svgElements.filter(isLowercase).map(casing.capitalize)) + ]) const reservedNames = new Set([ ...RESERVED_NAMES_IN_HTML, @@ -133,6 +132,17 @@ module.exports = { } } + /** + * @param {string} name + * @returns {string} + */ + function getMessageId(name) { + if (RESERVED_NAMES_IN_HTML.has(name)) return 'reservedInHtml' + if (RESERVED_NAMES_IN_VUE.has(name)) return 'reservedInVue' + if (RESERVED_NAMES_IN_VUE3.has(name)) return 'reservedInVue3' + return 'reserved' + } + /** * @param {ESNode} node * @param {string} name diff --git a/tests/lib/rules/no-reserved-component-names.js b/tests/lib/rules/no-reserved-component-names.js index 41cddcfd5..289e04880 100644 --- a/tests/lib/rules/no-reserved-component-names.js +++ b/tests/lib/rules/no-reserved-component-names.js @@ -410,6 +410,12 @@ const invalidElements = [ 'xmp', 'Xmp' ] +const invalidLowerCaseElements = invalidElements.filter( + (element) => element === element.toLowerCase() +) +const invalidUpperCaseElements = invalidElements.filter( + (element) => element === element.toUpperCase() +) const vue2BuiltInComponents = [ 'component', @@ -559,6 +565,16 @@ ruleTester.run('no-reserved-component-names', rule, { languageOptions, options: [{ disallowVueBuiltInComponents: true }] })), + ...invalidUpperCaseElements.map((name) => ({ + filename: `${name}.vue`, + code: ` + export default { + name: '${name}' + } + `, + languageOptions, + options: [{ htmlElementCaseSensitive: true }] + })), { filename: 'test.vue', code: ``, @@ -701,6 +717,24 @@ ruleTester.run('no-reserved-component-names', rule, { } ] })), + ...invalidLowerCaseElements.map((name) => ({ + filename: `${name}.vue`, + code: ``, + languageOptions: { + parser: require('vue-eslint-parser'), + ...languageOptions + }, + options: [{ htmlElementCaseSensitive: true }], + errors: [ + { + messageId: RESERVED_NAMES_IN_HTML.has(name) + ? 'reservedInHtml' + : 'reserved', + data: { name }, + line: 1 + } + ] + })), ...vue2BuiltInComponents.map((name) => ({ filename: `${name}.vue`, code: ` From e7c45c349950debed802b520e5e8320a69175460 Mon Sep 17 00:00:00 2001 From: waynzh Date: Sun, 3 Nov 2024 01:26:28 +0800 Subject: [PATCH 2/7] feat: update docs --- docs/rules/no-reserved-component-names.md | 32 ++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/rules/no-reserved-component-names.md b/docs/rules/no-reserved-component-names.md index a5d85cde8..480c1c0da 100644 --- a/docs/rules/no-reserved-component-names.md +++ b/docs/rules/no-reserved-component-names.md @@ -35,13 +35,15 @@ export default { { "vue/no-reserved-component-names": ["error", { "disallowVueBuiltInComponents": false, - "disallowVue3BuiltInComponents": false + "disallowVue3BuiltInComponents": false, + "caseSensitive": false, }] } ``` - `disallowVueBuiltInComponents` (`boolean`) ... If `true`, disallow Vue.js 2.x built-in component names. Default is `false`. - `disallowVue3BuiltInComponents` (`boolean`) ... If `true`, disallow Vue.js 3.x built-in component names. Default is `false`. +- `htmlElementCaseSensitive` (`boolean`) ... If `true`, become case-sensitive when comparing component names with HTML reserved elements. Default is `false`. This means that a component name must exactly match the case of an HTML element to be considered conflicting. ### `"disallowVueBuiltInComponents": true` @@ -73,6 +75,34 @@ export default { +### `"htmlElementCaseSensitive": true` + + + +```vue + +``` + + + + + +```vue + +``` + + + ## :couple: Related Rules - [vue/multi-word-component-names](./multi-word-component-names.md) From f3c4dd2c51f12ceb27a1e378444440bf72f70c49 Mon Sep 17 00:00:00 2001 From: waynzh Date: Sun, 3 Nov 2024 01:30:17 +0800 Subject: [PATCH 3/7] feat: update docs --- docs/rules/no-reserved-component-names.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-reserved-component-names.md b/docs/rules/no-reserved-component-names.md index 480c1c0da..074b91d68 100644 --- a/docs/rules/no-reserved-component-names.md +++ b/docs/rules/no-reserved-component-names.md @@ -36,7 +36,7 @@ export default { "vue/no-reserved-component-names": ["error", { "disallowVueBuiltInComponents": false, "disallowVue3BuiltInComponents": false, - "caseSensitive": false, + "htmlElementCaseSensitive": false, }] } ``` From 837ead4339b0298b2c8101736c02c6e2f3bbb2bf Mon Sep 17 00:00:00 2001 From: waynzh Date: Sun, 3 Nov 2024 01:34:05 +0800 Subject: [PATCH 4/7] feat: update docs --- docs/rules/no-reserved-component-names.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-reserved-component-names.md b/docs/rules/no-reserved-component-names.md index 074b91d68..6859cac72 100644 --- a/docs/rules/no-reserved-component-names.md +++ b/docs/rules/no-reserved-component-names.md @@ -81,7 +81,7 @@ export default { ```vue