一、模板引擎的前世今生
在Web开发的世界里,模板引擎就像是建筑工地的脚手架,它帮我们把数据和界面优雅地结合在一起。想象一下,如果没有模板引擎,我们可能需要手动拼接一大堆字符串,那场景简直就像用螺丝刀盖摩天大楼。
Node.js生态中有三大主流模板引擎:EJS、Pug和Handlebars。它们各有特色,就像不同风格的厨师——有的喜欢原汁原味(EJS),有的追求极简主义(Pug),还有的坚持结构化(Handlebars)。
让我们先看个简单的例子感受下它们的区别。假设我们要显示一个用户列表:
// EJS示例 (Node.js技术栈)
<% users.forEach(user => { %>
<div class="user-card">
<h2><%= user.name %></h2>
<p>注册于: <%= user.registerDate.toLocaleDateString() %></p>
</div>
<% }) %>
// Pug示例 (Node.js技术栈)
each user in users
.user-card
h2= user.name
p 注册于: #{user.registerDate.toLocaleDateString()}
// Handlebars示例 (Node.js技术栈)
{{#each users}}
<div class="user-card">
<h2>{{name}}</h2>
<p>注册于: {{formatDate registerDate}}</p>
</div>
{{/each}}
看到区别了吗?EJS保留了HTML的原始味道,Pug像写诗一样简洁,而Handlebars则强调逻辑与模板的分离。
二、EJS:简单直白的实力派
EJS(Embedded JavaScript)最大的特点就是"所见即所得"。它的语法几乎就是JavaScript穿上HTML的马甲,学习成本低到尘埃里。
2.1 基础用法
// 服务端设置 (Node.js技术栈)
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
// 渲染示例
app.get('/', (req, res) => {
res.render('index', {
title: '我的小店',
products: [
{ name: '有机苹果', price: 12.5 },
{ name: '新鲜橙子', price: 8.8 }
]
});
});
<!-- 对应EJS模板 -->
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1>今日特价商品</h1>
<ul>
<% products.forEach(product => { %>
<li>
<%= product.name %> -
<span class="price"><%= product.price.toFixed(2) %>元</span>
</li>
<% }) %>
</ul>
</body>
</html>
2.2 进阶特性
EJS支持模板继承,这让我们可以创建基础布局:
<!-- layout.ejs -->
<html>
<head>
<title><%- title %></title>
<%- include('partials/head') %>
</head>
<body>
<%- include('partials/header') %>
<%- body %>
<%- include('partials/footer') %>
</body>
</html>
<!-- home.ejs -->
<% layout('layout', {title: '首页'}) %>
<section>
<h1>欢迎光临</h1>
<p>这里是内容区域...</p>
</section>
2.3 适用场景
EJS特别适合:
- 从传统后端(如PHP)转Node.js的开发者
- 需要快速上手的项目
- 团队中有前端新手的情况
- 需要直接编辑HTML的场景
三、Pug:极简主义的艺术
Pug(原名Jade)就像模板引擎界的Python,用缩进来代替标签,写起来行云流水。不过这种风格也容易引发"空格还是Tab"的圣战。
3.1 基础语法
// 服务端设置 (Node.js技术栈)
app.set('view engine', 'pug');
app.set('views', './views');
//- 模板示例
doctype html
html(lang="zh-CN")
head
title= title
link(rel="stylesheet", href="/styles.css")
body
header
h1 商品列表
main
each product in products
article.product
h2= product.name
p.price ¥#{product.price}
if product.stock < 10
p.low-stock 库存紧张!
3.2 混合代码
Pug支持内联JavaScript:
- const getDiscount = (price) => price * 0.9
each product in products
.product
h2= product.name
p 原价: ¥#{product.price}
p 会员价: ¥#{getDiscount(product.price)}
3.3 适用场景
Pug是以下情况的最佳选择:
- 追求开发效率的项目
- 需要精简代码量的场景
- 团队统一使用缩进风格的环境
- 需要快速原型设计的场合
四、Handlebars:逻辑与表现的完美分离
Handlebars奉行"模板应该尽可能简单"的哲学,把复杂逻辑都赶到了helper里。它就像是模板引擎界的瑞士军刀——结构清晰,扩展性强。
4.1 基础示例
// 注册helper (Node.js技术栈)
const handlebars = require('express-handlebars');
app.engine('hbs', handlebars({
helpers: {
formatCurrency: (value) => '¥' + value.toFixed(2),
isLowStock: (stock) => stock < 5
}
}));
app.set('view engine', 'hbs');
{{! 模板文件 }}
<div class="products">
{{#each products}}
<div class="product {{#if (isLowStock stock)}}low-stock{{/if}}">
<h3>{{name}}</h3>
<p class="price">{{formatCurrency price}}</p>
{{#if description}}
<p>{{description}}</p>
{{else}}
<p>暂无描述</p>
{{/if}}
</div>
{{/each}}
</div>
4.2 高级用法
Handlebars支持模板继承:
{{! layout.hbs }}
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
{{{block "styles"}}}
</head>
<body>
{{{body}}}
{{{block "scripts"}}}
</body>
</html>
{{! page.hbs }}
{{#extend "layout"}}
{{#content "styles"}}
<link rel="stylesheet" href="/custom.css">
{{/content}}
{{#content "body"}}
<main>这里是内容区域</main>
{{/content}}
{{/extend}}
4.3 适用场景
Handlebars特别适合:
- 大型长期维护的项目
- 需要严格分离逻辑和表现层的场景
- 需要服务端和客户端共享模板的情况
- 团队中有前端架构师的项目
五、技术选型的终极对决
5.1 性能对比
在实际项目中,三者的渲染速度差异其实不大(都在毫秒级),但我们可以看个简单对比:
| 引擎 | 简单模板(ms) | 复杂模板(ms) | 内存占用 |
|---|---|---|---|
| EJS | 1.2 | 4.5 | 中等 |
| Pug | 1.5 | 5.2 | 较高 |
| Handlebars | 1.8 | 6.0 | 较低 |
5.2 学习曲线
- EJS:★☆☆☆☆ (会JS就会EJS)
- Pug:★★★☆☆ (要适应缩进语法)
- Handlebars:★★☆☆☆ (需要理解helper概念)
5.3 团队协作
- EJS:适合混合技能团队
- Pug:适合风格统一的团队
- Handlebars:适合前后端分离的团队
六、决策指南:如何选择
最后送上一个简单的决策树:
- 需要快速上手? → 选EJS
- 追求极致简洁? → 选Pug
- 项目长期复杂? → 选Handlebars
- 需要同构渲染? → 选Handlebars
- 团队有历史包袱? → 看现有技术栈
记住,没有最好的模板引擎,只有最适合的。就像选咖啡一样,有人喜欢黑咖啡的纯粹(EJS),有人中意拿铁的平衡(Handlebars),还有人钟情浓缩的高效(Pug)。
评论