File tree Expand file tree Collapse file tree 6 files changed +321
-0
lines changed Expand file tree Collapse file tree 6 files changed +321
-0
lines changed Original file line number Diff line number Diff line change @@ -268,6 +268,7 @@ For example:
268268| [ vue/prefer-prop-type-boolean-first] ( ./prefer-prop-type-boolean-first.md ) | enforce ` Boolean ` comes first in component prop types | :bulb : | :warning : |
269269| [ 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 : |
270270| [ vue/prefer-true-attribute-shorthand] ( ./prefer-true-attribute-shorthand.md ) | require shorthand form attribute when ` v-bind ` value is ` true ` | :bulb : | :hammer : |
271+ | [ vue/require-default-export] ( ./require-default-export.md ) | require components to be the default export | | :warning : |
271272| [ vue/require-direct-export] ( ./require-direct-export.md ) | require the component to be directly exported | | :hammer : |
272273| [ vue/require-emit-validator] ( ./require-emit-validator.md ) | require type definitions in emits | :bulb : | :hammer : |
273274| [ vue/require-explicit-slots] ( ./require-explicit-slots.md ) | require slots to be explicitly defined | | :warning : |
Original file line number Diff line number Diff line change @@ -49,6 +49,10 @@ export default {
4949
5050Nothing.
5151
52+ ## :couple : Related Rules
53+
54+ - [ vue/require-default-export] ( ./require-default-export.md )
55+
5256## :books : Further Reading
5357
5458- [ Style guide - Component files] ( https://vuejs.org/style-guide/rules-strongly-recommended.html#component-files )
Original file line number Diff line number Diff line change 1+ ---
2+ pageClass : rule-details
3+ sidebarDepth : 0
4+ title : vue/require-default-export
5+ description : require components to be the default export
6+ ---
7+
8+ # vue/require-default-export
9+
10+ > require components to be the default export
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 reports when a Vue component does not have a default export, if the component is not defined as ` <script setup> ` .
17+
18+ <eslint-code-block :rules =" {'vue/require-default-export': ['error']} " >
19+
20+ ``` vue
21+ <!-- ✗ BAD -->
22+ <script>
23+ const foo = 'foo';
24+ </script>
25+ ```
26+
27+ </eslint-code-block >
28+
29+ <eslint-code-block :rules =" {'vue/require-default-export': ['error']} " >
30+
31+ ``` vue
32+ <!-- ✓ GOOD -->
33+ <script>
34+ export default {
35+ data() {
36+ return {
37+ foo: 'foo'
38+ };
39+ }
40+ };
41+ </script>
42+ ```
43+
44+ </eslint-code-block >
45+
46+ ## :wrench : Options
47+
48+ Nothing.
49+
50+ ## :couple : Related Rules
51+
52+ - [ vue/one-component-per-file] ( ./one-component-per-file.md )
53+
54+ ## :mag : Implementation
55+
56+ - [ Rule source] ( https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-default-export.js )
57+ - [ Test source] ( https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/require-default-export.js )
Original file line number Diff line number Diff line change @@ -209,6 +209,7 @@ const plugin = {
209209 'prop-name-casing' : require ( './rules/prop-name-casing' ) ,
210210 'quote-props' : require ( './rules/quote-props' ) ,
211211 'require-component-is' : require ( './rules/require-component-is' ) ,
212+ 'require-default-export' : require ( './rules/require-default-export' ) ,
212213 'require-default-prop' : require ( './rules/require-default-prop' ) ,
213214 'require-direct-export' : require ( './rules/require-direct-export' ) ,
214215 'require-emit-validator' : require ( './rules/require-emit-validator' ) ,
Original file line number Diff line number Diff line change 1+ /**
2+ * @author ItMaga
3+ * See LICENSE file in root directory for full license.
4+ */
5+ 'use strict'
6+
7+ const utils = require ( '../utils' )
8+
9+ module . exports = {
10+ meta : {
11+ type : 'problem' ,
12+ docs : {
13+ description : 'require components to be the default export' ,
14+ categories : undefined ,
15+ url : 'https://eslint.vuejs.org/rules/require-default-export.html'
16+ } ,
17+ fixable : null ,
18+ schema : [ ] ,
19+ messages : {
20+ missing : 'Missing default export.' ,
21+ mustBeDefaultExport : 'Component must be the default export.'
22+ }
23+ } ,
24+ /** @param {RuleContext } context */
25+ create ( context ) {
26+ const sourceCode = context . getSourceCode ( )
27+ const documentFragment = sourceCode . parserServices . getDocumentFragment ?. ( )
28+
29+ const hasScript =
30+ documentFragment &&
31+ documentFragment . children . some (
32+ ( e ) => utils . isVElement ( e ) && e . name === 'script'
33+ )
34+
35+ if ( utils . isScriptSetup ( context ) || ! hasScript ) {
36+ return { }
37+ }
38+
39+ let hasDefaultExport = false
40+ let hasDefinedComponent = false
41+
42+ return utils . compositingVisitors (
43+ utils . defineVueVisitor ( context , {
44+ onVueObjectExit ( ) {
45+ hasDefinedComponent = true
46+ }
47+ } ) ,
48+
49+ {
50+ 'Program > ExportDefaultDeclaration' ( ) {
51+ hasDefaultExport = true
52+ } ,
53+
54+ /**
55+ * @param {Program } node
56+ */
57+ 'Program:exit' ( node ) {
58+ if ( ! hasDefaultExport && node . body . length > 0 ) {
59+ context . report ( {
60+ loc : node . tokens [ node . tokens . length - 1 ] . loc ,
61+ messageId : hasDefinedComponent ? 'mustBeDefaultExport' : 'missing'
62+ } )
63+ }
64+ }
65+ }
66+ )
67+ }
68+ }
Original file line number Diff line number Diff line change 1+ /**
2+ * @author ItMaga
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/require-default-export' )
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 ( 'require-default-export' , rule , {
19+ valid : [
20+ {
21+ filename : 'test.vue' ,
22+ code : `
23+ <template>Without script</template>
24+ `
25+ } ,
26+ {
27+ filename : 'test.vue' ,
28+ code : `
29+ <script>
30+ import { ref } from 'vue';
31+
32+ export default {}
33+ </script>
34+ `
35+ } ,
36+ {
37+ filename : 'test.vue' ,
38+ code : `
39+ <script setup>
40+ const foo = 'foo';
41+ </script>
42+ `
43+ } ,
44+ {
45+ filename : 'test.vue' ,
46+ code : `
47+ <script>
48+ const component = {};
49+
50+ export default component;
51+ </script>
52+ `
53+ } ,
54+ {
55+ filename : 'test.vue' ,
56+ code : `
57+ <script>
58+ import {defineComponent} from 'vue';
59+
60+ export default defineComponent({});
61+ </script>
62+ `
63+ } ,
64+ {
65+ filename : 'test.js' ,
66+ code : `
67+ const foo = 'foo';
68+ export const bar = 'bar';
69+ `
70+ } ,
71+ {
72+ filename : 'test.js' ,
73+ code : `
74+ import {defineComponent} from 'vue';
75+ defineComponent({});
76+ `
77+ }
78+ ] ,
79+ invalid : [
80+ {
81+ filename : 'test.vue' ,
82+ code : `
83+ <script>
84+ const foo = 'foo';
85+ </script>
86+ ` ,
87+ errors : [
88+ {
89+ messageId : 'missing' ,
90+ line : 4 ,
91+ endLine : 4 ,
92+ column : 7 ,
93+ endColumn : 16
94+ }
95+ ]
96+ } ,
97+ {
98+ filename : 'test.vue' ,
99+ code : `
100+ <script>
101+ export const foo = 'foo';
102+ </script>
103+ ` ,
104+ errors : [
105+ {
106+ messageId : 'missing' ,
107+ line : 4 ,
108+ endLine : 4 ,
109+ column : 7 ,
110+ endColumn : 16
111+ }
112+ ]
113+ } ,
114+ {
115+ filename : 'test.vue' ,
116+ code : `
117+ <script>
118+ const foo = 'foo';
119+
120+ export { foo };
121+ </script>
122+ ` ,
123+ errors : [
124+ {
125+ messageId : 'missing' ,
126+ line : 6 ,
127+ endLine : 6 ,
128+ column : 7 ,
129+ endColumn : 16
130+ }
131+ ]
132+ } ,
133+ {
134+ filename : 'test.vue' ,
135+ code : `
136+ <script>
137+ export const foo = 'foo';
138+ export const bar = 'bar';
139+ </script>
140+ ` ,
141+ errors : [
142+ {
143+ messageId : 'missing' ,
144+ line : 5 ,
145+ endLine : 5 ,
146+ column : 7 ,
147+ endColumn : 16
148+ }
149+ ]
150+ } ,
151+ {
152+ filename : 'test.vue' ,
153+ code : `
154+ <script>
155+ import { defineComponent } from 'vue';
156+
157+ export const component = defineComponent({});
158+ </script>
159+ ` ,
160+ errors : [
161+ {
162+ messageId : 'mustBeDefaultExport' ,
163+ line : 6 ,
164+ endLine : 6 ,
165+ column : 7 ,
166+ endColumn : 16
167+ }
168+ ]
169+ } ,
170+ {
171+ filename : 'test.vue' ,
172+ code : `
173+ <script>
174+ import Vue from 'vue';
175+
176+ const component = Vue.component('foo', {});
177+ </script>
178+ ` ,
179+ errors : [
180+ {
181+ messageId : 'mustBeDefaultExport' ,
182+ line : 6 ,
183+ endLine : 6 ,
184+ column : 7 ,
185+ endColumn : 16
186+ }
187+ ]
188+ }
189+ ]
190+ } )
You can’t perform that action at this time.
0 commit comments