说说如何用js实现一个模板引擎
本文同步更新在: https://github.com/whxaxes/blog/issues/4 ,在 github 看文章显示效果会更好一些。
前言
不知不觉就很长时间没造过什么轮子了,以前一直想自己实现一个模板引擎,只是没付诸于行动,最近终于在业余时间里抽了点时间写了一下。因为我们的项目大部分用的是 swig 或者 nunjucks ,于是就想实现一个类似的模板引擎。
至于为什么要做这么一个东西?基本上每一个做前端的人都会有自己的一个框架梦,而一个成熟的前端框架,模板编译能力就是其中很重要的一环,虽然目前市面上的大部分框架 vue、angular 这些都是属于 dom base 的,而 swig nunjucks ejs这些都是属于 string base 的,但是其实实现起来都是差不多的。不外乎都是 Template
=parse=> Ast
=render=>String
。
再者,做一个模板引擎,个人感觉还是对自身的编码能力的提升还是很有帮助的,在性能优化、正则、字符解析上尤为明显。在日后的业务需求中,如果有一些需要解析字符串相关的需求,也会更得心应手。
功能分析
一个模板引擎,在我看来,就是由两块核心功能组成,一个是用来将模板语言解析为 ast(抽象语法树)。还有一个就是将 ast 再编译成 html。
先说明一下 ast 是什么,已知的可以忽略。
抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。
在实现具体逻辑之前,先决定要实现哪几种 tag 的功能,在我看来,for
,if else
,set
,raw
还有就是基本的变量输出,有了这几种,模板引擎基本上也就够用了。除了 tag,还有就是 filter 功能也是必须的。
构建 AST
我们需要把模板语言解析成一个又一个的语法节点,比如下面这段模板语言:
<div>
{% if test > 1 %}
{{ test }}
{% endif %}
</div>
很明显,div 将会被解析为一个文本节点,然后接着是一个块级节点 if ,然后 if 节点下又有一个变量子节点,再之后有是一个
说说如何用js实现一个模板引擎的更多相关文章
- Jade —— 源于 Node.js 的 HTML 模板引擎
2013-12-11 发布 Jade —— 源于 Node.js 的 HTML 模板引擎 开源项目介绍 web 模板引擎 node.js jade 207.8k 次阅读 · 读完需要 69 分钟 ...
- handlebars——另外一个模板引擎
什么是handlebars? handlebars库是另外一个模板引擎,他继承mustache(胡子),感觉没有jade(珠宝)好听,他不允许在模板中写很多JavaScript的逻辑.这有助于保持模板 ...
- 如何用 js 实现一个 class 类函数
如何用 js 实现一个 class 类函数 原理 实现方式 总结 refs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refere ...
- 如何用 js 实现一个 apply 函数
如何用 js 实现一个 apply 函数 原理 实现方式 总结 refs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referen ...
- 如何用 js 实现一个 call 函数
如何用 js 实现一个 call 函数 原理 实现方式 总结 refs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referenc ...
- 如何用 js 实现一个 sleep 函数
如何用 js 实现一个 sleep 函数 原理 实现方式 总结 refs js sleep xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- 如何用 js 实现一个 new 函数
如何用 js 实现一个 new 函数 原理 new 关键字实现经过了如下过程 创建一个空对象 obj = {} 链接到原型 obj.proto = constructor.prototype 绑定 t ...
- 如何用 js 实现一个 bind 函数
如何用 js 实现一个 bind 函数 原理 实现方式 总结 refs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referenc ...
- 如何用 js 实现一个类似微信红包的随机算法
如何用 js 实现一个类似微信红包的随机算法 js, 微信红包, 随机算法 "use strict"; /** * * @author xgqfrms * @license MIT ...
随机推荐
- Pomelo的component组件
pomelo的核心是由一系列松耦合的component组成,同时我们也可以实现我们自己的component来完成一些自己定制的功能.对于我们的聊天应用,我们尝试给其增加一个component,目的是展 ...
- V8 Javascript 引擎设计理念
Netscape Navigator 在 90 在年代中期对 JavaScript 进行了集成,这让网页开发人员对 HTML 页面中诸如 form .frame 和 image 之类的元素的访问变得非 ...
- jQuery获取URL中所带参数的办法
可以使用正则表达式进行结果的拆分: http://www.cnblogs.com/babycool/p/3169058.html 可以直接进行所需内容的split: http://blog.scien ...
- ASP.NET Zero--12.一个例子(5)商品分类管理-编辑分类
1.添加编辑按钮 打开文件Index.js [..\MyCompanyName.AbpZeroTemplate.Web\Areas\Mpa\Views\Category\Index.js] 在acti ...
- 从新手到高手c++全方位学习 pdf + 视频教程 共18章
淘宝已经和谐了这个网站,原网址:https://item.taobao.com/item.htm?spm=a1z09.8149145.0.0.mb00D0&id=17350311256& ...
- 关于a.b和a[b]的区别
在写代码的过程中,我们经常可以看到a.b或啊a[b],但是他们有什么区别呢: 简单说一下吧,有自己的还用群友的大力支持! 在js的对象中 var arr = {a:"b",b:&q ...
- gcc 简单编译流程
注意:GCC在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,可在编译时加上-static选项,强制使用静态链接库. gcc -static 此选项将禁止使用动态库,所以,编 ...
- list与数组转换
1.数组转换list (1) List myList = new ArrayList(); String[] myStringArray = new String[] {"Java" ...
- [转]CentOS 6.3下Samba服务器的安装与配置
一.简介 Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件,而SMB是Server Message Block的缩写,即为服务器消息块 ,SMB主要是作为Microsoft的 ...
- [Hadoop] - 异常Cannot obtain block length for LocatedBlock
在Flume NG+hadoop的开发中,运行mapreduce的时候出现异常Error: java.io.IOException: Cannot obtain block length for Lo ...