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


Posted in Javascript onSeptember 04, 2019

vue-loader 是一个 webpack 的 loader,可以将指定格式编写的 Vue 组件转换为 JavaScript模块

同时,vue-loader 支持使用非默认语言,通过设置语言块的lang属性,就可以使用指定的预处理器,比如最常见的sass 语法:

<style lang="sass">
 ...
</style>

这里重点讨论使用不同的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标签解析后输出。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript 获取字符串字节数的多种方法
Jun 02 Javascript
firefox下frameset取不到值的解决方法
Sep 06 Javascript
JavaScript获取一个范围内日期的方法
Apr 24 Javascript
JavaScript实现的圆形浮动标签云效果实例
Aug 06 Javascript
js实现的全国省市二级联动下拉选择菜单完整实例
Aug 17 Javascript
Javascript动画效果(2)
Oct 11 Javascript
微信小程序 天气预报开发实例代码源码
Jan 20 Javascript
简单实现AngularJS轮播图效果
Apr 10 Javascript
JS实现遍历不规则多维数组的方法
Mar 21 Javascript
微信小程序实现折叠展开效果
Jul 19 Javascript
利用Blob进行文件上传的完整步骤
Aug 02 Javascript
vue 验证两次输入的密码是否一致的方法示例
Sep 29 Javascript
解决layer图标icon不加载的问题
Sep 04 #Javascript
JSX在render函数中的应用详解
Sep 04 #Javascript
关于layui的动态图标不显示的解决方法
Sep 04 #Javascript
vue本地打开build后生成的dist文件夹index.html问题
Sep 04 #Javascript
简单谈谈javascript高级特性
Sep 04 #Javascript
在layui中使用form表单监听ajax异步验证注册的实例
Sep 03 #Javascript
解决mui框架中switch开关通过js控制开或者关状态时小圆点不动的问题
Sep 03 #Javascript
You might like
php在多维数组中根据键名快速查询其父键以及父键值的代码
2011/05/07 PHP
php中ftp_chdir与ftp_cdup函数用法
2014/11/18 PHP
PHP使用stream_context_create()模拟POST/GET请求的方法
2016/04/02 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
Google Map Api和GOOGLE Search Api整合实现代码
2009/07/18 Javascript
asp.net+jquery滚动滚动条加载数据的下拉控件
2010/06/25 Javascript
JavaScript判断窗口是否最小化的代码(跨浏览器)
2010/08/01 Javascript
基于node.js的快速开发透明代理
2010/12/25 Javascript
js获取窗口相对于屏幕左边和上边的位置坐标
2014/05/15 Javascript
node.js中的fs.createWriteStream方法使用说明
2014/12/17 Javascript
jquery实现简易的移动端验证表单
2015/11/08 Javascript
基于javascript如何传递特殊字符
2015/11/30 Javascript
CSS3+JavaScript实现翻页幻灯片效果
2017/06/28 Javascript
javascript ES6 新增了let命令使用介绍
2017/07/07 Javascript
JS实现可切换图片的幻灯切换效果示例
2019/05/24 Javascript
JavaScript Window窗口对象属性和使用方法
2020/01/19 Javascript
python+numpy+matplotalib实现梯度下降法
2018/08/31 Python
python爬虫 execjs安装配置及使用
2019/07/30 Python
Django rstful登陆认证并检查session是否过期代码实例
2019/08/13 Python
python 动态迁移solr数据过程解析
2019/09/04 Python
Python利用 utf-8-sig 编码格式解决写入 csv 文件乱码问题
2020/02/21 Python
Windows下Pycharm远程连接虚拟机中Centos下的Python环境(图文教程详解)
2020/03/19 Python
Pycharm激活方法及详细教程(详细且实用)
2020/05/12 Python
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
消防安全责任书范本
2014/04/15 职场文书
影视广告专业求职信
2014/09/02 职场文书
卫生厅领导班子党的群众路线教育实践活动整改措施
2014/09/20 职场文书
幼师求职自荐信
2015/03/26 职场文书
致短跑运动员加油稿
2015/07/21 职场文书
2016秋季小学开学寄语
2015/12/03 职场文书
创业计划书之珠宝饰品
2019/08/26 职场文书
go语言中切片与内存复制 memcpy 的实现操作
2021/04/27 Golang
浅谈Redis的几个过期策略
2021/05/27 Redis
MySQL优化常用的19种有效方法(推荐!)
2022/03/17 MySQL
MYSQL如何查看操作日志详解
2022/05/30 MySQL
MySQL约束(创建表时的各种条件说明)
2022/06/21 MySQL