FORMA

EJS

EJS(Embedded JavaScript templates)在 HTML 中嵌入 JavaScript,常用于 Express 服务端渲染(SSR)。

一、EJS 基础概念

  • 什么是 EJS:Embedded JavaScript templates,是一款简单高效的嵌入式 JavaScript 模板引擎。
  • 核心定位:允许在 HTML 中嵌入 JavaScript 代码,实现动态内容生成和复用。
  • 主要优势:语法简单、可内嵌 JavaScript、与 Express 无缝集成。
  • 模板文件后缀.ejs

二、安装与基础使用

1. 安装

bash
npm install ejs

也可同时安装 Express(如需配合使用):

bash
npm install express ejs

2. 核心 API

方法说明
ejs.compile(str, options)编译模板字符串为可复用的渲染函数
ejs.render(str, data, options)渲染模板字符串,直接输出 HTML
ejs.renderFile(filename, data, options, callback)读取并渲染模板文件
javascript
const ejs = require("ejs");

// 方式一:compile(适合多次使用同一模板)
const template = ejs.compile("<h1><%= name %></h1>");
const html = template({ name: "张三" });

// 方式二:render(一次性渲染)
const html2 = ejs.render("<h1><%= name %></h1>", { name: "李四" });

// 方式三:renderFile(从文件读取)
ejs.renderFile("./views/index.ejs", { title: "首页" }, (err, html) => {
  if (err) throw err;
  console.log(html);
});

三、核心标签语法

EJS 使用特殊的标签在 HTML 中嵌入 JavaScript 代码。

标签说明示例
<%= ... %>输出标签:输出变量值,自动 HTML 转义(防止 XSS)<h1><%= title %></h1>
<%- ... %>原始输出标签:输出未经转义的原始 HTML(慎用,需确保内容安全)<div><%- article.content %></div>
<% ... %>脚本标签:执行 JavaScript 逻辑(条件、循环等),不输出内容<% if (user) { %><% } %>
<%# ... %>注释标签:添加注释,不会出现在最终输出中<%# 这是注释 %>
<%_ ... _%>空白修剪标签:自动去除标签前后的空白字符<%_ for (...) { _%>
<%% %%>原始标签:输出 <%%> 字符本身,避免被解析<p>使用<%%= variable %%>输出</p>

四、条件渲染

js
<% if (isLoggedIn) { %>
  <p>欢迎回来,<%= user.name %>!</p>
<% } else { %>
  <p>请先登录。</p>
<% } %>

五、循环

js
<ul>
  <% products.forEach(product => { %>
    <li><%= product.name %> - ¥<%= product.price %></li>
  <% }) %>
</ul>

六、Include 机制(模块化)

<%- include('partial') %> 用于在模板中引入其他模板文件,实现代码复用。

  • 基础用法
    js
    <%- include('header') %>
    <main>页面内容</main>
    <%- include('footer') %>
    
  • 传递参数给被包含的模板
    js
    <%- include('user/profile', { user: currentUser }) %>
    
  • 文件夹结构示例
    text
    views/
    ├── index.ejs          # 主模板
    └── partials/
        ├── header.ejs     # 导航栏
        └── footer.ejs     # 页脚
    

七、Layout / 模板继承

EJS 原生不支持完整的模板继承(如 Jinja2 的 extendsblock),需要通过以下方式实现:

  1. 使用 Include 组织 Layout(最常用):
    js
    <!-- layout.ejs -->
    <!DOCTYPE html>
    <html>
    <head><title><%= title %></title></head>
    <body>
      <%- include('header') %>
      <%- body %>
      <%- include('footer') %>
    </body>
    </html>
    
  2. 使用 express-ejs-layouts 中间件
    bash
    npm install express-ejs-layouts
    
    javascript
    const expressLayouts = require("express-ejs-layouts");
    app.use(expressLayouts); // 默认使用 views/layout.ejs
    
  3. 手动传递 Layout 数据:通过局部变量或第三方库(如 ejs-locals)组织布局块。

八、与 Express 集成

javascript
const express = require("express");
const app = express();

// 1. 设置模板引擎为 ejs
app.set("view engine", "ejs");
// 2. 设置模板文件存放目录(默认可不写)
app.set("views", path.join(__dirname, "views"));

// 3. 在路由中使用 res.render() 渲染
app.get("/", (req, res) => {
  res.render("index", {
    title: "首页",
    user: { name: "张三", isAdmin: true },
  });
});

九、常用配置选项

通过 options 参数配置 EJS 行为:

选项类型说明
cacheBoolean是否缓存编译后的函数
filenameString必须cachetrue 时指定,用于 Include 与缓存
rootString/ArrayInclude 文件的根路径
viewsArray解析相对路径 Include 时使用的路径列表
compileDebugBooleanfalse 时不编译调试信息(提升性能)
clientBooleantrue 时返回可在浏览器端独立运行的编译函数
debugBoolean输出生成的函数体
strictBoolean生成的渲染函数以严格模式运行
escapeFunction自定义 HTML 转义函数
asyncBoolean启用异步渲染
delimiter / openDelimiter / closeDelimiterString自定义标签定界符

十、缓存机制

EJS 内置基础缓存(ejs.cache),用于存储编译后的模板函数。搭配 LRU 缓存可有效控制内存上限,避免缓存无限膨胀。

  • 清除缓存
    javascript
    ejs.clearCache();
    
  • 使用 LRU 缓存
    javascript
    const ejs = require("ejs");
    const LRU = require("lru-cache");
    ejs.cache = new LRU(100); // 最多缓存 100 个模板
    

十一、调试与常见问题

  • 开启调试模式
    javascript
    ejs.render(str, { debug: true });
    
  • 变量未渲染:检查是否误将输出内容放在 <% ... %> 而非 <%= ... %> 中。
  • Include 路径错误:确保 include 路径相对于主模板,或通过 options.views / options.root 指定绝对路径。
  • 安全性注意事项:不要直接渲染用户提交的模板,也不要将 req.query 当成数据渲染,否则可能引发 XSS 或远程代码执行漏洞。

十二、EJS 适用场景

  • 需要在服务端生成带动态内容的 HTML(利于 SEO)
  • 快速原型开发,希望用最简单的方式实现模板化展示
  • 与 Express 配合,实现传统的“后端 MVC”模式

补充说明:需要完整 extends / block 继承时,可考虑 PugNunjucks

参考文献

以下链接在编写时均可正常访问:

资料说明
EJS 文档官方
express-ejs-layoutsLayout 中间件
Express 模板引擎集成方式