新思路:模板引擎Templet-js,语法糖简洁,实现代码简洁
发布于 1 个月前 作者 index-js 1308 次浏览 来自 分享

想法

不管是造轮子和新想法, 自己做出来的东西也需要推广 希望得到大家的认可,能帮助到大家,有问题也可以得到反馈 如果打扰到大家,不好意思!

要点

模板引擎拆分,根据语法不同,不用单独区分JS和HTML,只需要变量替换 思路简单,实现简单,兼顾一下Browser和Node

说明

Github地址:https://github.com/index-js/templet-js npm地址:https://www.npmjs.com/package/templet-js

语法说明:https://github.com/index-js/templet-js/blob/master/README_zh.md 浏览器示例(可直接运行HTML):https://github.com/index-js/templet-js/blob/master/test/browser/test.html

规则

  1. 由于JS语句和HTML的特殊性,采用混合写法,自动解析,{{}}和${}作变量替换
  2. 每行单独处理进行编译,"<“开始视作HTML,”|"开始当做纯文本,其它视作JS语句
  3. 除了JS语句,其它行都会进行变量替换;如果出现冲突符号,需要转义输出
  4. 非空首字符是"<"、"|"和script/style标签内部和多行注释内部,都会当做纯文本处理
  5. 内部语法是ES6的Template String 和 Arrow Function,以及解析函数new Function,主要使用正则替换和字符串拼接
  6. 新增: 小数点.开头函数,子组件,可传参

内部逻辑都有了,可能上面还有一些没有提到,如果发现,可以加上去

<html>
<body>
<script type="text/javascript" src="http://jslang.org/templet.js"></script>
<script type="test" id="test_dom">
  <p>x={{x}}</p> 会将内容escape转义输出
  <style>
    body: {
      width: ${x} // 原始内容直接输出
    }
  </style>
  for (var i = 0; i <= 5; i ++) { // 直接运行的JS语句
    <div>i={{i}}</div>
  }
  <div>
    | 多行文本
    | 多行文本
    | JS语句 for(var i = 0; i <= 5; i ++) {
    | 
    | }
  </div>
  <!-- 
	annotation
	annotation
	// 下面是子模板调用
  -->
  .child({x: i + 5, y: false})
</script>
<script type="test_child" id="child_dom">
  <div>number - {{x}}</div>
  <p>boolean - {{y}}</p>
</script>
<script type="text/javascript">
  var code = document.getElementById('test_dom').innerHTML
  var child = document.getElementById('child_dom').innerHTML
  var result = new Templet(code, { compress: false }).render({
	x: 0,
	child: new Templet(child)
  })
  console.log(result)
  document.body.innerHTML = result
</script>
</body>
</html>

声明

之前或许有类似实现的,不过就我而言,有一些自己的想法改造和优化 比如类似:https://gitee.com/tianqiq/tpl.js,也参考了其它模板引擎如jade/pug,ejs, handlebars,dot以及vuejs等 不过想法是我之前就有的,只是最近实现

其它

个人喜欢精简一点的东西,不喜欢像node有些package那样很多dependencies,特别是嵌套的dependencies 看到express 30+,Koa20+, 就觉得不舒服,自己写了一个node-net (风格仿写koa,本来想法和koa不一样,结果还是用了context,只是现在精简了许多dependencies,还要最核心部分不一样,其实刚入门Github不久,也算深入学习了)

11 回复

支持一下~ 自己造个轮子至少对轮子的原理了解更清楚。

Node.js五大模板 基本都用过,除了特别个性的pug之外都是大同小异。我个人对模板使用原则是,语法简洁,贴近原生,性能高。所以我用handlebars。

来自✨ Node.js开源项目精选

@vendar 谢谢!你说的那5个框架我用过3个,确实是不错,我这个只是想简化一点

@DerekYeung 我是语法变了,简单化了 比如art-template: {{if user}} <h2>{{user.name}}</h2> {{/if}} 现在直接是(混合的JS和HTML): if (user) { <h2>{{user.name}}</h2> }

@index-js 如果我的html是

if (user) {
}

这种可以输出吗

@DerekYeung 我的设计想法是每行前面加|,和pug/jade纯文本多行一样 style和script和多行注释内部都是当文本处理

@index-js 那还是会影响性能的 个人觉得目前art的解决方案还是最完美的

@DerekYeung 这个我没什么说的,我只是分享一下我的想法,每个人喜好都是不一样的 我个人就喜欢简单一点,不管是风格,还是代码量

👍 支持一个

不过这样的语法并不简洁

  <div>
    | 多行文本
    | 多行文本
    | JS语句 for(var i = 0; i <= 5; i ++) {
    |
    | }
  </div>

可以造一个 JSX 的模版语法。

初次编译模版的时候,使用 Babel 转义, 然后缓存起来.

  <div>
   多行文本
   多行文本
   {
   	... js 代码
   }
  </div>

或许 jsx 思想,模版转义成为 function 调用,也不失为一中办法

@axetroy 关于这个,确实没有考虑那么多,当初想法jade的 | 纯文本可以用,而且HTML的多行文本也会自动合并,内容不会那么多 经你提醒,我会考虑加入。参考script/style标签内容,自定义一个新标签,标签内部的内容全部视为纯文本,输出时去掉该标签

回到顶部