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 相关文章推荐
Jquery中对数组的操作代码
Aug 12 Javascript
推荐9款炫酷的基于jquery的页面特效
Dec 07 Javascript
理解和运用JavaScript的闭包机制
Aug 13 Javascript
jQuery获取多种input值的简单实现方法
Jun 20 Javascript
多种方式实现js图片预览
Dec 12 Javascript
浅谈js for循环输出i为同一值的问题
Mar 01 Javascript
JS按钮闪烁功能的实现代码
Jul 21 Javascript
JS获取指定月份的天数两种实现方法
Jun 22 Javascript
Elementui表格组件+sortablejs实现行拖拽排序的示例代码
Aug 28 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
Sep 28 Javascript
vue页面加载时的进度条功能(实例代码)
Jan 13 Javascript
vue webpack build资源相对路径的问题及解决方法
Jun 04 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 利用socket发送HTTP请求(GET,POST)
2015/08/24 PHP
thinkphp跨库操作的简单代码实例
2016/09/22 PHP
实例介绍PHP删除数组中的重复元素
2019/03/03 PHP
JS 文件本身编码转换 图文教程
2009/10/12 Javascript
优化javascript的执行速度
2010/01/23 Javascript
node.js chat程序如何实现Ajax long-polling长链接刷新模式
2012/03/13 Javascript
获取内联和链接中的样式(js代码)
2013/04/11 Javascript
jQuery中appendTo()方法用法实例
2015/01/08 Javascript
jquery动态改变div宽度和高度
2015/02/09 Javascript
javascript日期处理函数,性能优化批处理
2015/09/06 Javascript
简单实现js选项卡切换效果
2016/02/03 Javascript
Bootstrap Chart组件使用教程
2016/04/28 Javascript
Jquery根据浏览器窗口改变调整大小的方法
2017/02/07 Javascript
基于Bootstrap的网页设计实例
2017/03/01 Javascript
使用gulp搭建本地服务器并实现模拟ajax
2017/04/05 Javascript
angularjs实现时间轴效果的示例代码
2017/11/29 Javascript
微信小程序使用modal组件弹出对话框功能示例
2017/11/29 Javascript
vue生成token并保存到本地存储中
2018/07/17 Javascript
Python中常见的数据类型小结
2015/08/29 Python
python 拷贝特定后缀名文件,并保留原始目录结构的实例
2018/04/27 Python
Python基于机器学习方法实现的电影推荐系统实例详解
2019/06/25 Python
python numpy实现rolling滚动案例
2020/06/08 Python
BannerBuzz加拿大:在线定制横幅印刷、广告和标志
2020/03/10 全球购物
PHP如何去执行一个SQL语句
2016/03/05 面试题
酒店总经理工作职责
2013/12/13 职场文书
境外导游求职信
2014/02/27 职场文书
奥巴马开学演讲稿
2014/05/15 职场文书
工程承诺书怎么写
2014/05/24 职场文书
2015年全国爱眼日活动小结
2015/02/27 职场文书
小学教师岗位职责
2015/04/02 职场文书
客户经理岗位职责大全
2015/04/09 职场文书
浪漫的婚礼主持词
2015/06/30 职场文书
提档介绍信范文
2015/10/22 职场文书
《自己去吧》教学反思
2016/02/16 职场文书
Nginx+Tomcat实现负载均衡、动静分离的原理解析
2021/03/31 Servers
继承Win10缺点!教你关闭Win11烦人的网络搜索
2021/11/23 数码科技