首页
/ freeCodeCamp Advanced Node and Express:Express 应用中配置 Pug 模板引擎的完整实战

freeCodeCamp Advanced Node and Express:Express 应用中配置 Pug 模板引擎的完整实战

2026-09-05 23:51:03作者:虞亚竹Luna

本篇技术指南基于 freeCodeCamp 课程仓库中 Advanced Node and Express 认证的首个实战挑战 “Set up a Template Engine”,系统讲解如何在 Express 应用中接入 Pug 模板引擎:包括依赖确认、view engineviews 两项关键配置的设定、res.render() 的调用方式,以及课程测试系统对每一步的自动化验证逻辑。读完本文,你将能够独立在一个 Express 应用中完成服务端模板渲染的搭建,并清楚理解每项配置在运行时的实际作用与验收标准。

挑战背景:两种可用的开发方式

该挑战属于 freeCodeCamp Advanced Node and Express 认证(见 区块结构文件),是认证学习路径中的第一个任务。根据 挑战文档 的说明,完成本项目有两种方式:

  • 本地开发:克隆课程配套的 boilerplate-advancednode 脚手架仓库,在本地环境中完成挑战;
  • 在线站点构建器:使用任一站点构建平台完成项目,但必须将脚手架仓库中的全部文件纳入项目。

无论选择哪种方式,脚手架已经为你预装了一个关键依赖:

  • pug@~3.0.0 已安装完成,并作为依赖项列在 package.json 中。

这一点很重要:课程后续的自动化测试会直接检查 package.jsondependencies 字段,若你从零搭建项目,务必确保 pug 以近似版本(~3.0.0)锁定并列入依赖。

模板引擎解决了什么问题

文档对模板引擎的定义非常精炼,值得完整理解:

模板引擎让你在应用中可以使用静态模板文件(例如以 Pug 编写的文件)。运行时,模板引擎会把模板文件中的变量替换为服务端提供的实际值,然后把模板转换成一份静态 HTML 文件发送给客户端。这种方式让 HTML 页面的设计更容易,并且无需客户端发起 API 调用就能在页面上展示变量。

从这段话可以拆解出三个技术要点:

  1. 静态模板 + 运行时渲染:模板文件(如 .pug)本身不是最终产物,服务端在请求到来时执行渲染,输出的才是浏览器收到的静态 HTML。
  2. 变量由服务端注入:页面上展示的数据直接来自服务器内存或数据库,渲染完成后以 HTML 形式下发。
  3. 省去一次客户端 API 往返:与纯前端方案相比,初始页面数据不需要等 HTML 加载完后再由 JS 发起 API 请求拉取,首屏呈现更直接。

Pug 本身是一种高度依赖空白与缩进来表示嵌套、语法极简的模板语言。课程下一个挑战 Use a Template Engine's Powers 中给出的示例可以直观感受其风格:

head
  script(type='text/javascript').
    if (foo) bar(1 + 5);
body
  if youAreUsingPug
      p You are amazing
    else
      p Get on it!

上述 Pug 代码渲染后产出对应的 <head>/<body> 标准 HTML 结构。掌握这一点对理解本挑战“页面由空白变为渲染成功”的验收标准很有帮助。

第一步:用 set 方法指定 view engine

Express 默认并不知道你要用哪一种模板引擎,因此必须显式告知它。使用 Express 应用实例的 set 方法,将 view engine 属性赋值为 pug

app.set('view engine', 'pug');

这行配置会写入 Express 内部的 app.settings 对象。课程测试正是利用这一点来验证的(详见下文“验收标准”一节):测试会读取应用设置并断言 settings['view engine'] 严格等于字符串 "pug"。注意这里是精确匹配,写成 "Pug" 或其他变体都会失败。

第二步:把 views 指向 ./views/pug 目录

指定引擎之后,还要告诉 Express 去哪里找模板文件。再加一个 set 调用,把 views 属性指向 ./views/pug 目录:

app.set('views', './views/pug');

该配置的含义是:Express 渲染所有视图时都以此为基准目录。也就是说,之后凡是 res.render('index'),Express 实际查找的就是 ./views/pug/index.pug。脚手架的 index.pug 模板就放在该目录下,保持相对路径 ./views/pug 原样(含 ./ 前缀)是关键——课程的自动化测试对此做的是字符串精确比对,而不是路径解析后的等价性判断。

第三步:在首页路由中调用 res.render('index')

配置完成后,在首页路由(/)的处理器中调用 res.render(),并将 index 作为第一个参数传入:

app.get('/', function (req, res) {
  res.render('index');
});

res.render('index') 会触发对 ./views/pug/index.pug 的渲染流程:Pug 编译模板 → 生成静态 HTML → 作为响应体发送。如果一切按计划执行,应用首页将不再是空白页,而是显示一条渲染成功的提示信息(该页面 HTML 中包含 “FCC Advanced Node and Express” 字样与 pug-success-message 标识,二者都是课程测试的断言锚点,见下文)。

验收标准:课程测试如何逐步验证你的实现

本挑战的 # --hints-- 部分定义了 5 组自动化断言,它们以 HTTP 请求的形式作用于你部署/运行中的应用(相关测试端点如 /_api/package.json/_api/app 是课程测试平台暴露的自省接口)。这些断言也构成了本任务事实上的“验收清单”:

  1. Pug 必须是依赖项
const url = new URL("/_api/package.json", code);
const res = await fetch(url);
const packJson = await res.json();
assert.property(
  packJson.dependencies,
  'pug',
  'Your project should list "pug" as a dependency'
);

检查 package.jsondependencies 中是否存在 pug 键。

  1. View engine 必须为 Pug
const url = new URL("/_api/app", code);
const res = await fetch(url);
const app = await res.json();
assert.equal(app?.settings?.['view engine'], "pug");

通过 /_api/app 端点读取应用设置,断言 view engine 精确等于 "pug"

  1. views 属性必须为 ./views/pug
assert.equal(app?.settings?.views, "./views/pug");

注意这里比对的是字面字符串 "./views/pug",因此路径写法必须与课程要求完全一致。

  1. 首页必须渲染出成功提示
const url = new URL("/", code);
const res = await fetch(url);
const data = await res.text();
assert.match(
  data,
  /FCC Advanced Node and Express/gi,
  'You successfully rendered the Pug template!'
);

请求根路径 /,断言返回的 HTML 文本匹配 FCC Advanced Node and Express(忽略大小写)。

  1. Pug 必须真正在工作
assert.match(
  data,
  /pug-success-message/gi,
  'Your projects home page should now be rendered by pug with the projects .pug file unaltered'
);

断言页面包含 pug-success-message 标识,且错误提示明确要求 .pug 文件未被修改——即你不能通过改写模板文件来“绕过”渲染,必须让 Express 真正走 Pug 渲染管线产出页面。

在认证体系中的位置与后续路线

区块结构文件 定义的 challengeOrder 可以看出,本挑战是整个 Advanced Node and Express 认证的起点,模板引擎的设置是后续所有功能的地基:

  • 紧接其后的 Use a Template Engine's Powers 会教你在 res.render 中传入第二个参数(变量对象),把服务端变量注入模板,例如 res.render('index', { title: 'Hello', message: 'Please log in' }),模板内可用 #{variable}p=variable 语法消费;
  • 再往后是 Set up Passport,引入 express-session 与 Passport 完成会话与认证体系;
  • 认证后段还包括 Socket.IO 实时通信等一系列挑战。

模板渲染之所以被安排在最前面,正是因为 Passport 登录状态展示、用户信息等后续功能都需要把服务端数据渲染进 HTML 页面——view engineviews 两项配置正是这一切渲染能力的前提。

小结

本挑战的核心操作只有三步,却覆盖了 Express 模板渲染的全部关键链路:

步骤 配置/代码 运行时作用
1 app.set('view engine', 'pug') 告知 Express 使用 Pug 渲染引擎
2 app.set('views', './views/pug') 指定模板基准目录
3 res.render('index')(首页路由) 渲染 ./views/pug/index.pug 并下发 HTML

配合 package.json 中已就绪的 pug@~3.0.0 依赖,即可让 Express 应用具备“服务端渲染 + 静态 HTML 下发”的完整能力。实现时请保持 .pug 模板文件原样不动,并以页面成功渲染出包含 “FCC Advanced Node and Express” 与 pug-success-message 标识的 HTML 作为自检标准——这也正是课程自动化测试的五项断言所验证的内容。

登录后查看全文
热门项目推荐
相关项目推荐