Skip to content

Commit 753d86d

Browse files
committed
Allow to use @vue/component to set type of file to vue
1 parent a3d64c7 commit 753d86d

File tree

3 files changed

+291
-3
lines changed

3 files changed

+291
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ module.exports = {
4444
}
4545
```
4646

47-
## Configs
47+
## :gear: Configs
4848

4949
This plugin provides two predefined configs:
5050
- `plugin:vue/base` - contains necessary settings for this plugin to work properly

lib/utils/index.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,21 +432,52 @@ module.exports = {
432432
executeOnVueComponent (context, cb) {
433433
const filePath = context.getFilename()
434434
const _this = this
435+
const componentComments = []
436+
const foundNodes = []
437+
438+
const hasNode = (node) => {
439+
return foundNodes.some(el => el.loc.start.line === node.loc.start.line)
440+
}
435441

436442
return {
443+
LineComment (node) {
444+
// line comment with @vue/component
445+
if (!_this.isVueComponentComment(node.value)) return
446+
componentComments.push(node)
447+
},
448+
BlockComment (node) {
449+
// block comment with @vue/component
450+
if (!_this.isVueComponentComment(node.value)) return
451+
componentComments.push(node)
452+
},
453+
ObjectExpression (node) {
454+
// comment with @vue/component
455+
if (!componentComments.some(el => el.loc.end.line === node.loc.start.line - 1) || hasNode(node)) return
456+
foundNodes.push(node)
457+
cb(node)
458+
},
437459
'ExportDefaultDeclaration:exit' (node) {
438460
// export default {} in .vue || .jsx
439-
if (!_this.isVueComponentFile(node, filePath)) return
461+
if (!_this.isVueComponentFile(node, filePath, context) || hasNode(node)) return
440462
cb(node.declaration)
441463
},
442464
'CallExpression:exit' (node) {
443465
// Vue.component('xxx', {}) || component('xxx', {})
444-
if (!_this.isVueComponent(node)) return
466+
if (!_this.isVueComponent(node) || foundNodes.some(el => el.loc.start.line === node.loc.start.line)) return
445467
cb(node.arguments.slice(-1)[0])
446468
}
447469
}
448470
},
449471

472+
/**
473+
* Check whether the given comment is a Vue component based
474+
* @param {string} value Conent of comment.
475+
* @return {boolean}
476+
*/
477+
isVueComponentComment (value) {
478+
return /@vue\/component/g.test(value)
479+
},
480+
450481
/**
451482
* Return generator with all properties
452483
* @param {ASTNode} node Node to check

tests/lib/utils/vue-component.js

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/**
2+
* @author Armano
3+
*/
4+
'use strict'
5+
6+
const utils = require('../../../lib/utils/index')
7+
8+
// ------------------------------------------------------------------------------
9+
// Requirements
10+
// ------------------------------------------------------------------------------
11+
12+
const rule = {
13+
create (context) {
14+
return utils.executeOnVueComponent(context, obj => {
15+
context.report({
16+
node: obj,
17+
message: 'Internal test: component.'
18+
})
19+
})
20+
},
21+
meta: {
22+
fixable: null,
23+
schema: []
24+
}
25+
}
26+
27+
const RuleTester = require('eslint').RuleTester
28+
const parserOptions = {
29+
ecmaVersion: 6,
30+
sourceType: 'module'
31+
}
32+
33+
function makeError (line) {
34+
return {
35+
message: 'Internal test: component.',
36+
line,
37+
type: 'ObjectExpression'
38+
}
39+
}
40+
41+
function notFoundTests (ext) {
42+
return [
43+
{
44+
filename: `test.${ext}`,
45+
code: `export const foo = {}`,
46+
parserOptions
47+
},
48+
{
49+
filename: `test.${ext}`,
50+
code: `export var foo = {}`,
51+
parserOptions
52+
},
53+
{
54+
filename: `test.${ext}`,
55+
code: `const foo = {}`,
56+
parserOptions
57+
},
58+
{
59+
filename: `test.${ext}`,
60+
code: `var foo = {}`,
61+
parserOptions
62+
},
63+
{
64+
filename: `test.${ext}`,
65+
code: `let foo = {}`,
66+
parserOptions
67+
},
68+
{
69+
filename: `test.${ext}`,
70+
code: `foo({ })`,
71+
parserOptions
72+
},
73+
{
74+
filename: `test.${ext}`,
75+
code: `foo(() => { return {} })`,
76+
parserOptions
77+
},
78+
{
79+
filename: `test.${ext}`,
80+
code: `Vue.component('async-example', function (resolve, reject) { })`,
81+
parserOptions
82+
},
83+
{
84+
filename: `test.${ext}`,
85+
code: `Vue.component('async-example', function (resolve, reject) { resolve({}) })`,
86+
parserOptions
87+
},
88+
{
89+
filename: `test.${ext}`,
90+
code: `new Vue({ })`,
91+
parserOptions
92+
},
93+
{
94+
filename: `test.${ext}`,
95+
code: `{
96+
foo: {}
97+
}`,
98+
parserOptions
99+
}
100+
]
101+
}
102+
103+
function foundTests (ext) {
104+
return [
105+
{
106+
filename: `test.${ext}`,
107+
code: `// ${ext}
108+
Vue.component('async-example', function (resolve, reject) {
109+
// @vue/component
110+
resolve({})
111+
})`,
112+
parserOptions,
113+
errors: [makeError(4)]
114+
},
115+
{
116+
filename: `test.${ext}`,
117+
code: `Vue.component({})`,
118+
parserOptions,
119+
errors: [makeError(1)]
120+
},
121+
{
122+
filename: `test.${ext}`,
123+
code: `// ${ext}
124+
// @vue/component
125+
export default { }`,
126+
parserOptions,
127+
errors: [makeError(3)]
128+
},
129+
{
130+
filename: `test.${ext}`,
131+
code: `// ${ext}
132+
/* @vue/component */
133+
export default { }
134+
// ${ext}`,
135+
parserOptions,
136+
errors: [makeError(3)]
137+
},
138+
{
139+
filename: `test.${ext}`,
140+
code: `
141+
/*
142+
* ext: ${ext}
143+
* @vue/component
144+
*/
145+
export default { }
146+
// ${ext}`,
147+
parserOptions,
148+
errors: [makeError(6)]
149+
},
150+
{
151+
filename: `test.${ext}`,
152+
code: `// @vue/component
153+
export default { }
154+
// @vue/component
155+
export var a = { }
156+
// ${ext}`,
157+
parserOptions,
158+
errors: [makeError(2), makeError(4)]
159+
},
160+
{
161+
filename: `test.${ext}`,
162+
code: `/* @vue/component */
163+
export const foo = { }
164+
/* @vue/component */
165+
export default { }
166+
// ${ext}`,
167+
parserOptions,
168+
errors: [makeError(2), makeError(4)]
169+
},
170+
{
171+
filename: `test.${ext}`,
172+
code: `export default { }
173+
// @vue/component
174+
export let foo = { }
175+
// ${ext}`,
176+
parserOptions,
177+
errors: (ext === 'js' ? [] : [makeError(1)]).concat([makeError(3)])
178+
},
179+
{
180+
filename: `test.${ext}`,
181+
code: `let foo = { }
182+
// @vue/component
183+
export let bar = { }
184+
// ${ext}`,
185+
parserOptions,
186+
errors: [makeError(3)]
187+
},
188+
{
189+
filename: `test.${ext}`,
190+
code: `export var dar = { }
191+
// @vue/component
192+
foo({ })
193+
bar({ })
194+
// ${ext}`,
195+
parserOptions,
196+
errors: [makeError(3)]
197+
},
198+
{
199+
filename: `test.${ext}`,
200+
code: `foo({ })
201+
export default {
202+
test: {},
203+
// @vue/component
204+
foo: { }
205+
}
206+
bar({ })
207+
// ${ext}`,
208+
parserOptions,
209+
errors: (ext === 'js' ? [] : [makeError(2)]).concat([makeError(5)])
210+
},
211+
{
212+
filename: `test.${ext}`,
213+
code: `export default {
214+
bar () {
215+
return {}
216+
},
217+
foo () {
218+
// @vue/component
219+
return {}
220+
}
221+
}
222+
// ${ext}`,
223+
parserOptions,
224+
errors: (ext === 'js' ? [] : [makeError(1)]).concat([makeError(7)])
225+
}
226+
]
227+
}
228+
229+
// ------------------------------------------------------------------------------
230+
// Tests
231+
// ------------------------------------------------------------------------------
232+
233+
const ruleTester = new RuleTester()
234+
ruleTester.run('vue-component', rule, {
235+
236+
valid: [
237+
{
238+
filename: 'test.js',
239+
code: `export default { }`,
240+
parserOptions
241+
}
242+
].concat(notFoundTests('js')).concat(notFoundTests('jsx')).concat(notFoundTests('vue')),
243+
invalid: [
244+
{
245+
filename: 'test.vue',
246+
code: `export default { }`,
247+
parserOptions,
248+
errors: [makeError(1)]
249+
},
250+
{
251+
filename: 'test.jsx',
252+
code: `export default { }`,
253+
parserOptions,
254+
errors: [makeError(1)]
255+
}
256+
].concat(foundTests('js')).concat(foundTests('jsx')).concat(foundTests('vue'))
257+
})

0 commit comments

Comments
 (0)