Commit c954f323 authored by Evan You's avatar Evan You

feat: handle <template lang="xxx"> with loaders

BREAKING CHANGE: <template lang="xxx"> are now handled
with webpack loaders as well.
parent 144cc7c1
......@@ -88,6 +88,50 @@ The benefit is that this same rule also applies to plain `*.less` imports from J
v15 also allows using non-serializable options for loaders, which was not possible in previous versions.
### Template Preprocessing
v14 and below uses [consolidate](https://github.com/tj/consolidate.js/) to compile `<template lang="xxx">`. v15 now applies preprocessing for them using webpack loaders instead.
Note that some template loaders such as `pug-loader` exports a compiled templating function instead of plain HTML. In order to pass the correct content to Vue's template compiler, you must use a loader that outputs plain HTML instead. For example, to support `<template lang="pug">`, you can use [pug-plain-loader](https://github.com/yyx990803/pug-plain-loader):
``` js
{
module: {
rules: [
{
test: /\.pug$/,
loader: 'pug-plain-loader'
}
]
}
}
```
If you also intend to use it to import .pug files as HTML strings in JavaScript, you will need to chain `raw-loader` after the preprocessing loader. Note however adding raw-loader would break the usage in Vue components, so you need to have two rules, one of them excluding Vue components:
``` js
{
module: {
rules: [
{
test: /\.pug$/,
oneOf: [
// this applies to <template lang="pug"> in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader']
},
// this applies to pug imports inside JavaScript
{
use: ['raw-loader', 'pug-plain-loader']
}
]
}
]
}
}
```
### Style Injection
Client-side style injection now injects all styles upfront to ensure consistent behavior between development and extracted mode.
......@@ -200,6 +244,7 @@ The following options have been deprecated and should be configured using normal
- `cssSourceMap`
- `buble`
- `extractCSS`
- `template`
The following options have been deprecated and should be configured using the new `compilerOptions` option:
......
module.exports = function (...args) {
this.callback(null, ...args)
}
module.exports.pitch = function (request) {
// debug
}
<template>
<div>
<h1 :class="$style.red">{{ msg }}</h1>
</div>
<template lang="pug">
div(ok)
h1(:class="$style.red") hello
</template>
<script>
......
div(ok)
h1(:class="$style.red") hello
......@@ -15,17 +15,37 @@ module.exports = {
},
module: {
rules: [
// { loader: require.resolve('./debugger') },
{
test: /\.vue$/,
loader: 'vue-loader'
},
// example to apply loader to a custom block without lang="xxx"
// this rule applies to <foo> blocks
{
resourceQuery: /blockType=foo/,
loader: 'babel-loader'
},
// example configuring preprocessor for <template lang="pug">
{
test: /\.pug$/,
oneOf: [
// this applies to <template lang="pug"> in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader']
},
// this applies to pug imports inside JavaScript
{
use: ['raw-loader', 'pug-plain-loader']
}
]
},
// example configuring CSS Modules
{
test: /\.css$/,
oneOf: [
// this applies to <style module>
{
resourceQuery: /module/,
use: [
......@@ -39,6 +59,7 @@ module.exports = {
}
]
},
// this applies to <style> or <style scoped>
{
use: [
'vue-style-loader',
......@@ -47,19 +68,16 @@ module.exports = {
}
]
},
// exmaple configration for <style lang="scss">
{
test: /\.scss$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]_[hash:base64:8]'
}
},
'css-loader',
{
loader: 'sass-loader',
// global data for all components
// this can be read from a scss file
options: {
data: '$color: red;'
}
......
......@@ -34,9 +34,6 @@ module.exports = function (source) {
filename: this.resourcePath,
compiler,
compilerOptions,
// handle possible lang="xxx"
preprocessLang: query.lang,
preprocessOptions: options.template,
// allow customizing behavior of vue-template-es2015-compiler
transpileOptions: options.transpileOptions,
transformAssetUrls: options.transformAssetUrls || true,
......
......@@ -34,11 +34,15 @@ test('pre-processors', done => {
module: {
rules: [
{
test: /\.js/,
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.stylus/,
test: /\.pug$/,
loader: 'pug-plain-loader'
},
{
test: /\.stylus$/,
use: [
'vue-style-loader',
'css-loader',
......@@ -112,6 +116,26 @@ test('template import', done => {
})
})
test('template import with pre-processors', done => {
mockBundleAndRun({
entry: 'template-import-pre.vue',
module: {
rules: [
{
test: /\.pug$/,
loader: 'pug-plain-loader'
}
]
}
}, ({ window, module }) => {
const vnode = mockRender(module)
// '<div><h1>hello</h1></div>'
expect(vnode.children[0].tag).toBe('h1')
expect(vnode.children[0].children[0].text).toBe('hello')
done()
})
})
test('script import', done => {
mockBundleAndRun({
entry: 'script-import.vue'
......
<template lang="pug" src="./template-import.pug"></template>
<div>
<h1>hello</h1>
</div>
<template lang="pug" src="./template-import.pug"></template>
<template src="./template-import.html"></template>
import Comp1 from './template-pre.vue'
import Comp2 from './template-import-pre.vue'
import html from './template-import.pug'
window.exports = {
Comp1,
Comp2,
html
}
<template lang="pug">
div
h1 hello
</template>
......@@ -252,3 +252,43 @@ test('custom compiler directives', done => {
done()
})
})
test('separate loader configuration for template lang and js imports', done => {
mockBundleAndRun({
entry: './test/fixtures/template-pre.js',
module: {
rules: [
{
test: /\.pug$/,
oneOf: [
// this applies to <template lang="pug"> in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader']
},
// this applies to pug imports inside JavaScript
{
use: ['raw-loader', 'pug-plain-loader']
}
]
}
]
}
}, ({ exports }) => {
function assertRender (vnode) {
expect(vnode.tag).toBe('div')
expect(vnode.children[0].tag).toBe('h1')
expect(vnode.children[0].children[0].text).toBe('hello')
}
// <template lang="pug">
const vnode1 = mockRender(exports.Comp1, {})
assertRender(vnode1)
// <template lang="pug" src="./foo.pug">
const vnode2 = mockRender(exports.Comp2, {})
assertRender(vnode2)
// import html from './foo.pug'
expect(exports.html).toBe('<div><h1>hello</h1></div>')
done()
})
})
......@@ -6646,6 +6646,12 @@ pug-parser@^5.0.0:
pug-error "^1.3.2"
token-stream "0.0.1"
pug-plain-loader@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/pug-plain-loader/-/pug-plain-loader-1.0.0.tgz#cef2a984c90251882109ec2d417a6b433aa6b42a"
dependencies:
loader-utils "^1.1.0"
pug-runtime@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.4.tgz#e178e1bda68ab2e8c0acfc9bced2c54fd88ceb58"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment