Skip to content

Commit 3d7d91d

Browse files
committed
feat: call custom block loaders with Component as argument
1 parent 19b9d07 commit 3d7d91d

File tree

4 files changed

+93
-3
lines changed

4 files changed

+93
-3
lines changed

docs/en/configurations/custom-blocks.md

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
55
You can define custom language blocks inside `*.vue` files. The content of a custom block will be processed by the loaders specified in the `loaders` object of `vue-loader` options and then required by the component module. The configuration is similar to what is described in [Advanced Loader Configuration](../configurations/advanced.md), except the matching uses the tag name instead of the `lang` attribute.
66

7-
If a matching loader is found for a custom block, it will be processed; otherwise the custom block will simply be ignored.
7+
If a matching loader is found for a custom block, it will be processed; otherwise the custom block will simply be ignored. Additionally, if the found loader returns a function, that function will be called with the component of the `*.vue` file as a parameter.
88

9-
## Example
9+
## Single docs file example
1010

1111
Here's an example of extracting all `<docs>` custom blocks into a single docs file:
1212

@@ -65,3 +65,69 @@ module.exports = {
6565
}
6666
}
6767
```
68+
69+
## Runtime available docs
70+
71+
Here's an example of injecting the `<docs>` custom blocks into the component so that it's available during runtime.
72+
73+
#### docs-loader.js
74+
75+
In order for the custom block content to be injected, we'll need a custom loader:
76+
77+
``` js
78+
module.exports = function (source, map) {
79+
this.callback(null, 'module.exports = function(Component) {Component.options.__docs = ' +
80+
JSON.stringify(source) +
81+
'}', map)
82+
}
83+
```
84+
85+
#### webpack.config.js
86+
87+
Now we'll configure webpack to use our custom loader for `<docs>` custom blocks.
88+
89+
``` js
90+
const docsLoader = require.resolve('./custom-loaders/docs-loader.js')
91+
92+
module.exports = {
93+
module: {
94+
rules: [
95+
{
96+
test: /\.vue$/,
97+
loader: 'vue',
98+
options: {
99+
loaders: {
100+
'docs': docsLoader
101+
}
102+
}
103+
}
104+
]
105+
}
106+
}
107+
```
108+
109+
#### component.vue
110+
111+
We are now able to access the `<docs>` block's content of imported components during runtime.
112+
113+
``` html
114+
<template>
115+
<div>
116+
<component-b \>
117+
<p>{{ docs }}</p>
118+
</div>
119+
</template>
120+
121+
<script>
122+
import componentB from 'componentB';
123+
124+
export default = {
125+
data () {
126+
return {
127+
docs: componentB.__docs
128+
}
129+
},
130+
components: {componentB}
131+
}
132+
</script>
133+
```

lib/loader.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,11 @@ module.exports = function (content) {
411411
addedPrefix = true
412412
}
413413

414-
output += requireString + '\n'
414+
output +=
415+
'var customBlock = ' + requireString + '\n' +
416+
'if (typeof customBlock === "function") {' +
417+
'customBlock(Component)' +
418+
'}\n'
415419
}
416420
})
417421

test/mock-loaders/docs.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = function (source, map) {
2+
this.callback(null, 'module.exports = function(Component) {Component.options.__docs = ' +
3+
JSON.stringify(source) +
4+
'}', map)
5+
}

test/test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,21 @@ describe('vue-loader', function () {
634634
})
635635
})
636636

637+
it('passes Component to custom block loaders', done => {
638+
const mockLoaderPath = require.resolve('./mock-loaders/docs')
639+
test({
640+
entry: './test/fixtures/custom-language.vue',
641+
vue: {
642+
loaders: {
643+
'documentation': mockLoaderPath
644+
}
645+
}
646+
}, (window, module) => {
647+
expect(module.__docs).to.contain('This is example documentation for a component.')
648+
done()
649+
})
650+
})
651+
637652
it('custom blocks can be ignored', done => {
638653
bundle({
639654
entry: './test/fixtures/custom-language.vue'

0 commit comments

Comments
 (0)