前言

今天在看vue-loader预处理器配置相关的内容,突然看到了Pug,然后有了一个疑问:模版引擎原来是预处理器吗?

答案是:YES

说明

这里重点讨论使用不同的js模板引擎作为预处理器,

下面示例使用了pug模板引擎

<template lang="pug">
div
h1 Hello world!
</template>

1. 支持哪些模板引擎

v14 或更低版本使用 consolidate 来编译 <template lang="xxx">, 所以支持的模板引擎,从consolidate的支持列表中可以找到,包括了大部分引擎,

vue-loader/preprocessor.js文件里面,

// loader for pre-processing templates with e.g. pug
const cons = require('consolidate')
const loaderUtils = require('loader-utils')
const { loadOptions } = require('../utils/options-cache') module.exports = function (content) {
const callback = this.async()
const opt = loaderUtils.getOptions(this) || {} if (!cons[opt.engine]) {
return callback(
new Error(
"Template engine '" +
opt.engine +
"' " +
"isn't available in Consolidate.js"
)
)
} // allow passing options to the template preprocessor via `template` option
const vueOptions = loadOptions(opt.optionsId)
if (vueOptions.template) {
Object.assign(opt, vueOptions.template)
} // for relative includes
opt.filename = this.resourcePath cons[opt.engine].render(content, opt, (err, html) => {
if (err) {
return callback(err)
}
callback(null, html)
})
}

可以看到,使用consolidate 进行预处理。

v15 及以上版本,允许对vue组件中的每个部分使用其他的webpack loader,可以正常使用各种模板引擎。

使用@vue/component-compiler-utils 工具编译模板,实际在component-compiler-utils中编译template时,也把consolidate作为预处理器,使用consolidate.render编译成字符串。

2. 引入pug

需安装pug-plain-loader,利用它返回一个编译好的 HTML 字符串,

在最新的vue-cli@3.x 配置中,默认已配置好pug的相关loader, 所以安装完可以直接在<template/>中使用

/* config.module.rule('pug') */
{
test: /\.pug$/,
oneOf: [
/* config.module.rule('pug').oneOf('pug-vue') */
{
resourceQuery: /vue/,
use: [
/* config.module.rule('pug').oneOf('pug-vue').use('pug-plain-loader') */
{
loader: 'pug-plain-loader'
}
]
},
/* config.module.rule('pug').oneOf('pug-template') */
{
use: [
/* config.module.rule('pug').oneOf('pug-template').use('raw') */
{
loader: 'raw-loader'
},
/* config.module.rule('pug').oneOf('pug-template').use('pug-plain') */
{
loader: 'pug-plain-loader'
}
]
}
]
},

3. 引入dotjs或其他模板引擎,

需在vue.confg.js 里面手动配置loader, 配置规则跟引入pug类似,修改相关loader即可。

还有一点比较特殊,该模板引擎对应的loader, 必须返回字符串,

比如我们使用dotjs-loader,来解析dotjs模板,就会报错,然后查看dotjs-loader,发现

return 'export default ' + doT.template(source);

最后返回导出结果, doT.template(source)执行成功后,返回一个匿名函数,

所以想要返回最终的字符串,只有传入数据,执行函数 doT.template(source)(data)。

直接使用dotjs-loader无法达到上面的要求,只有修改loader中的返回格式,具体可以参考pug-plain-loader, 逻辑比较简单,传入模板引擎相关参数,options对应webpack 配置中的options参数,最后返回编译后的字符串。

const pug = require('pug')
const loaderUtils = require('loader-utils') module.exports = function (source) {
const options = Object.assign({
filename: this.resourcePath,
doctype: 'html',
compileDebug: this.debug || false
}, loaderUtils.getOptions(this)) const template = pug.compile(source, options)
template.dependencies.forEach(this.addDependency)
return template(options.data || {})
}

这里可以发现问题,上面代码中options.data只是在webpack配置时传入的,并不是正式的下发数据,使用预处理模板引擎,为了返回字符串,编译函数执行在loader中进行,没有办法传入数据data,参与编译。

而且模板引擎的相关语法,不能与vue 的模板语法冲突,这样会导致js模板引擎解析后,再进行vue 模板解析时报错

如果只是纯静态页面,可以直接把需要经过模板引擎编译的内容部分抽离出去,使用require引入时,webpack会自动对应loader,解析完成后,只需在当前组件中传入data,通过v-html把生成的字符串当成HTML标签解析后输出。

参考

vue-loader中引入模板预处理器的实现

Vue学习(十三)模版引擎算是预处理器吗?的更多相关文章

  1. C学习笔记(9)--- 预处理器,头文件

    1.预处理器: 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤.简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理. 我们将把 C 预处理 ...

  2. vue与node模版引擎的渲染标记{{}}(双花括号)冲突

    由于之前练习koa2,直接渲染的jquery写的传统页面. 这次想偷懒,直接script引入vue,发现渲染不出data值. 渲染引擎用得是xtpl, 找了半天没有发现可以修改xtpl渲染分隔符的配置 ...

  3. vue学习(十三) 删除对象数组中的某个元素

    //html <div id="app"> //v-for循环就不写了 每一条数据最后都有一个删除的超链 .prevent阻止默认的跳转行为 只执行点击事件 <a ...

  4. Vue学习小结(二)

    接上一批,小结(二). 三.导航内容(含左侧导航及顶部面包屑导航) 其实导航条主要根据element-ui的教程进行编写,官网:http://element-ui.cn/#/zh-CN/compone ...

  5. Nodejs学习笔记(五)--- Express安装入门与模版引擎ejs

    目录 前言 Express简介和安装 运行第一个基于express框架的Web 模版引擎 ejs express项目结构 express项目分析 app.set(name,value) app.use ...

  6. Nodejs学习笔记(五)—Express安装入门与模版引擎ejs

    前言 前面也学习了一些Node.js的基本入门知道,现在开始进入Web开发的部分: Node.js提供了http模块,这个模块中提供了一些底层接口,可以直接使用,但是直接开发网站那还是太累了,所以ht ...

  7. C#预处理器指令——学习

    若要详细了解如何使用 C# 预处理器指令选择性地编译代码段,请参阅 #define(C# 参考)和 #if(C# 参考). #define(C# 参考) 地址:https://docs.microso ...

  8. vue使用stylus样式预处理器

    vue使用stylus样式预处理器,样式总是报错,需要从上一行的样式回车换行才不会报错 <style lang="stylus" scoped> .navbar mar ...

  9. Express学习 ------模版引擎(handlebars)

    Handlebars一款js模版引擎,我们在做客户端开发的时候,也可能已经使用过.它语法比较简单,和我们平常写的html 一样,只不过html 中可以加入handlebars 表达式. handleb ...

随机推荐

  1. Netty 学习笔记(1) ------ Hello World

    服务端启动流程 package com.example.netty; import com.example.netty.handler.HelloServerHandler; import io.ne ...

  2. Dart函数

    函数 Dart是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型Function.这意味着函数可以赋值给变量或作为参数传递给其他函数,这是函数式编程的典型特征.同时意味着在Dart语言 ...

  3. Nginx配置中文参数说明

    #定义Nginx运行的用户和用户组 user www www; # #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; # #全局错误日志定义类型,[ debu ...

  4. MySQL(四)数据备份与还原

    数据备份与还原: 备份:将当前已有的数据或者记录保留 还原:将已经保留的数据恢复到对应的表中 为什么要做备份还原: 1.防止数据丢失:被盗.误操作 2.保护数据的记录 数据备份还原的方式很多:数据表备 ...

  5. Raid0,1,5,10,50

    raid0 就是把多个硬盘合并成1个逻辑盘使用,数据读写时对各硬盘同时操作,不同硬盘写入不同数据,速度快. **最少需要2块硬盘 raid1 同时对2个硬盘读写(同样的数据).强调数据的安全性.损坏一 ...

  6. Ansible基础

    Ansible基于Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用YMAL 及Jinja2模板语言. 组件: 核心:ansible 核心模块(Core Modules): ...

  7. dubbo泛化调用 小demo

    前两天刚好有个同事来问是否用过 dubbo泛化 调用,不需要通过指定配置.第一次听到的时候,还是有点懵,但觉得有意思,可以学点东西. 立马百度了,找了demo,这篇比较容易上手(http://www. ...

  8. Python元组内置函数

    Python元组内置函数: len(元组名): 返回元组长度 # len(元组名): # 返回元组长度 tuple_1 = (1,2,3,'a','b','c') print("tuple_ ...

  9. activiti7 导出bpmn文件

    最近在学习springboot+activiti7整合,想做一个导出bpmn文件的功能,查了相关资料,最后没有实现.最后查看了一下代码 找到了方法 如下所示 @GetMapping("exp ...

  10. PHP localtime() 函数

    ------------恢复内容开始------------ 实例 以一个数值数组和一个关联数组的形式输出本地时间: <?phpprint_r(localtime());echo "& ...