Skip to content

Commit f60d90c

Browse files
authored
feat: Vue Support
Thanks to @batje, documentation.js now supports Vue! .vue files are parsed for their JavaScript contents by default.
1 parent 542031e commit f60d90c

File tree

9 files changed

+355
-2
lines changed

9 files changed

+355
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
[![Coverage Status](https://coveralls.io/repos/github/documentationjs/documentation/badge.svg?branch=master)](https://coveralls.io/github/documentationjs/documentation?branch=master)
1515
[![Inline docs](http://inch-ci.org/github/documentationjs/documentation.svg?branch=master&style=flat-square)](http://inch-ci.org/github/documentationjs/documentation)
1616

17-
* Supports modern JavaScript: ES5, ES2017, JSX, and [Flow](http://flowtype.org/) type annotations.
17+
* Supports modern JavaScript: ES5, ES2017, JSX, Vue and [Flow](http://flowtype.org/) type annotations.
1818
* Infers parameters, types, membership, and more. Write less documentation: let the computer write it for you.
1919
* Integrates with GitHub to link directly from documentation to the code it refers to.
2020
* Customizable output: HTML, JSON, Markdown, and more

__tests__/__snapshots__/test.js.snap

+277
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,282 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Vue file 1`] = `
4+
Array [
5+
Object {
6+
"augments": Array [],
7+
"context": Object {
8+
"loc": SourceLocation {
9+
"end": Position {
10+
"column": 1,
11+
"line": 19,
12+
},
13+
"start": Position {
14+
"column": 0,
15+
"line": 7,
16+
},
17+
},
18+
},
19+
"description": Object {
20+
"children": Array [
21+
Object {
22+
"children": Array [
23+
Object {
24+
"position": Position {
25+
"end": Object {
26+
"column": 29,
27+
"line": 1,
28+
"offset": 28,
29+
},
30+
"indent": Array [],
31+
"start": Object {
32+
"column": 1,
33+
"line": 1,
34+
"offset": 0,
35+
},
36+
},
37+
"type": "text",
38+
"value": "This Vue Component is a test",
39+
},
40+
],
41+
"position": Position {
42+
"end": Object {
43+
"column": 29,
44+
"line": 1,
45+
"offset": 28,
46+
},
47+
"indent": Array [],
48+
"start": Object {
49+
"column": 1,
50+
"line": 1,
51+
"offset": 0,
52+
},
53+
},
54+
"type": "paragraph",
55+
},
56+
],
57+
"position": Object {
58+
"end": Object {
59+
"column": 29,
60+
"line": 1,
61+
"offset": 28,
62+
},
63+
"start": Object {
64+
"column": 1,
65+
"line": 1,
66+
"offset": 0,
67+
},
68+
},
69+
"type": "root",
70+
},
71+
"errors": Array [],
72+
"examples": Array [],
73+
"loc": SourceLocation {
74+
"end": Position {
75+
"column": 3,
76+
"line": 6,
77+
},
78+
"start": Position {
79+
"column": 0,
80+
"line": 3,
81+
},
82+
},
83+
"members": Object {
84+
"events": Array [],
85+
"global": Array [],
86+
"inner": Array [],
87+
"instance": Array [],
88+
"static": Array [],
89+
},
90+
"name": "vue.input",
91+
"namespace": "vue.input",
92+
"params": Array [],
93+
"path": Array [
94+
Object {
95+
"kind": undefined,
96+
"name": "vue.input",
97+
},
98+
],
99+
"properties": Array [],
100+
"returns": Array [
101+
Object {
102+
"description": Object {
103+
"children": Array [
104+
Object {
105+
"children": Array [
106+
Object {
107+
"position": Position {
108+
"end": Object {
109+
"column": 21,
110+
"line": 1,
111+
"offset": 20,
112+
},
113+
"indent": Array [],
114+
"start": Object {
115+
"column": 1,
116+
"line": 1,
117+
"offset": 0,
118+
},
119+
},
120+
"type": "text",
121+
"value": "vue-tested component",
122+
},
123+
],
124+
"position": Position {
125+
"end": Object {
126+
"column": 21,
127+
"line": 1,
128+
"offset": 20,
129+
},
130+
"indent": Array [],
131+
"start": Object {
132+
"column": 1,
133+
"line": 1,
134+
"offset": 0,
135+
},
136+
},
137+
"type": "paragraph",
138+
},
139+
],
140+
"position": Object {
141+
"end": Object {
142+
"column": 21,
143+
"line": 1,
144+
"offset": 20,
145+
},
146+
"start": Object {
147+
"column": 1,
148+
"line": 1,
149+
"offset": 0,
150+
},
151+
},
152+
"type": "root",
153+
},
154+
"title": "returns",
155+
"type": Object {
156+
"name": "vue-tested",
157+
"type": "NameExpression",
158+
},
159+
},
160+
],
161+
"sees": Array [],
162+
"tags": Array [
163+
Object {
164+
"description": "vue-tested component",
165+
"lineNumber": 2,
166+
"title": "returns",
167+
"type": Object {
168+
"name": "vue-tested",
169+
"type": "NameExpression",
170+
},
171+
},
172+
],
173+
"throws": Array [],
174+
"todos": Array [],
175+
},
176+
Object {
177+
"augments": Array [],
178+
"context": Object {
179+
"loc": SourceLocation {
180+
"end": Position {
181+
"column": 3,
182+
"line": 17,
183+
},
184+
"start": Position {
185+
"column": 2,
186+
"line": 14,
187+
},
188+
},
189+
},
190+
"description": Object {
191+
"children": Array [
192+
Object {
193+
"children": Array [
194+
Object {
195+
"position": Position {
196+
"end": Object {
197+
"column": 17,
198+
"line": 1,
199+
"offset": 16,
200+
},
201+
"indent": Array [],
202+
"start": Object {
203+
"column": 1,
204+
"line": 1,
205+
"offset": 0,
206+
},
207+
},
208+
"type": "text",
209+
"value": "This is a number",
210+
},
211+
],
212+
"position": Position {
213+
"end": Object {
214+
"column": 17,
215+
"line": 1,
216+
"offset": 16,
217+
},
218+
"indent": Array [],
219+
"start": Object {
220+
"column": 1,
221+
"line": 1,
222+
"offset": 0,
223+
},
224+
},
225+
"type": "paragraph",
226+
},
227+
],
228+
"position": Object {
229+
"end": Object {
230+
"column": 17,
231+
"line": 1,
232+
"offset": 16,
233+
},
234+
"start": Object {
235+
"column": 1,
236+
"line": 1,
237+
"offset": 0,
238+
},
239+
},
240+
"type": "root",
241+
},
242+
"errors": Array [],
243+
"examples": Array [],
244+
"loc": SourceLocation {
245+
"end": Position {
246+
"column": 5,
247+
"line": 13,
248+
},
249+
"start": Position {
250+
"column": 2,
251+
"line": 11,
252+
},
253+
},
254+
"members": Object {
255+
"events": Array [],
256+
"global": Array [],
257+
"inner": Array [],
258+
"instance": Array [],
259+
"static": Array [],
260+
},
261+
"name": "myNumber",
262+
"namespace": "myNumber",
263+
"params": Array [],
264+
"path": Array [
265+
Object {
266+
"kind": undefined,
267+
"name": "myNumber",
268+
},
269+
],
270+
"properties": Array [],
271+
"returns": Array [],
272+
"sees": Array [],
273+
"tags": Array [],
274+
"throws": Array [],
275+
"todos": Array [],
276+
},
277+
]
278+
`;
279+
3280
exports[`config 1`] = `
4281
"<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
5282

__tests__/fixture/vue.input.vue

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<template>
2+
<div>not relevant</div>
3+
</template>
4+
5+
<script>
6+
7+
/**
8+
* This Vue Component is a test
9+
* @returns {vue-tested} vue-tested component
10+
*/
11+
export default {
12+
13+
props: {
14+
15+
/**
16+
* This is a number
17+
*/
18+
myNumber: {
19+
default: 42,
20+
type: Number
21+
}
22+
}
23+
}
24+
</script>
25+
26+
<style>
27+
28+
</style>

__tests__/test.js

+7
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,10 @@ test('.lint with bad input', async function() {
234234
expect(err).toBeTruthy();
235235
}
236236
});
237+
238+
test('Vue file', async function() {
239+
await pify(chdir)(__dirname);
240+
const data = await documentation.build('__tests__/fixture/vue.input.vue', {});
241+
normalize(data);
242+
expect(data).toMatchSnapshot();
243+
});

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"vfile-sort": "^2.1.0",
5555
"vinyl": "^2.1.0",
5656
"vinyl-fs": "^3.0.2",
57+
"vue-template-compiler": "^2.5.16",
5758
"yargs": "^9.0.1"
5859
},
5960
"devDependencies": {

src/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
const fs = require('fs');
2+
const path = require('path');
23
const _ = require('lodash');
34
const sort = require('./sort');
45
const nest = require('./nest');
56
const filterAccess = require('./filter_access');
67
const dependency = require('./input/dependency');
78
const shallow = require('./input/shallow');
89
const parseJavaScript = require('./parsers/javascript');
10+
const parseVueScript = require('./parsers/vue');
911
const github = require('./github');
1012
const hierarchy = require('./hierarchy');
1113
const inferName = require('./infer/name');
@@ -103,6 +105,9 @@ function buildInternal(inputsAndConfig) {
103105
sourceFile.source = fs.readFileSync(sourceFile.file, 'utf8');
104106
}
105107

108+
if (path.extname(sourceFile.file) === '.vue') {
109+
return parseVueScript(sourceFile, config).map(buildPipeline);
110+
}
106111
return parseJavaScript(sourceFile, config).map(buildPipeline);
107112
}).filter(Boolean);
108113

src/merge_config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ function mergeConfig(config: Object): Promise<DocumentationConfig> {
8888
'js',
8989
'jsx',
9090
'es5',
91-
'es6'
91+
'es6',
92+
'vue'
9293
]);
9394

9495
return mergeConfigFile(config).then(mergePackage);

src/parsers/vue.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* @flow */
2+
3+
const parseJavaScript = require('./javascript');
4+
const vuecompiler = require('vue-template-compiler');
5+
6+
/**
7+
* Receives a module-dep item,
8+
* reads the file, parses the VueScript, and parses the JSDoc.
9+
*
10+
* @param {Object} data a chunk of data provided by module-deps
11+
* @param {Object} config config
12+
* @returns {Array<Object>} an array of parsed comments
13+
*/
14+
function parseVueScript(data: Object, config: DocumentationConfig) {
15+
data.source = vuecompiler.parseComponent(data.source).script.content;
16+
return parseJavaScript(data, config);
17+
}
18+
19+
module.exports = parseVueScript;

0 commit comments

Comments
 (0)