Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented support for parsing multiple exports #4

Merged
merged 5 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"prettier": "^1.19.1",
"rimraf": "^3.0.0",
"vue": "^2.6.10",
"vue-docgen-api": "^4.0.0",
"vue-docgen-api": "^4.1.1",
"vue-loader": "^15.7.2",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.41.2"
Expand Down
27 changes: 15 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,24 @@ module.exports = async function(content, map) {
// vue-loader, we need to read file to get the source code.
const infoOrPromise = isSFC
? docgen.parse(this.resourcePath, options.docgenOptions)
: docgen.parseSource(content, this.resourcePath, options.docgenOptions)
: docgen.parseMulti(this.resourcePath, options.docgenOptions)
Aaron-Pool marked this conversation as resolved.
Show resolved Hide resolved

// `parse` is async since vue-docgen-api@4.
const info =
infoOrPromise instanceof Promise ? await infoOrPromise : infoOrPromise

// The default value 'component' is for SFC(vue-loader)'s export name.
const ident =
(info.exportName !== 'default' && info.exportName) || 'component'

const exportStatement = `;(${ident}.options = ${ident}.options || {}).__docgenInfo = ${JSON.stringify(
info
)}\n`
const allInfo =
[].concat(infoOrPromise instanceof Promise ? await infoOrPromise : infoOrPromise)

let fullExportStatement = '';
for(let i = 0; i < allInfo.length; i++) {
const info = allInfo[i];
const ident =
(info.exportName !== 'default' && info.exportName) || 'component'
const exportStatement = `;(${ident}.options = ${ident}.options || {}).__docgenInfo = ${JSON.stringify(
info
)}\n`
fullExportStatement += `${exportStatement}`;
}

const js = content + '\n' + exportStatement
const js = content + '\n' + fullExportStatement

callback(null, js, map)
} catch (e) {
Expand Down
113 changes: 112 additions & 1 deletion test/__snapshots__/loader.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,30 @@ Object {
}
`;

exports[`Injects docgen result for non-SFC 1`] = `
exports[`Injects docgen result for non-SFC with default exports 1`] = `
Object {
"description": "",
"displayName": "basicDefault.vue",
"exportName": "default",
"props": Array [
Object {
"defaultValue": Object {
"func": false,
"value": "-1",
},
"description": "Foo the number.",
"name": "foo",
"tags": Object {},
"type": Object {
"name": "number",
},
},
],
"tags": Object {},
}
`;

exports[`Injects docgen result for non-SFC with named exports 1`] = `
Object {
"description": "",
"displayName": "basic.vue",
Expand All @@ -45,3 +68,91 @@ Object {
"tags": Object {},
}
`;

exports[`Injects docgen result non-SFC with multiple exports 1`] = `
Object {
"description": "",
"exportName": "MyButton1",
"props": Array [
Object {
"defaultValue": Object {
"func": false,
"value": "-1",
},
"description": "Foo the number.",
"name": "foo",
"tags": Object {},
"type": Object {
"name": "number",
},
},
],
"tags": Object {},
}
`;

exports[`Injects docgen result non-SFC with multiple exports 2`] = `
Object {
"description": "",
"exportName": "MyButton2",
"props": Array [
Object {
"defaultValue": Object {
"func": false,
"value": "-1",
},
"description": "Foo the number.",
"name": "foo",
"tags": Object {},
"type": Object {
"name": "number",
},
},
],
"tags": Object {},
}
`;

exports[`Injects docgen result non-SFC with multiple, mixed, both named and default, exports 1`] = `
Object {
"description": "",
"exportName": "MyButton1",
"props": Array [
Object {
"defaultValue": Object {
"func": false,
"value": "-1",
},
"description": "Foo the number.",
"name": "foo",
"tags": Object {},
"type": Object {
"name": "number",
},
},
],
"tags": Object {},
}
`;

exports[`Injects docgen result non-SFC with multiple, mixed, both named and default, exports 2`] = `
Object {
"description": "",
"exportName": "default",
"props": Array [
Object {
"defaultValue": Object {
"func": false,
"value": "-1",
},
"description": "Foo the number.",
"name": "foo",
"tags": Object {},
"type": Object {
"name": "number",
},
},
],
"tags": Object {},
}
`;
14 changes: 14 additions & 0 deletions test/fixtures/basicDefault.vue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Vue from 'vue'

export default {
pocka marked this conversation as resolved.
Show resolved Hide resolved
props: {
/**
* Foo the number.
*/
foo: {
type: Number,
default: -1
}
},
template: '<span>{{foo}}</span>'
}
30 changes: 30 additions & 0 deletions test/fixtures/basicMixed.vue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Vue from 'vue'

export const MyButton1 = {
props: {
/**
* Foo the number.
*/
foo: {
type: Number,
default: -1
}
},
template: '<span>{{foo}}</span>'
}

export default {
props: {
/**
* Foo the number.
*/
foo: {
type: Number,
default: -1
}
},
template: '<span>{{foo}}</span>'
}

// NOTE: vue-docgen-api cannot handle default exports (is it expected behavor or bug? idk...)
// export default MyButton
30 changes: 30 additions & 0 deletions test/fixtures/basicMulti.vue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Vue from 'vue'

export const MyButton1 = {
props: {
/**
* Foo the number.
*/
foo: {
type: Number,
default: -1
}
},
template: '<span>{{foo}}</span>'
}

export const MyButton2 = {
props: {
/**
* Foo the number.
*/
foo: {
type: Number,
default: -1
}
},
template: '<span>{{foo}}</span>'
}

// NOTE: vue-docgen-api cannot handle default exports (is it expected behavor or bug? idk...)
// export default MyButton
55 changes: 54 additions & 1 deletion test/loader.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,20 @@ it('Injects docgen result as __docgenInfo property', async () => {
expect(JSON.parse(output.match(docgenPattern)[1])).toMatchSnapshot()
})

it('Injects docgen result for non-SFC', async () => {
it('Injects docgen result for non-SFC with default exports', async () => {
const fixture = './fixtures/basicDefault.vue.js'

const stats = await compiler(fixture)
const output = stats.toJson().modules.find(mod => mod.name.includes(fixture))
.source

const docgenPattern = /\.__docgenInfo\s?=\s?(\{[\s\S]*})/

expect(output).toMatch(docgenPattern)
expect(JSON.parse(output.match(docgenPattern)[1])).toMatchSnapshot()
})

it('Injects docgen result for non-SFC with named exports', async () => {
const fixture = './fixtures/basic.vue.js'

const stats = await compiler(fixture)
Expand All @@ -22,3 +35,43 @@ it('Injects docgen result for non-SFC', async () => {
expect(output).toMatch(docgenPattern)
expect(JSON.parse(output.match(docgenPattern)[1])).toMatchSnapshot()
})

it('Injects docgen result non-SFC with multiple exports', async () => {
const fixture = './fixtures/basicMulti.vue.js'

const stats = await compiler(fixture)
const output = stats.toJson().modules.find(mod => mod.name.includes(fixture))
.source

const buttonExports = ['MyButton1', 'MyButton2']

const createDocgenPattern = exportName =>
`^.*${exportName}.*\\.__docgenInfo\\s?=\\s?(\\{[\\s\\S]*?})$`
const match1 = new RegExp(createDocgenPattern(buttonExports[0]), 'm')
const match2 = new RegExp(createDocgenPattern(buttonExports[1]), 'm')

expect(output).toMatch(match1)
expect(output).toMatch(match2)
expect(JSON.parse(output.match(match1)[1])).toMatchSnapshot()
expect(JSON.parse(output.match(match2)[1])).toMatchSnapshot()
})

it('Injects docgen result non-SFC with multiple, mixed, both named and default, exports', async () => {
const fixture = './fixtures/basicMixed.vue.js'

const stats = await compiler(fixture)
const output = stats.toJson().modules.find(mod => mod.name.includes(fixture))
.source

const buttonExports = ['MyButton1', 'component']

const createDocgenPattern = exportName =>
`^.*${exportName}.*\\.__docgenInfo\\s?=\\s?(\\{[\\s\\S]*?})$`
const match1 = new RegExp(createDocgenPattern(buttonExports[0]), 'm')
const match2 = new RegExp(createDocgenPattern(buttonExports[1]), 'm')

expect(output).toMatch(match1)
expect(output).toMatch(match2)
expect(JSON.parse(output.match(match1)[1])).toMatchSnapshot()
expect(JSON.parse(output.match(match2)[1])).toMatchSnapshot()
})