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 相关文章推荐
Mootools 1.2 手风琴(Accordion)教程
Sep 15 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
Dec 30 Javascript
扩展jquery实现客户端表格的分页、排序功能代码
Mar 16 Javascript
深入理解JavaScript系列(12) 变量对象(Variable Object)
Jan 16 Javascript
如何让页面加载完成后执行js
Jun 26 Javascript
jquery实现可横向和竖向展开的动态下滑菜单效果
Aug 24 Javascript
node.js使用cluster实现多进程
Mar 17 Javascript
jQuery Mobile中的button按钮组件基础使用教程
May 23 Javascript
BootStrap表单宽度设置方法
Mar 10 Javascript
vue.js数据绑定的方法(单向、双向和一次性绑定)
Jul 13 Javascript
JavaScript如何实现元素全排列实例代码
May 14 Javascript
Vue中错误图片的处理的实现代码
Nov 07 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的类树(支持无限分类)
2006/10/09 PHP
用DBSQL类加快开发MySQL数据库程序的速度
2006/10/09 PHP
php 操作excel文件的方法小结
2009/12/31 PHP
解析php中curl_multi的应用
2013/07/17 PHP
慎用 somefunction.prototype 分析
2009/06/02 Javascript
javascript 新浪背投广告实现代码
2009/07/07 Javascript
jQuery+JSON+jPlayer实现QQ空间音乐查询功能示例
2013/06/17 Javascript
页面加载完成后再执行JS的jquery写法以及区别说明
2014/02/22 Javascript
javascript中callee与caller的区别分析
2015/04/20 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
angularjs学习笔记之完整的项目结构
2015/09/26 Javascript
Node.js环境下编写爬虫爬取维基百科内容的实例分享
2016/06/12 Javascript
Bootstrap菜单按钮及导航实例解析
2016/09/09 Javascript
微信小程序 页面传参实例详解
2016/11/16 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
2017/01/30 Javascript
浅谈js中的变量名和函数名重名
2017/02/13 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
Vue插件打包与发布的方法示例
2018/08/20 Javascript
jQuery插件实现的日历功能示例【附源码下载】
2018/09/07 jQuery
vue-cli2与vue-cli3在一台电脑共存的实现方法
2019/09/25 Javascript
Vue中img的src是动态渲染时不显示的解决
2019/11/14 Javascript
antd日期选择器禁止选择当天之前的时间操作
2020/10/29 Javascript
Python2.7基于淘宝接口获取IP地址所在地理位置的方法【测试可用】
2017/06/07 Python
django中forms组件的使用与注意
2019/07/08 Python
详解Python的三种拷贝方式
2020/02/11 Python
Pycharm配置PyQt5环境的教程
2020/04/02 Python
Canvas在超级玛丽游戏中的应用详解
2021/02/06 HTML / CSS
FC-Moto丹麦:欧洲最大的摩托车服装和头盔商店之一
2019/08/20 全球购物
如何启动时不需输入用户名与密码
2014/05/09 面试题
优秀应届毕业生自荐信
2013/11/16 职场文书
群众路线批评与自我批评
2014/02/06 职场文书
挂牌仪式策划方案
2014/05/18 职场文书
一个独生女的故事观后感
2015/06/04 职场文书
宝宝满月祝酒词
2015/08/10 职场文书
2019年个人工作总结范文
2019/03/25 职场文书
剑指Offer之Java算法习题精讲二叉树的构造和遍历
2022/03/21 Java/Android