如果说 Node.js 是 JavaScript 服务端的"开国元勋",那么 Express 就是 Node.js Web 框架的"开山鼻祖"。虽然后来者众多,但 Express 依然是 Node.js 开发者的首选。
Express 是什么?#
Express 是 Node.js 生态最经典的 Web 框架,2009 年由 TJ Holowaychuk 创建。它的核心特点是:简洁、灵活、极简主义。
类比理解#
| 对比项 | Express | NestJS |
|---|---|---|
| 风格 | 极简主义 | 企业级 |
| 约束 | 几乎没有 | 约定优先 |
| 学习曲线 | 平缓 | 较陡 |
| 灵活性 | 极高 | 中等 |
| 就像 | 乐高自由拼搭 | 乐高官方套装 |
Express 给你最大的自由—— 你可以按自己的方式组织代码。
核心特性#
1. 简洁的 API:五分钟入门#
Express 的 API 极其简洁:
const express = require('express');
const app = express();
const port = 3000;
// 路由
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/api/users', (req, res) => {
res.json([
{ id: 1, name: '张三' },
{ id: 2, name: '李四' }
]);
});
// 启动服务器
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});2. 路由系统:清晰明了#
Express 的路由非常直观:
// 基本路由
app.get('/users', (req, res) => {
res.send('获取用户列表');
});
app.post('/users', (req, res) => {
res.send('创建用户');
});
app.put('/users/:id', (req, res) => {
res.send(`更新用户 ${req.params.id}`);
});
app.delete('/users/:id', (req, res) => {
res.send(`删除用户 ${req.params.id}`);
});
// 路由参数
app.get('/users/:id/posts/:postId', (req, res) => {
res.json({
userId: req.params.id,
postId: req.params.postId
});
});
// 查询参数
app.get('/search', (req, res) => {
res.json(req.query); // ?q=keyword&page=1
});3. 中间件:Express 的灵魂#
中间件是 Express 的核心概念—— 它是一个函数,可以访问请求和响应对象。
// 中间件函数
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // 调用下一个中间件
};
// 应用级中间件
app.use(logger);
// 路由级中间件
const auth = (req, res, next) => {
if (req.headers.authorization) {
next();
} else {
res.status(401).send('未授权');
}
};
app.get('/protected', auth, (req, res) => {
res.send('受保护的路由');
});常用中间件:
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const bodyParser = require('body-parser');
app.use(cors()); // 跨域资源共享
app.use(helmet()); // 安全头
app.use(morgan('dev')); // 日志
app.use(bodyParser.json()); // 解析 JSON
app.use(bodyParser.urlencoded({ extended: true })); // 解析表单
4. 请求对象:获取客户端数据#
app.get('/demo', (req, res) => {
// 路由参数:/demo/123
console.log(req.params.id);
// 查询参数:/demo?id=123
console.log(req.query.id);
// 请求头
console.log(req.headers.authorization);
// 请求体(需要 body-parser)
console.log(req.body.name);
// Cookie
console.log(req.cookies.token);
});5. 响应对象:返回数据#
app.get('/responses', (req, res) => {
// 发送字符串
res.send('Hello');
// 发送 JSON
res.json({ message: 'Hello' });
// 发送文件
res.download('/path/to/file');
// 重定向
res.redirect('/other-page');
// 设置状态码
res.status(201).json({ created: true });
});6. 错误处理#
// 同步错误处理
app.get('/error', (req, res) => {
throw new Error('出错了!');
});
// 异步错误处理
app.get('/async-error', async (req, res, next) => {
try {
const data = await fetchData();
res.json(data);
} catch (error) {
next(error); // 传递给错误处理中间件
}
});
// 错误处理中间件(必须放在最后)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: '服务器错误' });
});7. Router:模块化路由#
// users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('用户列表');
});
router.get('/:id', (req, res) => {
res.send(`用户 ${req.params.id}`);
});
module.exports = router;
// app.js
const usersRouter = require('./users');
app.use('/users', usersRouter);为什么 Express 如此流行?#
1. 简单灵活#
Express 的设计理念是"最小化":
- 核心非常小
- 功能通过中间件扩展
- 不强制任何代码结构
2. 生态成熟#
Express 拥有最成熟的 Node.js 生态:
- 中间件丰富
- 文档完善
- 社区庞大
- 教程众多
3. 几乎所有 Node.js 框架的底层#
很多框架都是基于 Express 构建:
- NestJS(可使用 Express 适配器)
- Next.js(早期版本)
- Feathers
- Sails.js
4. 适合快速开发#
对于小型项目和原型,Express 是最佳选择:
- 上手快
- 代码量少
- 灵活度高
适用场景#
| 场景 | 适合程度 | 说明 |
|---|---|---|
| 小型 Web 应用 | ⭐⭐⭐⭐⭐ | 简单灵活 |
| REST API | ⭐⭐⭐⭐⭐ | 快速开发 |
| 原型开发 | ⭐⭐⭐⭐⭐ | 快速迭代 |
| 微服务 | ⭐⭐⭐⭐ | 轻量快速 |
| 中大型应用 | ⭐⭐⭐ | 需要良好的代码组织 |
| 企业级应用 | ⭐⭐ | 推荐用 NestJS |
Express 与原生 Node.js 对比#
// 原生 Node.js
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/users' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify([{ id: 1 }]));
}
});
server.listen(3000);
// Express
const express = require('express');
const app = express();
app.get('/users', (req, res) => {
res.json([{ id: 1 }]);
});
app.listen(3000);Express 大大简化了 Node.js 的 HTTP 处理。
学习路线建议#
入门阶段(1 周)#
- 掌握 Node.js 基础
- 理解 Express 基本用法
- 学会路由和中间件
- 掌握请求和响应对象
进阶阶段(1-2 周)#
- 深入理解中间件原理
- 掌握错误处理
- 学会使用 Router 模块化
- 掌握模板引擎(可选)
高级阶段(持续学习)#
- 性能优化
- 安全最佳实践
- 与数据库集成
- 了解 Express 原理
常用中间件#
| 中间件 | 用途 |
|---|---|
| cors | 跨域支持 |
| helmet | 安全头 |
| morgan | 日志 |
| body-parser | 请求体解析 |
| cookie-parser | Cookie 解析 |
| express-session | 会话 |
| multer | 文件上传 |
| compression | 压缩 |
与其他 Node.js 框架对比#
| 特性 | Express | Koa | Fastify | NestJS |
|---|---|---|---|---|
| 简洁度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| 性能 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 异步支持 | 回调 | async/await | async/await | async/await |
| 中间件 | 传统 | 洋葱模型 | 插件 | 守卫/拦截器 |
| 学习曲线 | 平缓 | 平缓 | 平缓 | 较陡 |
简单来说:
- Express:经典稳定,生态成熟
- Koa:更现代,洋葱模型
- Fastify:性能最高
- NestJS:企业级架构
总结#
Express 是 Node.js 生态的"常青树":
- 简洁 API—— 五分钟入门
- 中间件系统—— 灵活扩展
- 路由清晰—— 易于理解
- 生态成熟—— 资料丰富
- 高度灵活—— 按需定制
虽然"新框架"层出不穷,但 Express 依然是 Node.js 开发的基石。学会 Express,你就能轻松过渡到其他框架。
下期预告:后端框架聊完了,接下来我们进入移动端领域。Flutter 是 Google 打造的跨平台 UI 框架,以其高性能渲染和"一次编写,到处运行"著称。下一篇文章我们来详细介绍这个"UI 框架的新物种"。
