Skip to content

Commit 002d637

Browse files
author
Andre Asselin
committed
Rebase changes onto current version of master
Add in additional changes that add attributes on custom blocks as query parms for the loader
1 parent 733c810 commit 002d637

File tree

10 files changed

+314
-12
lines changed

10 files changed

+314
-12
lines changed

docs/en/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ There are many cool features provided by `vue-loader`:
1010

1111
- ES2015 enabled by default;
1212
- Allows using other Webpack loaders for each part of a Vue component, for example SASS for `<style>` and Jade for `<template>`;
13+
- Allows custom sections in a .vue file that can have custom loader chains applied to them
1314
- Treat static assets referenced in `<style>` and `<template>` as module dependencies and handle them with Webpack loaders;
1415
- Can simulate scoped CSS for each component;
1516
- Supports component hot-reloading during development.

docs/en/configurations/advanced.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@ module.exports = {
4141
{
4242
test: /\.vue$/,
4343
loader: 'vue-loader',
44-
// vue-loader options goes here
4544
options: {
4645
loaders: {
47-
// ...
46+
// load all <script> without "lang" attribute with coffee-loader
47+
js: 'coffee',
48+
// load <template> directly as HTML string, without piping it
49+
// through vue-html-loader first
50+
html: 'raw'
4851
}
4952
}
5053
}

docs/en/start/spec.md

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Vue Component Spec
22

3-
A `*.vue` file is a custom file format that uses HTML-like syntax to describe a Vue component. Each `*.vue` file consists of three types of top-level language blocks: `<template>`, `<script>` and `<style>`:
3+
A `*.vue` file is a custom file format that uses HTML-like syntax to describe a Vue component. Each `*.vue` file consists of three types of top-level language blocks: `<template>`, `<script>`, and `<style>`, and optionally additional custom blocks:
44

55
``` html
66
<template>
@@ -22,6 +22,10 @@ export default {
2222
color: red;
2323
}
2424
</style>
25+
26+
<custom1>
27+
This could be e.g. documentation for the component.
28+
</custom1>
2529
```
2630

2731
`vue-loader` will parse the file, extract each language block, pipe them through other loaders if necessary, and finally assemble them back into a CommonJS module whose `module.exports` is a Vue.js component options object.
@@ -66,6 +70,66 @@ More details can be found in [Using Pre-Processors](../configurations/pre-proces
6670

6771
- By default, contents will be extracted and dynamically inserted into the document's `<head>` as an actual `<style>` tag using `style-loader`. It's also possible to [configure Webpack so that all styles in all components are extracted into a single CSS file](../configurations/extract-css.md).
6872

73+
### Custom Blocks
74+
75+
Additional custom blocks can be included in a `*.vue` file for any project specific needs. `vue-loader` will use the tag name to look up which webpack loaders should be applied to the contents of the section. The webpack loaders should be specified in the `loaders` hash of the `vue` section of the webpack configuration in the same way that languages are specified for the standard sections of the file. See [Advanced Loader Configuration](../configurations/advanced.md).
76+
77+
Example:
78+
79+
#### component.vue
80+
``` html
81+
<unit-test>
82+
describe('example', function () {
83+
it('basic', function (done) {
84+
done();
85+
})
86+
})
87+
</unit-test>
88+
89+
<template>
90+
<h2 class="red">{{msg}}</h2>
91+
</template>
92+
93+
<script>
94+
export default {
95+
data () {
96+
return {
97+
msg: 'Hello from Component A!'
98+
}
99+
}
100+
}
101+
</script>
102+
103+
<style>
104+
comp-a h2 {
105+
color: #f00;
106+
}
107+
</style>
108+
```
109+
110+
#### webpack.config.js
111+
112+
``` js
113+
// Webpack 2.x (^2.1.0-beta.25)
114+
module.exports = {
115+
module: {
116+
rules: [
117+
{
118+
test: /\.vue$/,
119+
loader: 'vue',
120+
// vue-loader options go here
121+
options: {
122+
loaders: {
123+
unit-test: 'buble-loader',
124+
}
125+
}
126+
}
127+
]
128+
}
129+
}
130+
```
131+
132+
69133
### Src Imports
70134

71135
If you prefer splitting up your `*.vue` components into multiple files, you can use the `src` attribute to import an external file for a language block:
@@ -83,6 +147,13 @@ Beware that `src` imports follow the same path resolution rules to CommonJS `req
83147
<style src="todomvc-app-css/index.css">
84148
```
85149
150+
`src` imports also work with custom blocks, e.g.:
151+
152+
``` html
153+
<unit-test src="./unit-test.js">
154+
</unit-test>
155+
```
156+
86157
### Syntax Highlighting
87158
88159
Currently there is syntax highlighting support for [Sublime Text](https://github.com/vuejs/vue-syntax-highlight), [Atom](https://atom.io/packages/language-vue), [Vim](https://github.com/posva/vim-vue), [Visual Studio Code](https://marketplace.visualstudio.com/items/liuji-jim.vue), [Brackets](https://github.com/pandao/brackets-vue), and [JetBrains products](https://plugins.jetbrains.com/plugin/8057) (WebStorm, PhpStorm, etc). Contributions for other editors/IDEs are highly appreciated! If you are not using any pre-processors in Vue components, you can also get by treating `*.vue` files as HTML in your editor.

lib/loader.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var parse = require('./parser')
33
var genId = require('./gen-id')
44
var normalize = require('./normalize')
55
var loaderUtils = require('loader-utils')
6+
var querystring = require('querystring')
67

78
// internal lib loaders
89
var selectorPath = normalize.lib('selector')
@@ -122,6 +123,13 @@ module.exports = function (content) {
122123
})
123124
}
124125

126+
function buildCustomBlockLoaderString (attrs) {
127+
var noSrcAttrs = Object.assign({}, attrs)
128+
delete noSrcAttrs.src
129+
var qs = querystring.stringify(noSrcAttrs)
130+
return qs ? '?' + qs : qs
131+
}
132+
125133
// stringify an Array of loader objects
126134
function stringifyLoaders (loaders) {
127135
return loaders.map(function (obj) {
@@ -164,6 +172,12 @@ module.exports = function (content) {
164172
return loader + '!' + rewriter + ensureBang(ensureLoader(lang))
165173
case 'script':
166174
return injectString + ensureBang(ensureLoader(lang))
175+
default:
176+
loader = loaders[type]
177+
if (Array.isArray(loader)) {
178+
loader = stringifyLoaders(loader)
179+
}
180+
return ensureBang(loader + buildCustomBlockLoaderString(part.attrs))
167181
}
168182
}
169183
}
@@ -181,7 +195,7 @@ module.exports = function (content) {
181195

182196
function getSelectorString (type, index) {
183197
return selectorPath +
184-
'?type=' + type +
198+
'?type=' + ((type === 'script' || type === 'template' || type === 'styles') ? type : 'customBlocks') +
185199
'&index=' + index + '!'
186200
}
187201

@@ -241,6 +255,32 @@ module.exports = function (content) {
241255
output += '\n'
242256
}
243257

258+
// add requires for customBlocks
259+
if (parts.customBlocks && parts.customBlocks.length) {
260+
var addedPrefix = false
261+
262+
parts.customBlocks.forEach(function (customBlock, i) {
263+
if (!loaders[customBlock.type]) {
264+
loaderContext.emitWarning('Loader for custom block type "' + customBlock.type + '" not found in webpack configuration')
265+
} else {
266+
// require customBlock
267+
customBlock.src = customBlock.attrs.src
268+
var requireString = customBlock.src
269+
? getRequireForImport(customBlock.type, customBlock)
270+
: getRequire(customBlock.type, customBlock, i)
271+
272+
if (!addedPrefix) {
273+
output += '\n/* customBlocks */\n'
274+
addedPrefix = true
275+
}
276+
277+
output += requireString + '\n'
278+
}
279+
})
280+
281+
output += '\n'
282+
}
283+
244284
// we require the component normalizer function, and call it like so:
245285
// normalizeComponent(
246286
// scriptExports,

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,11 @@
6666
"mocha": "^3.2.0",
6767
"node-libs-browser": "^2.0.0",
6868
"normalize-newline": "^3.0.0",
69+
"null-loader": "^0.1.1",
6970
"postcss": "^5.0.21",
7071
"pug": "^2.0.0-beta6",
72+
"raw-loader": "^0.5.1",
73+
"skeleton-loader": "0.0.5",
7174
"stylus": "^0.54.5",
7275
"stylus-loader": "^2.0.0",
7376
"sugarss": "^0.2.0",

test/fixtures/custom-import.vue

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<unit-test src="./unit-test.js">
2+
</unit-test>
3+
4+
<template>
5+
<h2 class="red">{{msg}}</h2>
6+
</template>
7+
8+
<script>
9+
export default {
10+
data () {
11+
return {
12+
msg: 'Hello from Component A!'
13+
}
14+
}
15+
}
16+
</script>
17+
18+
<style>
19+
comp-a h2 {
20+
color: #f00;
21+
}
22+
</style>

test/fixtures/custom-language.vue

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<unit-test>
2+
describe('example', function () {
3+
it('basic', function (done) {
4+
done();
5+
})
6+
})
7+
</unit-test>
8+
9+
<documentation>
10+
This is example documentation for a component.
11+
</documentation>
12+
13+
<template>
14+
<h2 class="red">{{msg}}</h2>
15+
</template>
16+
17+
<script>
18+
export default {
19+
data () {
20+
return {
21+
msg: 'Hello from Component A!'
22+
}
23+
}
24+
}
25+
</script>
26+
27+
<style>
28+
comp-a h2 {
29+
color: #f00;
30+
}
31+
</style>

test/fixtures/custom-options.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<unit-test foo="bar" opt2="value2">
2+
describe('example', function () {
3+
it('basic', function (done) {
4+
done();
5+
})
6+
})
7+
</unit-test>

test/fixtures/unit-test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
describe('example', function () {
2+
it('basic', function (done) {
3+
done();
4+
})
5+
})

0 commit comments

Comments
 (0)