From 426f5afe4af8ca0a854616a9918473c5cff73cf2 Mon Sep 17 00:00:00 2001 From: ItMaga Date: Sun, 30 Jun 2024 22:04:48 +0300 Subject: [PATCH 01/11] Add `vue/require-default-export` rule --- docs/rules/index.md | 1 + docs/rules/object-curly-newline.md | 2 +- docs/rules/object-property-newline.md | 2 +- docs/rules/require-default-export.md | 54 +++++++++ lib/configs/flat/vue2-essential.js | 1 + lib/configs/flat/vue3-essential.js | 1 + lib/configs/vue2-essential.js | 1 + lib/configs/vue3-essential.js | 1 + lib/index.js | 1 + lib/rules/require-default-export.js | 47 ++++++++ tests/lib/rules/require-default-export.js | 136 ++++++++++++++++++++++ 11 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 docs/rules/require-default-export.md create mode 100644 lib/rules/require-default-export.js create mode 100644 tests/lib/rules/require-default-export.js diff --git a/docs/rules/index.md b/docs/rules/index.md index e718603f8..bb3fd0a16 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -95,6 +95,7 @@ Rules in this category are enabled for all presets provided by eslint-plugin-vue | [vue/no-watch-after-await](./no-watch-after-await.md) | disallow asynchronously registered `watch` | | :three::hammer: | | [vue/prefer-import-from-vue](./prefer-import-from-vue.md) | enforce import from 'vue' instead of import from '@vue/*' | :wrench: | :three::hammer: | | [vue/require-component-is](./require-component-is.md) | require `v-bind:is` of `` elements | | :three::two::warning: | +| [vue/require-default-export](./require-default-export.md) | require default export | | :three::two::warning: | | [vue/require-prop-type-constructor](./require-prop-type-constructor.md) | require prop type to be a constructor | :wrench: | :three::two::hammer: | | [vue/require-render-return](./require-render-return.md) | enforce render function to always return value | | :three::two::warning: | | [vue/require-slots-as-functions](./require-slots-as-functions.md) | enforce properties of `$slots` to be used as a function | | :three::warning: | diff --git a/docs/rules/object-curly-newline.md b/docs/rules/object-curly-newline.md index c4743c261..f0b0bf677 100644 --- a/docs/rules/object-curly-newline.md +++ b/docs/rules/object-curly-newline.md @@ -36,4 +36,4 @@ This rule was introduced in eslint-plugin-vue v7.0.0 - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/object-curly-newline.js) - [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/object-curly-newline.js) -Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/js/object-curly-newline) +Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/ts/object-curly-newline) diff --git a/docs/rules/object-property-newline.md b/docs/rules/object-property-newline.md index c6e315c08..bfba0c0a2 100644 --- a/docs/rules/object-property-newline.md +++ b/docs/rules/object-property-newline.md @@ -36,4 +36,4 @@ This rule was introduced in eslint-plugin-vue v7.0.0 - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/object-property-newline.js) - [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/object-property-newline.js) -Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/js/object-property-newline) +Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/ts/object-property-newline) diff --git a/docs/rules/require-default-export.md b/docs/rules/require-default-export.md new file mode 100644 index 000000000..7324d10ba --- /dev/null +++ b/docs/rules/require-default-export.md @@ -0,0 +1,54 @@ +--- +pageClass: rule-details +sidebarDepth: 0 +title: vue/require-default-export +description: require default export +--- + +# vue/require-default-export + +> require default export + +- :exclamation: _**This rule has not been released yet.**_ +- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `*.configs["flat/essential"]`, `"plugin:vue/essential"`, `*.configs["flat/vue2-essential"]`, `"plugin:vue/vue3-strongly-recommended"`, `*.configs["flat/strongly-recommended"]`, `"plugin:vue/strongly-recommended"`, `*.configs["flat/vue2-strongly-recommended"]`, `"plugin:vue/vue3-recommended"`, `*.configs["flat/recommended"]`, `"plugin:vue/recommended"` and `*.configs["flat/vue2-recommended"]`. + +## :book: Rule Details + +This rule reports when a Vue component does not have a default export, if the component is not defined as ` +``` + + + + + +```vue + + +``` + + + +## :wrench: Options + +Nothing. + +## :mag: Implementation + +- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-default-export.js) +- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/require-default-export.js) diff --git a/lib/configs/flat/vue2-essential.js b/lib/configs/flat/vue2-essential.js index 1de89dbc8..06b6b4634 100644 --- a/lib/configs/flat/vue2-essential.js +++ b/lib/configs/flat/vue2-essential.js @@ -46,6 +46,7 @@ module.exports = [ 'vue/no-v-model-argument': 'error', 'vue/no-v-text-v-html-on-component': 'error', 'vue/require-component-is': 'error', + 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-v-for-key': 'error', diff --git a/lib/configs/flat/vue3-essential.js b/lib/configs/flat/vue3-essential.js index 595af5f1d..9bcec98b5 100644 --- a/lib/configs/flat/vue3-essential.js +++ b/lib/configs/flat/vue3-essential.js @@ -61,6 +61,7 @@ module.exports = [ 'vue/no-watch-after-await': 'error', 'vue/prefer-import-from-vue': 'error', 'vue/require-component-is': 'error', + 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-slots-as-functions': 'error', diff --git a/lib/configs/vue2-essential.js b/lib/configs/vue2-essential.js index e2c66ceba..1a8ea3429 100644 --- a/lib/configs/vue2-essential.js +++ b/lib/configs/vue2-essential.js @@ -41,6 +41,7 @@ module.exports = { 'vue/no-v-model-argument': 'error', 'vue/no-v-text-v-html-on-component': 'error', 'vue/require-component-is': 'error', + 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-v-for-key': 'error', diff --git a/lib/configs/vue3-essential.js b/lib/configs/vue3-essential.js index f71508f75..47b3a8113 100644 --- a/lib/configs/vue3-essential.js +++ b/lib/configs/vue3-essential.js @@ -56,6 +56,7 @@ module.exports = { 'vue/no-watch-after-await': 'error', 'vue/prefer-import-from-vue': 'error', 'vue/require-component-is': 'error', + 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-slots-as-functions': 'error', diff --git a/lib/index.js b/lib/index.js index 956eeaa4b..f5b0986a8 100644 --- a/lib/index.js +++ b/lib/index.js @@ -208,6 +208,7 @@ const plugin = { 'prop-name-casing': require('./rules/prop-name-casing'), 'quote-props': require('./rules/quote-props'), 'require-component-is': require('./rules/require-component-is'), + 'require-default-export': require('./rules/require-default-export'), 'require-default-prop': require('./rules/require-default-prop'), 'require-direct-export': require('./rules/require-direct-export'), 'require-emit-validator': require('./rules/require-emit-validator'), diff --git a/lib/rules/require-default-export.js b/lib/rules/require-default-export.js new file mode 100644 index 000000000..50f0a1e25 --- /dev/null +++ b/lib/rules/require-default-export.js @@ -0,0 +1,47 @@ +/** + * @author ItMaga + * See LICENSE file in root directory for full license. + */ +'use strict' + +const utils = require('../utils') + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'require default export', + categories: ['vue3-essential', 'vue2-essential'], + url: 'https://eslint.vuejs.org/rules/require-default-export.html' + }, + fixable: null, + schema: [], + messages: { + missing: 'Missing default export.' + } + }, + /** @param {RuleContext} context */ + create(context) { + if (utils.isScriptSetup(context)) { + return {} + } + + return { + /** + * @param {Program} node + */ + 'Program:exit'(node) { + const hasDefaultExport = node.body.some( + (item) => item.type === 'ExportDefaultDeclaration' + ) + + if (!hasDefaultExport) { + context.report({ + loc: { line: 1, column: 0 }, + messageId: 'missing' + }) + } + } + } + } +} diff --git a/tests/lib/rules/require-default-export.js b/tests/lib/rules/require-default-export.js new file mode 100644 index 000000000..2e2c2b3d8 --- /dev/null +++ b/tests/lib/rules/require-default-export.js @@ -0,0 +1,136 @@ +/** + * @author ItMaga + * See LICENSE file in root directory for full license. + */ +'use strict' + +const RuleTester = require('../../eslint-compat').RuleTester +const rule = require('../../../lib/rules/require-default-export') + +const tester = new RuleTester({ + languageOptions: { + parser: require('vue-eslint-parser'), + ecmaVersion: 2020, + sourceType: 'module' + } +}) + +tester.run('require-default-export', rule, { + valid: [ + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + } + ], + invalid: [ + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'missing', + line: 1 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'missing', + line: 1 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'missing', + line: 1 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'missing', + line: 1 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'missing', + line: 1 + } + ] + } + ] +}) From 2daebd6ed0d6a675856219688e952e6981ccec9e Mon Sep 17 00:00:00 2001 From: ItMaga Date: Sun, 30 Jun 2024 23:29:23 +0300 Subject: [PATCH 02/11] fix: without script and jsx --- lib/rules/require-default-export.js | 23 +++++++++++++++++------ tests/lib/rules/require-default-export.js | 6 ++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/rules/require-default-export.js b/lib/rules/require-default-export.js index 50f0a1e25..163bb6990 100644 --- a/lib/rules/require-default-export.js +++ b/lib/rules/require-default-export.js @@ -22,20 +22,31 @@ module.exports = { }, /** @param {RuleContext} context */ create(context) { - if (utils.isScriptSetup(context)) { + const sourceCode = context.getSourceCode() + const documentFragment = sourceCode.parserServices.getDocumentFragment?.() + + const hasScript = + documentFragment && + documentFragment.children.some( + (e) => utils.isVElement(e) && e.name === 'script' + ) + + if (utils.isScriptSetup(context) || !hasScript) { return {} } + let hasDefaultExport = false + return { + 'Program > ExportDefaultDeclaration'() { + hasDefaultExport = true + }, + /** * @param {Program} node */ 'Program:exit'(node) { - const hasDefaultExport = node.body.some( - (item) => item.type === 'ExportDefaultDeclaration' - ) - - if (!hasDefaultExport) { + if (!hasDefaultExport && node.body.length > 0) { context.report({ loc: { line: 1, column: 0 }, messageId: 'missing' diff --git a/tests/lib/rules/require-default-export.js b/tests/lib/rules/require-default-export.js index 2e2c2b3d8..d268a19ac 100644 --- a/tests/lib/rules/require-default-export.js +++ b/tests/lib/rules/require-default-export.js @@ -17,6 +17,12 @@ const tester = new RuleTester({ tester.run('require-default-export', rule, { valid: [ + { + filename: 'test.vue', + code: ` + + ` + }, { filename: 'test.vue', code: ` From 3f5f4b402cda3ebf57a4c43f8b5756359a913a87 Mon Sep 17 00:00:00 2001 From: ItMaga Date: Sat, 6 Jul 2024 18:40:46 +0300 Subject: [PATCH 03/11] docs: add related rules and revert non-relevant changes --- docs/rules/object-curly-newline.md | 2 +- docs/rules/object-property-newline.md | 2 +- docs/rules/require-default-export.md | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/rules/object-curly-newline.md b/docs/rules/object-curly-newline.md index f0b0bf677..c4743c261 100644 --- a/docs/rules/object-curly-newline.md +++ b/docs/rules/object-curly-newline.md @@ -36,4 +36,4 @@ This rule was introduced in eslint-plugin-vue v7.0.0 - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/object-curly-newline.js) - [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/object-curly-newline.js) -Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/ts/object-curly-newline) +Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/js/object-curly-newline) diff --git a/docs/rules/object-property-newline.md b/docs/rules/object-property-newline.md index bfba0c0a2..c6e315c08 100644 --- a/docs/rules/object-property-newline.md +++ b/docs/rules/object-property-newline.md @@ -36,4 +36,4 @@ This rule was introduced in eslint-plugin-vue v7.0.0 - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/object-property-newline.js) - [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/object-property-newline.js) -Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/ts/object-property-newline) +Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/js/object-property-newline) diff --git a/docs/rules/require-default-export.md b/docs/rules/require-default-export.md index 7324d10ba..1760c25fa 100644 --- a/docs/rules/require-default-export.md +++ b/docs/rules/require-default-export.md @@ -2,15 +2,14 @@ pageClass: rule-details sidebarDepth: 0 title: vue/require-default-export -description: require default export +description: require components to be the default export --- # vue/require-default-export -> require default export +> require components to be the default export - :exclamation: _**This rule has not been released yet.**_ -- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `*.configs["flat/essential"]`, `"plugin:vue/essential"`, `*.configs["flat/vue2-essential"]`, `"plugin:vue/vue3-strongly-recommended"`, `*.configs["flat/strongly-recommended"]`, `"plugin:vue/strongly-recommended"`, `*.configs["flat/vue2-strongly-recommended"]`, `"plugin:vue/vue3-recommended"`, `*.configs["flat/recommended"]`, `"plugin:vue/recommended"` and `*.configs["flat/vue2-recommended"]`. ## :book: Rule Details @@ -48,6 +47,10 @@ export default { Nothing. +## :couple: Related Rules + +- [vue/one-component-per-file](./one-component-per-file.md) + ## :mag: Implementation - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-default-export.js) From dd353c2599a7ea7bc20de04e64f8a76cfef6c14d Mon Sep 17 00:00:00 2001 From: ItMaga Date: Sat, 6 Jul 2024 18:41:18 +0300 Subject: [PATCH 04/11] feat: revert categories and update description --- docs/rules/index.md | 2 +- lib/configs/flat/vue2-essential.js | 1 - lib/configs/flat/vue3-essential.js | 1 - lib/configs/vue2-essential.js | 1 - lib/configs/vue3-essential.js | 1 - lib/rules/require-default-export.js | 4 ++-- 6 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/rules/index.md b/docs/rules/index.md index bb3fd0a16..64bd7b81d 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -95,7 +95,6 @@ Rules in this category are enabled for all presets provided by eslint-plugin-vue | [vue/no-watch-after-await](./no-watch-after-await.md) | disallow asynchronously registered `watch` | | :three::hammer: | | [vue/prefer-import-from-vue](./prefer-import-from-vue.md) | enforce import from 'vue' instead of import from '@vue/*' | :wrench: | :three::hammer: | | [vue/require-component-is](./require-component-is.md) | require `v-bind:is` of `` elements | | :three::two::warning: | -| [vue/require-default-export](./require-default-export.md) | require default export | | :three::two::warning: | | [vue/require-prop-type-constructor](./require-prop-type-constructor.md) | require prop type to be a constructor | :wrench: | :three::two::hammer: | | [vue/require-render-return](./require-render-return.md) | enforce render function to always return value | | :three::two::warning: | | [vue/require-slots-as-functions](./require-slots-as-functions.md) | enforce properties of `$slots` to be used as a function | | :three::warning: | @@ -268,6 +267,7 @@ For example: | [vue/prefer-prop-type-boolean-first](./prefer-prop-type-boolean-first.md) | enforce `Boolean` comes first in component prop types | :bulb: | :warning: | | [vue/prefer-separate-static-class](./prefer-separate-static-class.md) | require static class names in template to be in a separate `class` attribute | :wrench: | :hammer: | | [vue/prefer-true-attribute-shorthand](./prefer-true-attribute-shorthand.md) | require shorthand form attribute when `v-bind` value is `true` | :bulb: | :hammer: | +| [vue/require-default-export](./require-default-export.md) | require components to be the default export | | :warning: | | [vue/require-direct-export](./require-direct-export.md) | require the component to be directly exported | | :hammer: | | [vue/require-emit-validator](./require-emit-validator.md) | require type definitions in emits | :bulb: | :hammer: | | [vue/require-explicit-slots](./require-explicit-slots.md) | require slots to be explicitly defined | | :warning: | diff --git a/lib/configs/flat/vue2-essential.js b/lib/configs/flat/vue2-essential.js index 06b6b4634..1de89dbc8 100644 --- a/lib/configs/flat/vue2-essential.js +++ b/lib/configs/flat/vue2-essential.js @@ -46,7 +46,6 @@ module.exports = [ 'vue/no-v-model-argument': 'error', 'vue/no-v-text-v-html-on-component': 'error', 'vue/require-component-is': 'error', - 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-v-for-key': 'error', diff --git a/lib/configs/flat/vue3-essential.js b/lib/configs/flat/vue3-essential.js index 9bcec98b5..595af5f1d 100644 --- a/lib/configs/flat/vue3-essential.js +++ b/lib/configs/flat/vue3-essential.js @@ -61,7 +61,6 @@ module.exports = [ 'vue/no-watch-after-await': 'error', 'vue/prefer-import-from-vue': 'error', 'vue/require-component-is': 'error', - 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-slots-as-functions': 'error', diff --git a/lib/configs/vue2-essential.js b/lib/configs/vue2-essential.js index 1a8ea3429..e2c66ceba 100644 --- a/lib/configs/vue2-essential.js +++ b/lib/configs/vue2-essential.js @@ -41,7 +41,6 @@ module.exports = { 'vue/no-v-model-argument': 'error', 'vue/no-v-text-v-html-on-component': 'error', 'vue/require-component-is': 'error', - 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-v-for-key': 'error', diff --git a/lib/configs/vue3-essential.js b/lib/configs/vue3-essential.js index 47b3a8113..f71508f75 100644 --- a/lib/configs/vue3-essential.js +++ b/lib/configs/vue3-essential.js @@ -56,7 +56,6 @@ module.exports = { 'vue/no-watch-after-await': 'error', 'vue/prefer-import-from-vue': 'error', 'vue/require-component-is': 'error', - 'vue/require-default-export': 'error', 'vue/require-prop-type-constructor': 'error', 'vue/require-render-return': 'error', 'vue/require-slots-as-functions': 'error', diff --git a/lib/rules/require-default-export.js b/lib/rules/require-default-export.js index 163bb6990..24d2fc433 100644 --- a/lib/rules/require-default-export.js +++ b/lib/rules/require-default-export.js @@ -10,8 +10,8 @@ module.exports = { meta: { type: 'problem', docs: { - description: 'require default export', - categories: ['vue3-essential', 'vue2-essential'], + description: 'require components to be the default export', + categories: undefined, url: 'https://eslint.vuejs.org/rules/require-default-export.html' }, fixable: null, From 77f112642480065555d7f37bc732320e18a54feb Mon Sep 17 00:00:00 2001 From: ItMaga Date: Sat, 6 Jul 2024 18:41:34 +0300 Subject: [PATCH 05/11] feat: add test suites --- tests/lib/rules/require-default-export.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/lib/rules/require-default-export.js b/tests/lib/rules/require-default-export.js index d268a19ac..088ad09ea 100644 --- a/tests/lib/rules/require-default-export.js +++ b/tests/lib/rules/require-default-export.js @@ -60,6 +60,20 @@ tester.run('require-default-export', rule, { export default defineComponent({}); ` + }, + { + filename: 'test.js', + code: ` + const foo = 'foo'; + export const bar = 'bar'; + ` + }, + { + filename: 'test.js', + code: ` + import {defineComponent} from 'vue'; + defineComponent({}); + ` } ], invalid: [ From 7f986443f1b9258bc9d19c0c49f51db89ed6e841 Mon Sep 17 00:00:00 2001 From: ItMaga Date: Sat, 6 Jul 2024 18:51:07 +0300 Subject: [PATCH 06/11] refactor: improve error message --- lib/rules/require-default-export.js | 4 ++-- tests/lib/rules/require-default-export.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/rules/require-default-export.js b/lib/rules/require-default-export.js index 24d2fc433..4053f16bf 100644 --- a/lib/rules/require-default-export.js +++ b/lib/rules/require-default-export.js @@ -17,7 +17,7 @@ module.exports = { fixable: null, schema: [], messages: { - missing: 'Missing default export.' + mustDefaultExport: 'The component must be the default export.' } }, /** @param {RuleContext} context */ @@ -49,7 +49,7 @@ module.exports = { if (!hasDefaultExport && node.body.length > 0) { context.report({ loc: { line: 1, column: 0 }, - messageId: 'missing' + messageId: 'mustDefaultExport' }) } } diff --git a/tests/lib/rules/require-default-export.js b/tests/lib/rules/require-default-export.js index 088ad09ea..438f057ee 100644 --- a/tests/lib/rules/require-default-export.js +++ b/tests/lib/rules/require-default-export.js @@ -86,7 +86,7 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'missing', + messageId: 'mustDefaultExport', line: 1 } ] @@ -100,7 +100,7 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'missing', + messageId: 'mustDefaultExport', line: 1 } ] @@ -116,7 +116,7 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'missing', + messageId: 'mustDefaultExport', line: 1 } ] @@ -131,7 +131,7 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'missing', + messageId: 'mustDefaultExport', line: 1 } ] @@ -147,7 +147,7 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'missing', + messageId: 'mustDefaultExport', line: 1 } ] From 73e00c8e51cd32e384282933ec73d28c14ae3876 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Mon, 8 Jul 2024 09:23:44 +0200 Subject: [PATCH 07/11] Discard changes to docs/rules/object-curly-newline.md --- docs/rules/object-curly-newline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/object-curly-newline.md b/docs/rules/object-curly-newline.md index c4743c261..f0b0bf677 100644 --- a/docs/rules/object-curly-newline.md +++ b/docs/rules/object-curly-newline.md @@ -36,4 +36,4 @@ This rule was introduced in eslint-plugin-vue v7.0.0 - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/object-curly-newline.js) - [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/object-curly-newline.js) -Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/js/object-curly-newline) +Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/ts/object-curly-newline) From b42646ab745bc587dc870a9ca747bf00ac28a5a3 Mon Sep 17 00:00:00 2001 From: Flo Edelmann Date: Mon, 8 Jul 2024 09:23:48 +0200 Subject: [PATCH 08/11] Discard changes to docs/rules/object-property-newline.md --- docs/rules/object-property-newline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/object-property-newline.md b/docs/rules/object-property-newline.md index c6e315c08..bfba0c0a2 100644 --- a/docs/rules/object-property-newline.md +++ b/docs/rules/object-property-newline.md @@ -36,4 +36,4 @@ This rule was introduced in eslint-plugin-vue v7.0.0 - [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/object-property-newline.js) - [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/object-property-newline.js) -Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/js/object-property-newline) +Taken with ❤️ [from ESLint Stylistic](https://eslint.style/rules/ts/object-property-newline) From 4a66d2e993195df3d9de075e3061855302402f6b Mon Sep 17 00:00:00 2001 From: ItMaga Date: Wed, 10 Jul 2024 16:59:32 +0300 Subject: [PATCH 09/11] feat: improve messages and accurate loc --- lib/rules/require-default-export.js | 42 +++++++++++------- tests/lib/rules/require-default-export.js | 54 ++++++++++++++++++----- 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/lib/rules/require-default-export.js b/lib/rules/require-default-export.js index 4053f16bf..5c5402008 100644 --- a/lib/rules/require-default-export.js +++ b/lib/rules/require-default-export.js @@ -17,7 +17,8 @@ module.exports = { fixable: null, schema: [], messages: { - mustDefaultExport: 'The component must be the default export.' + missing: 'Missing default export.', + mustBeDefaultExport: 'Component must be the default export.' } }, /** @param {RuleContext} context */ @@ -36,23 +37,32 @@ module.exports = { } let hasDefaultExport = false + let hasDefinedComponent = false - return { - 'Program > ExportDefaultDeclaration'() { - hasDefaultExport = true - }, - - /** - * @param {Program} node - */ - 'Program:exit'(node) { - if (!hasDefaultExport && node.body.length > 0) { - context.report({ - loc: { line: 1, column: 0 }, - messageId: 'mustDefaultExport' - }) + return utils.compositingVisitors( + utils.defineVueVisitor(context, { + onVueObjectExit() { + hasDefinedComponent = true + } + }), + + { + 'Program > ExportDefaultDeclaration'() { + hasDefaultExport = true + }, + + /** + * @param {Program} node + */ + 'Program:exit'(node) { + if (!hasDefaultExport && node.body.length > 0) { + context.report({ + loc: node.tokens[node.tokens.length - 1].loc, + messageId: hasDefinedComponent ? 'mustBeDefaultExport' : 'missing' + }) + } } } - } + ) } } diff --git a/tests/lib/rules/require-default-export.js b/tests/lib/rules/require-default-export.js index 438f057ee..279af4a38 100644 --- a/tests/lib/rules/require-default-export.js +++ b/tests/lib/rules/require-default-export.js @@ -86,8 +86,11 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'mustDefaultExport', - line: 1 + messageId: 'missing', + line: 4, + endLine: 4, + column: 7, + endColumn: 16 } ] }, @@ -100,8 +103,11 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'mustDefaultExport', - line: 1 + messageId: 'missing', + line: 4, + endLine: 4, + column: 7, + endColumn: 16 } ] }, @@ -116,8 +122,11 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'mustDefaultExport', - line: 1 + messageId: 'missing', + line: 6, + endLine: 6, + column: 7, + endColumn: 16 } ] }, @@ -131,8 +140,11 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'mustDefaultExport', - line: 1 + messageId: 'missing', + line: 5, + endLine: 5, + column: 7, + endColumn: 16 } ] }, @@ -147,8 +159,30 @@ tester.run('require-default-export', rule, { `, errors: [ { - messageId: 'mustDefaultExport', - line: 1 + messageId: 'mustBeDefaultExport', + line: 6, + endLine: 6, + column: 7, + endColumn: 16 + } + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'mustBeDefaultExport', + line: 6, + endLine: 6, + column: 7, + endColumn: 16 } ] } From c0dd101fcfe59dcd49be01f55254739a211b90a1 Mon Sep 17 00:00:00 2001 From: ItMaga Date: Wed, 10 Jul 2024 17:02:26 +0300 Subject: [PATCH 10/11] docs: add related rule to one-component-per-file --- docs/rules/one-component-per-file.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/rules/one-component-per-file.md b/docs/rules/one-component-per-file.md index 6fbede339..c5e94fbd8 100644 --- a/docs/rules/one-component-per-file.md +++ b/docs/rules/one-component-per-file.md @@ -49,6 +49,11 @@ export default { Nothing. + +## :couple: Related Rules + +- [vue/require-default-export](./require-default-export.md) + ## :books: Further Reading - [Style guide - Component files](https://vuejs.org/style-guide/rules-strongly-recommended.html#component-files) From 1c706a15ebb70487ff120ea4c2375d9f7468042f Mon Sep 17 00:00:00 2001 From: ItMaga Date: Wed, 10 Jul 2024 17:04:55 +0300 Subject: [PATCH 11/11] chore: remove empty line --- docs/rules/one-component-per-file.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/rules/one-component-per-file.md b/docs/rules/one-component-per-file.md index c5e94fbd8..5e6b37518 100644 --- a/docs/rules/one-component-per-file.md +++ b/docs/rules/one-component-per-file.md @@ -49,7 +49,6 @@ export default { Nothing. - ## :couple: Related Rules - [vue/require-default-export](./require-default-export.md) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy