定位
Express 5 在 2026 年终于正式发布(5.3.0)。核心改动只有一条值得记:async 处理函数里的异常会被自动捕获,不用再手写 try/catch 或包装函数。
这是十五年历史里最实际的改进。
安装
npm init -y
npm install express
1. TypeScript 项目还需要
npm install -D @types/express
最小示例
const express = require('express')
const app = express()
app.use(express.json())
app.get('/', (req, res) => {
res.send('Hello')
})
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id })
})
// Express 5:async 报错自动进入错误中间件
app.post('/users', async (req, res) => {
const user = await createUser(req.body) // 抛错会被自动捕获
res.status(201).json(user)
})
// 错误处理中间件(四个参数,顺序不能变)
app.use((err, req, res, next) => {
console.error(err)
res.status(500).json({ error: err.message })
})
app.listen(3000)
核心概念
1. 中间件链
Express 的一切都是中间件:(req, res, next) => {}。
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url}`)
next() // 不调用 next() 请求就停在这里
}
app.use(logger) // 全局
app.get('/a', [auth, handler]) // 路由级
忘记调 next() 是新手最常见的 bug——请求会挂住直到超时。
2. Express 5 的 async 支持
Express 4 里这样写会静默失败(Promise 拒绝没人管,请求挂起):
app.get('/x', async (req, res) => {
throw new Error('boom') // Express 4:进程可能崩,请求无响应
})
Express 5 会正确地把异常交给错误中间件。这是升级到 5.x 最实际的理由。
3. Router 模块化
// routes/users.js
const router = require('express').Router()
router.get('/', listUsers)
router.post('/', createUser)
module.exports = router
// app.js
app.use('/api/users', require('./routes/users'))
4. 路径语法变化(5.x 破坏性改动)
// Express 4
app.get('/files/*', handler) // * 匹配剩余
// Express 5:必须命名
app.get('/files/*splat', handler)
// 可选参数语法也变了
app.get('/users/:id?', handler) // 4.x
app.get('/users{/:id}', handler) // 5.x
迁移时这类路由要逐个改。
常见坑
① 没有内置 body 解析以外的能力
express.json() 只处理 JSON。上传文件要 multer,校验要 joi/zod,认证要 passport,安全头要 helmet。这些都要自己拼。
② req.params 和 req.query 都是字符串
不会自动转类型。req.query.limit 是 "10" 不是 10,做数学运算前要 Number()。
③ 错误中间件必须四个参数
app.use((err, req, res, next) => {}) // ✅
app.use((err, req, res) => {}) // ❌ 不会被当错误处理器
④ 中间件顺序即逻辑
app.use(express.json()) 必须在处理请求体之前;错误中间件必须在所有路由之后。顺序错了就是玄学 bug。
什么时候选它
- 维护老项目(存量最多)
- 需要大量现成中间件
- 快速出原型
- 团队已经熟悉
不选它的场景:要性能(选 Fastify)、要架构约定(选 NestJS)、要边缘部署(选 Hono)。
一个迁移提醒
从 4.x 升到 5.x 的实际风险点:
- 路径语法:
*必须改命名形式,?可选参数要换成{}语法 res.sendFile的行为:根路径处理有变- 移除的方法:
res.send(status)、app.del()等已删除
建议:先在测试环境跑通全部路由,再上生产。Express 5 的收益主要是 async 错误处理,如果你的项目全是同步 handler,升级的紧迫性不高。