diff --git a/package.json b/package.json
index e978369..d108d3f 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,8 @@
"dependencies": {
"clone": "^2.1.2",
"loader-utils": "^1.2.3",
- "querystring": "^0.2.0"
+ "querystring": "^0.2.0",
+ "vue-docgen-api": "^4.1.1"
},
"devDependencies": {
"@babel/cli": "^7.7.0",
@@ -48,13 +49,12 @@
"prettier": "^1.19.1",
"rimraf": "^3.0.0",
"vue": "^2.6.10",
- "vue-docgen-api": "^4.0.0",
"vue-loader": "^15.7.2",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.41.2"
},
"peerDependencies": {
- "vue-docgen-api": "^3.26.0",
+ "vue-docgen-api": ">=3",
"webpack": ">=4"
},
"scripts": {
diff --git a/src/index.js b/src/index.js
index 600d30d..eebaab6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -18,6 +18,7 @@ module.exports = async function(content, map) {
const ext = this.resourcePath
.replace(/^[\s\S]*\.([^.]+)$/, '$1')
.toLowerCase()
+
const isSFC = ext === 'vue'
try {
@@ -28,21 +29,25 @@ 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)
+ : attemptMultiParse(content, this.resourcePath, options.docgenOptions)
// `parse` is async since vue-docgen-api@4.
- const info =
+ const allInfo = [].concat(
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`
+ 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) {
@@ -55,3 +60,8 @@ module.exports = async function(content, map) {
callback(null, content, map)
}
}
+
+function attemptMultiParse(content, path, options) {
+ if (docgen.parseMulti) return docgen.parseMulti(path, options)
+ else return docgen.parseSource(content, path, options)
+}
diff --git a/test/__snapshots__/loader.spec.js.snap b/test/__snapshots__/loader.spec.js.snap
index 24f6ce5..4a5d920 100644
--- a/test/__snapshots__/loader.spec.js.snap
+++ b/test/__snapshots__/loader.spec.js.snap
@@ -45,3 +45,47 @@ 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 {},
+}
+`;
diff --git a/test/fixtures/basicMulti.vue.js b/test/fixtures/basicMulti.vue.js
new file mode 100644
index 0000000..d7ef241
--- /dev/null
+++ b/test/fixtures/basicMulti.vue.js
@@ -0,0 +1,30 @@
+import Vue from 'vue'
+
+export const MyButton1 = {
+ props: {
+ /**
+ * Foo the number.
+ */
+ foo: {
+ type: Number,
+ default: -1
+ }
+ },
+ template: '{{foo}}'
+}
+
+export const MyButton2 = {
+ props: {
+ /**
+ * Foo the number.
+ */
+ foo: {
+ type: Number,
+ default: -1
+ }
+ },
+ template: '{{foo}}'
+}
+
+// NOTE: vue-docgen-api cannot handle default exports (is it expected behavor or bug? idk...)
+// export default MyButton
diff --git a/test/loader.spec.js b/test/loader.spec.js
index fe10e8a..5918cf7 100644
--- a/test/loader.spec.js
+++ b/test/loader.spec.js
@@ -22,3 +22,23 @@ 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()
+})