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 Timer实现代码
Feb 17 Javascript
jQuery实现随意改变div任意属性的名称和值(部分原生js实现)
May 28 Javascript
jquery获取div距离窗口和父级dv的距离示例
Oct 10 Javascript
可以用鼠标拖动的DIV实现思路及代码
Oct 21 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
Nov 29 Javascript
使用JS画图之点、线、面
Jan 12 Javascript
JS+CSS实现鼠标经过弹出一个DIV框完整实例(带缓冲动画渐变效果)
Mar 25 Javascript
jquery checkbox的相关操作总结
Oct 17 Javascript
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
Jan 09 Javascript
ES6 Generator函数的应用实例分析
Jun 26 Javascript
JavaScript canvas实现跟随鼠标事件
Feb 10 Javascript
浅谈vue2的$refs在vue3组合式API中的替代方法
Apr 18 Vue.js
解决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和Mysqlweb应用开发核心技术 第1部分 Php基础-1 开始了解php
2011/07/03 PHP
php各种编码集详解和以及在什么情况下进行使用
2011/09/11 PHP
Zend Framework实现多服务器共享SESSION数据的方法
2016/03/22 PHP
使用php从身份证号中获取一系列线索(星座、生肖、生日等)
2016/05/11 PHP
PHP使用openssl扩展实现加解密方法示例
2020/02/20 PHP
讨论javascript(一)工厂方式 js面象对象的定义方法
2009/12/15 Javascript
javascript学习笔记(十三) js闭包介绍(转)
2012/06/20 Javascript
jqgrid 表格数据导出实例
2013/11/21 Javascript
javascript 获取网页标题代码实例
2014/01/22 Javascript
再谈javascript原型继承
2014/11/10 Javascript
JavaScript函数学习总结以及相关的编程习惯指南
2015/11/16 Javascript
angularjs 中$apply,$digest,$watch详解
2016/10/13 Javascript
关于vue中的ajax请求和axios包问题
2018/04/19 Javascript
jQuery实现动态加载select下拉列表项功能示例
2018/05/31 jQuery
vue devtools的安装与使用教程
2018/08/08 Javascript
React中使用外部样式的3种方式(小结)
2019/05/28 Javascript
vue项目引入ts步骤(小结)
2019/10/31 Javascript
微信小程序 wx.getUserInfo引导用户授权问题实例分析
2020/03/09 Javascript
autojs 蚂蚁森林能量自动拾取即给指定好友浇水的实现方法
2020/05/03 Javascript
[02:56]DOTA2英雄基础教程 巨魔战将
2013/12/10 DOTA
Python的Django框架下管理站点的基本方法
2015/07/17 Python
Python简单删除列表中相同元素的方法示例
2017/06/12 Python
python实现发送邮件功能
2017/07/22 Python
flask框架视图函数用法示例
2018/07/19 Python
pandas dataframe 中的explode函数用法详解
2020/05/18 Python
10个很棒的 CSS3 开发工具 推荐
2011/05/16 HTML / CSS
HTML5画渐变背景图片并自动下载实现步骤
2013/11/18 HTML / CSS
怎样在程序里获得一个空指针
2015/01/24 面试题
新手上路标语
2014/06/20 职场文书
中秋节国旗下演讲稿
2014/09/05 职场文书
2014年教师党员自我评议
2014/09/19 职场文书
幼师求职自荐信
2015/03/26 职场文书
利用ajax+php实现商品价格计算
2021/03/31 PHP
CSS几步实现赛博朋克2077风格视觉效果
2021/06/16 HTML / CSS
python保存图片的四个常用方法
2022/02/28 Python
PYTHON基于Pyecharts绘制常见的直角坐标系图表
2022/04/28 Python