一、HTML模板引擎的前世今生
说起模板引擎,就像装修房子时用的设计图纸。早些年我们做网站开发,都是把HTML代码和业务逻辑混在一起写的,就像把水电管道直接暴露在客厅墙面上一样难看。后来大家发现这样不行,就发明了模板引擎这个好东西。
最早的PHP本身就是个模板引擎,后来出现了Smarty这样的专门工具。现在前端领域常见的模板引擎有EJS、Handlebars、Pug(Jade)等等。它们就像不同风格的设计师,有的喜欢简约,有的偏爱复杂。
举个例子,我们用EJS写个简单的用户列表(技术栈:Node.js + Express + EJS):
<!-- 用户列表模板 userList.ejs -->
<!DOCTYPE html>
<html>
<head>
<title>用户列表</title>
</head>
<body>
<h1>系统用户</h1>
<ul>
<% users.forEach(function(user){ %>
<li>
<%= user.name %> - <%= user.email %>
<% if(user.isAdmin){ %>
<span>(管理员)</span>
<% } %>
</li>
<% }); %>
</ul>
</body>
</html>
// 后端路由处理
app.get('/users', (req, res) => {
const users = [
{name: '张三', email: 'zhang@example.com', isAdmin: true},
{name: '李四', email: 'li@example.com', isAdmin: false}
];
res.render('userList', {users: users});
});
这个例子展示了EJS的几个特点:
<% %>里面可以写JavaScript代码<%= %>用来输出变量值- 模板逻辑和后端数据完全分离
二、前后端分离的必然趋势
随着Web应用越来越复杂,传统的模板引擎开始显得力不从心。这就好比小饭馆可以一个厨师搞定所有,但大酒店必须前厅后厨明确分工。
前后端分离架构就像把餐厅分成厨房和用餐区,中间通过API传菜。前端专注展示和交互,后端专注数据处理。这种架构下,模板引擎的角色也发生了变化。
以Vue.js为例(技术栈:Vue + Node.js):
// 前端Vue组件 UserList.vue
<template>
<div>
<h1>系统用户</h1>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }} - {{ user.email }}
<span v-if="user.isAdmin">(管理员)</span>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
users: []
}
},
created() {
// 通过API获取数据
fetch('/api/users')
.then(res => res.json())
.then(data => this.users = data);
}
}
</script>
// 后端API接口
app.get('/api/users', (req, res) => {
const users = [
{id: 1, name: '张三', email: 'zhang@example.com', isAdmin: true},
{id: 2, name: '李四', email: 'li@example.com', isAdmin: false}
];
res.json(users);
});
这种模式下:
- 前端完全独立,可以使用任何框架
- 后端只提供数据接口,不关心展示逻辑
- 前后端可以并行开发
三、现代开发中的模板引擎选择
现在虽然前后端分离是主流,但模板引擎仍然有其用武之地。比如需要SEO的页面、简单的后台系统、电子邮件模板等。
让我们比较几个流行的选择:
- EJS:语法简单,类似原始HTML
<!-- 条件判断示例 -->
<% if (user) { %>
<h2>欢迎, <%= user.name %></h2>
<% } else { %>
<h2>请登录</h2>
<% } %>
- Pug(Jade):简洁的缩进语法
// 同样的条件判断
if user
h2 欢迎, #{user.name}
else
h2 请登录
- Handlebars:逻辑与模板严格分离
{{#if user}}
<h2>欢迎, {{user.name}}</h2>
{{else}}
<h2>请登录</h2>
{{/if}}
选择建议:
- 需要快速开发:EJS
- 追求简洁:Pug
- 需要严格分离:Handlebars
- 前后端分离项目:直接使用Vue/React模板
四、实战中的架构设计与注意事项
在实际项目中,我们常常需要混合使用多种技术。比如一个电商网站:
- 商品详情页:用SSR(服务端渲染)保证SEO
- 用户中心:用前后端分离实现丰富交互
- 后台管理:直接用模板引擎快速开发
这里给出一个混合架构示例(技术栈:Express + EJS + Vue):
// 服务端入口 app.js
const express = require('express');
const app = express();
// 静态文件和Vue应用
app.use(express.static('public'));
// 传统模板引擎路由
app.set('view engine', 'ejs');
app.get('/product/:id', (req, res) => {
// 从数据库获取商品数据
const product = getProductFromDB(req.params.id);
res.render('productDetail', {product});
});
// API路由
app.get('/api/cart', (req, res) => {
// 获取购物车数据
res.json(getCartData());
});
// Vue应用入口
app.get('/user/*', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'user', 'index.html'));
});
注意事项:
- 性能:模板引擎渲染会消耗服务器资源,高并发时要考虑缓存
- 安全:警惕XSS攻击,特别是使用
<%=时要转义输出 - 开发体验:前后端分离项目要解决跨域问题
- SEO:重要页面考虑预渲染或SSR
五、总结与未来展望
模板引擎就像工具箱里的锤子,前后端分离架构好比电动工具。没有绝对的好坏,关键看用在什么地方。
对于内容型网站,传统的模板引擎仍然简单高效;对于Web应用,前后端分离带来更好的开发体验和性能。未来,随着Edge Computing和Serverless的发展,我们可能会看到更多混合渲染的方案。
无论技术如何变化,核心原则不变:关注用户体验、保证代码质量、选择适合团队的技术栈。就像好厨师不会纠结用中式菜刀还是西式厨刀,重要的是做出美味佳肴。
评论