Express.js 教程
Express.js 是 Node.js 平台上最流行、最灵活的 Web 应用框架,为构建 Web 应用和 API 提供了强大的功能。它极简、高效,是 Node.js Web 开发的事实标准。
什么是 Express.js?
Express.js 是一个快速、开放、极简的 Node.js Web 应用框架,提供了一系列强大的功能来帮助你创建各种 Web 和移动应用。
- 极简主义:核心功能精简,扩展性强
- 灵活:不强制任何架构模式,自由选择
- 高性能:轻量级设计,性能优异
- 生态丰富:大量中间件和插件可用
- 社区活跃:Stack Overflow 问题最多、GitHub Star 最多的 Node.js 框架
Express 5.x 新时代
2024 年 10 月,Express 5.0.0 正式发布,这是 Express 近十年来最重要的版本更新。Express 5 的设计目标是"稳定且安全",重点在于:
核心改进
-
原生 Promise 支持:路由处理函数和中间件返回的 Promise 如果被拒绝(reject),Express 会自动将错误传递给错误处理中间件。这意味着在 async 函数中,你不再需要手动用 try-catch 包装并调用
next(err),错误会自动被捕获和传递。 -
安全性增强:移除正则表达式路由语法,从根本上防止 ReDoS(正则表达式拒绝服务)攻击;静态文件服务的
dotfiles选项默认值从'ignore'改为更安全的配置,防止意外暴露隐藏文件。 -
API 统一:移除了所有废弃的方法签名。例如
res.json(obj, status)不再支持,必须使用res.status(status).json(obj);res.redirect(url, status)参数顺序改为res.redirect(status, url)。这些改动让 API 更加一致和直观。 -
现代化:要求 Node.js 18 或更高版本,内置 Brotli 压缩支持(如果客户端支持),使用更新的依赖库。
路径匹配语法变化
Express 5 升级了底层 path-to-regexp 库,路径匹配语法有重要变化:
- 通配符
*必须有名称:使用/*splat或/{*splat}替代/* - 可选参数使用新语法:使用
/:file{.:ext}替代/:file.:ext? - 不再支持正则表达式语法
迁移工具
Express 官方提供了代码迁移工具(codemod),可以自动修复大部分废弃的 API 调用:
# 运行所有可用的 codemods
npx codemod@latest @expressjs/v5-migration-recipe
本教程基于 Express 5.x 编写,同时会说明与 Express 4.x 的差异。详细的迁移指南请参阅 Express 5.x 新特性与迁移 章节。
核心特性
路由系统
Express 提供了强大的路由功能,支持 RESTful 风格的 API 设计:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/users/:id', (req, res) => {
res.json({ userId: req.params.id });
});
app.post('/users', (req, res) => {
res.status(201).json({ message: 'User created' });
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
中间件机制
Express 的核心是中间件机制,请求响应流程由一系列中间件函数处理:
const express = require('express');
const app = express();
app.use(express.json());
app.use(express.static('public'));
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next();
});
app.get('/', (req, res) => {
res.send('Hello Express!');
});
模板引擎支持
Express 支持多种模板引擎,如 Pug、EJS、Handlebars 等:
app.set('view engine', 'pug');
app.set('views', './views');
app.get('/profile', (req, res) => {
res.render('profile', { name: 'Express', version: '4.x' });
});
与其他框架对比
| 特性 | Express.js | Koa | Fastify | NestJS |
|---|---|---|---|---|
| 性能 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 学习曲线 | 低 | 低 | 低 | 中 |
| 中间件生态 | 丰富 | 较少 | 较少 | 丰富 |
| TypeScript | 可选 | 可选 | 可选 | 原生 |
| 企业级支持 | 社区 | 社区 | 社区 | 企业 |
| 灵活性 | 极高 | 高 | 高 | 中 |
Express.js 技术栈
适用场景
适合使用 Express.js 的场景
- RESTful API 开发:构建后端 API 服务
- 单页应用后端:Vue/React/Angular 的服务端
- 微服务架构:轻量级服务组件
- 实时应用:配合 Socket.io 使用
- 服务端渲染:SSR 应用
- 中间层/BFF:Backend For Frontend
可能不太适合的场景
- 大型企业应用:考虑 NestJS
- 需要严格规范:考虑 NestJS 或 AdonisJS
- 极致性能需求:考虑 Fastify
教程目录
入门基础
核心功能
进阶特性
- 文件上传 - Multer 文件处理、图片压缩、云存储
- WebSocket 实时通信 - Socket.IO、ws 库、实时应用开发
- 错误处理 - 错误中间件、全局错误处理、自定义错误
- 安全认证 - Helmet 安全、CORS、认证授权
数据库集成
- 数据库集成 - MongoDB、MySQL、ORM 使用
测试与部署
版本迁移
- Express 5.x 新特性与迁移 - 新特性详解、破坏性变化、迁移指南
参考资料
- 速查表 - Express.js 常用语法速查
快速开始
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'Hello Express!' });
});
app.get('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ userId: id, name: 'User' + id });
});
app.post('/users', (req, res) => {
const { name, email } = req.body;
res.status(201).json({
message: 'User created',
user: { name, email }
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
运行:
npm init -y
npm install express
node app.js
学习建议
- 先掌握 Node.js 基础:理解模块系统、事件循环
- 理解中间件模式:Express 的核心概念
- 从简单 API 开始:先构建基本的 CRUD 接口
- 学习 RESTful 设计:API 设计最佳实践
- 关注安全性:学习常见 Web 安全问题及防护