导航
loaders 文件夹,创建 tpl-loader.js函数(loader 就是个函数)resolveLoader.module 让其除了从 node_modules 中找 loader 外,还能从我们创建的 loaders文件夹下找对应 loaderrules ,当遇见 .tpl 文件时,用我们的 tpl-loader 解析tpl-loader 其实就是个函数,会有个 source 参数,内容就是 tpl 文件中的源码MyTitleView({})),最终交给 babel-loader 程序会给我们把字符串转为 JS 程序tpl-loader
function tplLoader(source) {
// webpack找到 .tpl 文件后,会找我们这个loader
// 并把文件中的资源放到 source 变量 中来
return `
export default (component) => {
component.template = \\`${source}\\`;
return component;
}
`
}
使用
import './MyTitle.scss';
import MyTitleView from './MyTitle.tpl';
export default MyTitleView({
data() {
return {
title: 'This is my TITLE',
subTitle: 'This is my SUB_TITLE'
}
},
methods: {
handleTitleClick(e) {
console.log(e.target.innerText);
}
}
}, {
template: true, // 开发时是否打印 template、data、methods
data: true,
methods: true
});
MyTitle.tpl
<div>
<h1 @click="handleTitleClick($event)">{{ title }}</h1>
<h2 @click="handleTitleClick($event)">{{ subTitle }}</h2>
</div>
MyTitle.scss
h1 {
color: red;
}
h2 {
color: purple;
}
index.js
import './MyTitle.scss';
import MyTitleView from './MyTitle.tpl';
export default MyTitleView({
data() {
return {
title: 'This is my TITLE',
subTitle: 'This is my SUB_TITLE'
}
},
methods: {
handleTitleClick(e) {
console.log(e.target.innerText);
}
}
});
<template>
<div>
<my-title></my-title>
</div>
</template>
<script>
import MyTitle from './components/MyTitle/index';
export default {
name: 'App',
components: {
MyTitle
}
}
</script>
<style>
</style>
让 webpack 使用 tpl-loader 去解析我们的文件:
...
module.exports = {
...
resolveLoader: {
modules: [
'node_modules',
resolve(__dirname, './loaders')
]
},
// 合并loader,先在 node_modules 中找
// 找不到 就在 loaders 文件夹下找
module: {
rules: [
{
test: /\\.tpl$/,
loader: 'tpl-loader'
}, // 处理 .tpl 文件
...
]
},
...
}
接下来我们在根目录创建 loaders 文件夹,并创建 tpl-loader :
tpl-loader/index.js
function tplLoader(source) {
// webpack找到 .tpl 文件后,会找我们这个loader
// 并把文件中的资源放到 source 变量 中来
return `
export default (component) => {
component.template = \\`${source}\\`;
return component;
}
`
}
// component.template = \\`${source}\\`; 这一段为什么要转义,因为我们实际在写模板时就用了 `` 这个东西:
// template: `
// 为了写多行,我们template用了 ``
// `
// loader 在 node 环境运行,所以用 COMMONJS 语法
module.exports = tplLoader;

我们再 npm run dev 就能正常显示了:

function tplLoader(source) {
// webpack找到 .tpl 文件后,会找我们这个loader
// 并把文件中的资源放到 source 变量 中来
return `
export default (component) => {
if (Object.prototype.toString.call(component) !== '[object Object]') {
throw new Error('component must be the type of Object.');
}
component.template = \\`${source}\\`;
return component;
}
`
}
// component.template = \\`${source}\\`; 这一段为什么要转义,因为我们实际在写模板时就用了 `` 这个东西:
// template: `
// 为了写多行,我们template用了 ``
// `
// loader 在 node 环境运行,所以用 COMMONJS 语法
module.exports = tplLoader;
此时当传递空就会报错:
import './MyTitle.scss';
import MyTitleView from './MyTitle.tpl';
export default MyTitleView();

tpl-loader
function tplLoader(source) {
// webpack找到 .tpl 文件后,会找我们这个loader
// 并把文件中的资源放到 source 变量 中来
return `
export default (component, { template, data, methods }) => {
if (Object.prototype.toString.call(component) !== '[object Object]') {
throw new Error('component must be the type of Object.');
}
if (template) {
console.log(\\`${source}\\`);
}
if (component.data && data) {
console.log(component.data());
}
if (component.methods && methods) {
console.log(component.methods);
}
component.template = \\`${source}\\`;
return component;
}
`
}
// component.template = \\`${source}\\`; 这一段为什么要转义,因为我们实际在写模板时就用了 `` 这个东西:
// template: `
// 为了写多行,我们template用了 ``
// `
// loader 在 node 环境运行,所以用 COMMONJS 语法
module.exports = tplLoader;
MyTitle/index.js
import './MyTitle.scss';
import MyTitleView from './MyTitle.tpl';
export default MyTitleView({
data() {
return {
title: 'This is my TITLE',
subTitle: 'This is my SUB_TITLE'
}
},
methods: {
handleTitleClick(e) {
console.log(e.target.innerText);
}
}
}, {
template: true, // 开发时是否打印 template、data、methods
data: true,
methods: true
});

webpack.config.js
...
module.exports = {
...
resolveLoader: {
modules: [
'node_modules',
resolve(__dirname, './loaders')
]
},
// 合并loader,先在 node_modules 中找
// 找不到 就在 loaders 文件夹下找
module: {
rules: [
{
test: /\\.tpl$/,
loader: 'tpl-loader',
options: {
consoleLog: true, // 是否展示调试log信息
}
}, // 处理 .tpl 文件
...
]
},
...
}
tpl-loader
const { getOptions } = require('loader-utils');
function tplLoader(source) {
// webpack找到 .tpl 文件后,会找我们这个loader
// 并把文件中的资源放到 source 变量 中来
// 拿到 webpack 中的配置设置
const { consoleLog } = getOptions(this);
if (consoleLog) {
return `
export default (component, { template, data, methods }) => {
if (Object.prototype.toString.call(component) !== '[object Object]') {
throw new Error('component must be the type of Object.');
}
if (template) {
console.log(\\`${source}\\`);
}
if (component.data && data) {
console.log(component.data());
}
if (component.methods && methods) {
console.log(component.methods);
}
component.template = \\`${source}\\`;
return component;
}
`
} else {
return `
export default (component, { template, data, methods }) => {
if (Object.prototype.toString.call(component) !== '[object Object]') {
throw new Error('component must be the type of Object.');
}
component.template = \\`${source}\\`;
return component;
}
`
}
}
// component.template = \\`${source}\\`; 这一段为什么要转义,因为我们实际在写模板时就用了 `` 这个东西:
// template: `
// 为了写多行,我们template用了 ``
// `
// loader 在 node 环境运行,所以用 COMMONJS 语法
module.exports = tplLoader;