Nodejs 浏览器端 EJS Handlebars doT 如何选择?

Nodejs 浏览器端 EJS Handlebars doT 如何选择?

生成静态页面我喜欢 Jade, 但浏览器端模板引擎 Jade 就没有详细的文档来提升了

目前在用的是 Handlebars, Handlebars 是 logic-less 的引擎 有 Sublime Text 支持, 命令行编译工具, 性能也不错 但 logic-less 导致大量逻辑操作要在 helpers 文件里定义 加上有些判断和模板嵌套, 于是感觉整个在 helpers 相关部分变乱, 很想替换掉

看了下 EJS Eco 和 doT

doT 号称性能最快, 可以预编译, 但是文档没有详细给出预编译的命令行工具 命令行有 bug, 更新不长, 没有 Sublime Text 支持, 看得我有些迟疑啊 但基本的 JS 逻辑在 doT 能好恨书写的样子… 性能当然相当好

EJS 和 Eco 感觉上熟悉一些, JS 逻辑在里边也比较自然, 有 CNode 的 EJS 经验 预编译方面, Eco 有命令行, EJS 是通过暴露 API 提供编译的功能的 Sublime 插件两者都有. 目前基本的担心是性能上会不足, 而我们的前端应用又担心性能

另外一点是 Chrome 插件的 Content Security Policy 会对模板引擎有限制 目前这块更不熟悉, 但 Handlebars 和 Eco 网上有确认没问题的, 等待深入看细节

目前查了很多资料, 但是没有实际操作经验, 也不清楚如何测试, 哪位同学实际项目中用到过的可以指点一下吗?

参考: WEB模板jade、ejs、handlebars 万行代码解释效率比较,jade完败 Template-Engine-Chooser! jsperf: EJS vs Handlebars jsperf: JavaScript template language shootoff jsperf: performance comparison of jQuery Template vs underscore vs string append vs mustache vs handlebars vs icanhaz vs milk vs swig for table Javascript Templates and Chrome’s Content Security Policy sstephenson/eco visionmedia/ejs jonnsl/ejs-compile Javascript Template Engines that work with Chrome’s Content Security Policy doT: http://blog.rogerdudler.com/post/29910317444/client-side-templating-with-dot-js http://olado.github.io/doT/tutorial.html#intro http://jsperf.com/dot-vs-handlebars/11 http://olado.github.io/doT/


17 回复

Node.js 浏览器端 EJS Handlebars doT 如何选择?

生成静态页面时,我倾向于使用 Jade,但浏览器端模板引擎 Jade 并没有详细的文档支持。因此,我在寻找其他合适的替代方案。

目前我在用的是 Handlebars,这是一个无逻辑的模板引擎。它提供了 Sublime Text 支持和命令行编译工具,并且性能也很好。然而,由于它是无逻辑的,大量的逻辑操作需要在 helpers 文件中定义,这使得代码变得混乱。尤其是当处理复杂的条件判断和模板嵌套时,感觉整个项目在 helpers 部分变得杂乱无章,因此我想更换一个更适合的模板引擎。

EJS、Eco 和 doT

我查看了 EJS、Eco 和 doT。

  1. doT

    • 宣称是性能最快的模板引擎,并且支持预编译。
    • 但是,它的文档并没有详细说明如何使用命令行工具进行预编译,而且命令行工具存在一些 Bug,更新频率不高,也没有 Sublime Text 插件支持。这让我感到有些迟疑。不过,doT 在编写基本的 JS 逻辑时显得非常自然,性能也非常优秀。
  2. EJS 和 Eco

    • 我对 EJS 和 Eco 更加熟悉,JS 逻辑在这些引擎中也更加自然。EJS 通过暴露 API 来提供编译功能,而 Eco 则有命令行工具。两者都有 Sublime Text 插件支持。当前的主要担忧是性能,因为我们的前端应用对性能非常敏感。

    下面是一个简单的 EJS 示例:

    <!-- index.ejs -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title><%= title %></title>
    </head>
    <body>
        <h1><%= message %></h1>
        <% if (showButton) { %>
            <button onclick="alert('Button Clicked')">Click Me</button>
        <% } %>
    </body>
    </html>
    

    编译和渲染:

    const ejs = require('ejs');
    const fs = require('fs');
    
    // 读取模板文件
    const template = fs.readFileSync('./index.ejs', 'utf8');
    
    // 数据
    const data = {
        title: 'Welcome',
        message: 'Hello, EJS!',
        showButton: true
    };
    
    // 渲染模板
    ejs.render(template, data, (err, html) => {
        if (err) throw err;
        console.log(html);
    });
    
  3. Chrome 插件的 Content Security Policy

    • 这些模板引擎可能会受到 Chrome 插件的 Content Security Policy(CSP)限制。目前我对这方面还不太熟悉,但 Handlebars 和 Eco 网上已有确认没问题的案例,所以我打算进一步研究。

实际操作经验

目前,我查阅了许多资料,但缺乏实际操作经验,也不清楚如何测试这些模板引擎。如果有实际项目经验的同学,能否给我一些建议?

参考资料


用淘宝的juicer

http://juicer.name/docs/docs.html 最近很少碰到 504 的错误啊, 什么情况… 中文介绍蛮好的… http://ued.taobao.com/blog/2012/04/juicer-一个javascript模板引擎的实现和优化/ 不过编辑器命令行版本, 哪儿能看?

编辑器命令行版本是什么意思,我一般直接用的

刚看了下他们主页打不开, Github 倒是无压力: https://github.com/PaulGuo/Juicer … 貌似命令行工具 NPM 找到了, 但是编译没有详细的文档呀 你说的用是在前端没错吧?

是啊,直接在githup上把juicer-min.js弄下来就可以用了,不需要编译啊

不是. 主要是为了榨性能… HTML 模板打算在上浏览器跑之前编译到 JS. 这个没讲

主页可以访问了,也可以直接编译

还是打不开啊… http://juicer.name/

swig咋样? JADE 确实用起来少写很多代码~

.html 后缀, 编辑器支持没问题 语法和文档够清晰 http://paularmstrong.github.io/swig/docs/#tags 性能比 Handlebars 裸跑要好, http://jsperf.com/swig-vs-handbrake 没找到编译的说明, 不能编译估计性能要掉档次 另外 Chrome 插件上的问题… 不了解…

Jade 要是能 Handlebars 这么编译也挺想试试

实际上…这个高性能…能体现处在那里…如果一个页面 dom 也就 100 来个节点…我个人觉得…这性能在搞也差不了那里去… 如果是 1000来个节点倒是可以去考虑性能问题…问题是,一次性渲染 1000来个节点的网页…一般来说很少吧?

想想也有道理. 目前我这边遇到这样的, 某个 View 栏目可能被重复一百条以上 改成非 MVC 的写法, 合并 HTML, 这边的性能问题大概就没有了 可我现在的能力不可能改架构更不可能重写, 于是先注意边角上的性能了 还是觉得你说的有道理…

如果限定于浏览器端,那么性能优先级并不是第一的。与服务器端不同,浏览器端同一时间只需处理单一一个模板,而人类是无法感知50ms级别以下,只要在50ms以内完成一个模板渲染就算达标了,绝大部分的模板实现都能轻松搞定。只要是使用浏览器的是正常人类而不是神马机器爬虫,比50ms更快毫无意义。此时应该优先考虑其他一些因素,例如扩展性、兼容性、学习曲线等等。

另外如果注重用户操作交互性,基于dom的模板要比ejs/handlebars/dot这类基于string替换的模板优胜,毕竟前者只需要替换小量dom树的节点,后者则就算只更新了一个变量,都要重新渲染整个模板。

相关经验不够唉. 从前自己学网页应用, 基本都是 jQuery 风格的 DOM 操作 工作接触到的是 MVC 分离的, 不过交互很多, 部分模块有大量 DOM 操作 我感到手动操作 DOM 有大量的状态需要考虑和维护, 而 MVC 通过刷新减少了状态切换时对多种状态的切换的考虑 我就在想, 为了开发效率能提升能跟上需求, 是不是要尽量避免直接 DOM 操作 现在看这边也是有问题的, 略纠结

针对你的需求,我们可以从几个方面来评估这些模板引擎:易用性、性能、支持和生态。

1. Handlebars

  • 优点
    • logic-less 模板,易于维护。
    • 有大量的社区支持和插件(如 Sublime Text 插件)。
    • 性能较好。
  • 缺点
    • 逻辑需要写在 Helpers 中,如果逻辑复杂可能会显得混乱。

2. EJS

  • 优点
    • 允许直接在模板中写入 JavaScript 逻辑。
    • 有良好的社区支持和文档。
    • 通过暴露 API 可以进行预编译。
  • 缺点
    • 性能可能不如 Handlebars 和 doT。

3. doT

  • 优点
    • 性能最好。
    • 支持预编译。
  • 缺点
    • 文档较少且不完整。
    • 缺乏像 Handlebars 和 EJS 那样的社区支持。

示例代码

使用 Handlebars

// 安装 handlebars
npm install handlebars

// 引入 handlebars
const Handlebars = require('handlebars');

// 定义一个简单的模板
const source = `
  <div class="person">
    {{name}}
    <br>
    {{age}}
  </div>
`;

// 注册 Helper
Handlebars.registerHelper('if_even', function(value, options) {
  if (value % 2 === 0) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
});

// 编译模板
const template = Handlebars.compile(source);

// 渲染数据
const data = { name: 'John Doe', age: 25 };
console.log(template(data));

使用 EJS

// 安装 ejs
npm install ejs

// 引入 ejs
const ejs = require('ejs');

// 定义一个简单的模板
const source = `
  <div class="person">
    <%= name %>
    <br>
    <%= age %>
  </div>
`;

// 渲染数据
const data = { name: 'John Doe', age: 25 };
ejs.render(source, data).then(html => {
  console.log(html);
});

使用 doT

// 安装 dot
npm install doT

// 引入 doT
const doT = require('dot');

// 定义一个简单的模板
const template = doT.template(`
  <div class="person">
    {{= it.name }}
    <br>
    {{= it.age }}
  </div>
`);

// 渲染数据
const data = { name: 'John Doe', age: 25 };
console.log(template(data));

总结

根据你的需求,如果你希望保持逻辑简单并且容易维护,可以选择 Handlebars。如果你更喜欢直接在模板中编写 JavaScript 逻辑,可以使用 EJS。如果你对性能有极高的要求,那么 doT 可能是最好的选择,尽管它可能缺乏一些支持。

回到顶部