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 ...@@ -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. 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 ### Style Injection
Client-side style injection now injects all styles upfront to ensure consistent behavior between development and extracted mode. 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 ...@@ -200,6 +244,7 @@ The following options have been deprecated and should be configured using normal
- `cssSourceMap` - `cssSourceMap`
- `buble` - `buble`
- `extractCSS` - `extractCSS`
- `template`
The following options have been deprecated and should be configured using the new `compilerOptions` option: 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> <template lang="pug">
<div> div(ok)
<h1 :class="$style.red">{{ msg }}</h1> h1(:class="$style.red") hello
</div>
</template> </template>
<script> <script>
......
div(ok)
h1(:class="$style.red") hello
...@@ -15,17 +15,37 @@ module.exports = { ...@@ -15,17 +15,37 @@ module.exports = {
}, },
module: { module: {
rules: [ rules: [
// { loader: require.resolve('./debugger') },
{ {
test: /\.vue$/, test: /\.vue$/,
loader: 'vue-loader' loader: 'vue-loader'
}, },
// example to apply loader to a custom block without lang="xxx"
// this rule applies to <foo> blocks
{ {
resourceQuery: /blockType=foo/, resourceQuery: /blockType=foo/,
loader: 'babel-loader' 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$/, test: /\.css$/,
oneOf: [ oneOf: [
// this applies to <style module>
{ {
resourceQuery: /module/, resourceQuery: /module/,
use: [ use: [
...@@ -39,6 +59,7 @@ module.exports = { ...@@ -39,6 +59,7 @@ module.exports = {
} }
] ]
}, },
// this applies to <style> or <style scoped>
{ {
use: [ use: [
'vue-style-loader', 'vue-style-loader',
...@@ -47,19 +68,16 @@ module.exports = { ...@@ -47,19 +68,16 @@ module.exports = {
} }
] ]
}, },
// exmaple configration for <style lang="scss">
{ {
test: /\.scss$/, test: /\.scss$/,
use: [ use: [
'vue-style-loader', 'vue-style-loader',
{ 'css-loader',
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]_[hash:base64:8]'
}
},
{ {
loader: 'sass-loader', loader: 'sass-loader',
// global data for all components
// this can be read from a scss file
options: { options: {
data: '$color: red;' data: '$color: red;'
} }
......
...@@ -34,9 +34,6 @@ module.exports = function (source) { ...@@ -34,9 +34,6 @@ module.exports = function (source) {
filename: this.resourcePath, filename: this.resourcePath,
compiler, compiler,
compilerOptions, compilerOptions,
// handle possible lang="xxx"
preprocessLang: query.lang,
preprocessOptions: options.template,
// allow customizing behavior of vue-template-es2015-compiler // allow customizing behavior of vue-template-es2015-compiler
transpileOptions: options.transpileOptions, transpileOptions: options.transpileOptions,
transformAssetUrls: options.transformAssetUrls || true, transformAssetUrls: options.transformAssetUrls || true,
......
...@@ -34,11 +34,15 @@ test('pre-processors', done => { ...@@ -34,11 +34,15 @@ test('pre-processors', done => {
module: { module: {
rules: [ rules: [
{ {
test: /\.js/, test: /\.js$/,
loader: 'babel-loader' loader: 'babel-loader'
}, },
{ {
test: /\.stylus/, test: /\.pug$/,
loader: 'pug-plain-loader'
},
{
test: /\.stylus$/,
use: [ use: [
'vue-style-loader', 'vue-style-loader',
'css-loader', 'css-loader',
...@@ -112,6 +116,26 @@ test('template import', done => { ...@@ -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 => { test('script import', done => {
mockBundleAndRun({ mockBundleAndRun({
entry: 'script-import.vue' 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 => { ...@@ -252,3 +252,43 @@ test('custom compiler directives', done => {
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: ...@@ -6646,6 +6646,12 @@ pug-parser@^5.0.0:
pug-error "^1.3.2" pug-error "^1.3.2"
token-stream "0.0.1" 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: pug-runtime@^2.0.4:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.4.tgz#e178e1bda68ab2e8c0acfc9bced2c54fd88ceb58" 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