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实现表格数据的动态添加与统计的代码
Jan 31 Javascript
jQuery 写的简单打字游戏可以提示正确和错误的次数
Jul 01 Javascript
JavaScript实现彩虹文字效果的方法
Apr 16 Javascript
javascript实现鼠标拖动改变层大小的方法
Apr 30 Javascript
JavaScript中setMonth()方法的使用详解
Jun 11 Javascript
jquery简单实现幻灯片的方法
Aug 03 Javascript
再谈javascript注入 黑客必备!
Sep 14 Javascript
浅谈HTTP 缓存的那些事儿
Oct 17 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
Feb 28 Javascript
vue 实现搜索的结果页面支持全选与取消全选功能
May 10 Javascript
vue使用axios实现excel文件下载的功能
Jul 16 Javascript
JQuery基于FormData异步提交数据文件
Sep 01 jQuery
解决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
深入HTTP响应状态码速查表的详解
2013/06/07 PHP
使用Math.floor与Math.random取随机整数的方法详解
2013/05/07 Javascript
如何正确使用Nodejs 的 c++ module 链接到 OpenSSL
2014/08/03 NodeJs
超级简单实现JavaScript MVC 样式框架
2015/03/24 Javascript
实例代码详解jquery.slides.js
2015/11/16 Javascript
jQuery实现文本框邮箱输入自动补全效果
2015/11/17 Javascript
整理关于Bootstrap排版的慕课笔记
2017/03/29 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
文本溢出插件jquery.dotdotdot.js使用方法详解
2017/06/22 jQuery
Vue单页面应用保证F5强刷不清空数据的解决方案
2018/01/31 Javascript
vue-router 源码实现前端路由的两种方式
2018/07/02 Javascript
微信小程序个人中心的列表控件实现代码
2020/04/26 Javascript
echarts实现获取datazoom的起始值(包括x轴和y轴)
2020/07/20 Javascript
Python使用Flask框架同时上传多个文件的方法
2015/03/21 Python
基于python时间处理方法(详解)
2017/08/14 Python
python操作MySQL 模拟简单银行转账操作
2017/09/27 Python
Python探索之Metaclass初步了解
2017/10/28 Python
Sanic框架安装与简单入门示例
2018/07/16 Python
python整合ffmpeg实现视频文件的批量转换
2019/05/31 Python
Python3 Tkinkter + SQLite实现登录和注册界面
2019/11/19 Python
OpenCV 之按位运算举例解析
2020/06/19 Python
Python爬虫UA伪装爬取的实例讲解
2021/02/19 Python
阿联酋电子产品购物网站:Menakart
2017/09/15 全球购物
澳大利亚领先的女帽及配饰公司:Morgan&Taylor
2019/12/01 全球购物
保加利亚服装和鞋类购物网站:Bibloo.bg
2020/11/08 全球购物
路德维希•贝克(LUDWIG BECK)中文官网:德国大型美妆百货
2020/09/19 全球购物
物理教学随笔感言
2014/02/22 职场文书
英语一分钟演讲稿
2014/04/29 职场文书
金融专业毕业生自荐信
2014/06/26 职场文书
国家税务局干部作风整顿整改措施
2014/09/18 职场文书
2014年维修电工工作总结
2014/11/20 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
离婚起诉书范文2015
2015/05/19 职场文书
大学生学习十八届五中全会精神心得体会
2016/01/05 职场文书
2019毕业论文致谢词
2019/06/24 职场文书
《和时间赛跑》读后感3篇
2019/12/16 职场文书