Express 路由组织实践:从单文件到模块化拆分

项目早期只有十几个接口时,把所有路由写在同一个 server.js 里非常直观。但随着接口数量膨胀到三位数,单文件变得难以维护:滚动查找困难、职责边界模糊、同一段中间件被反复复制。本文记录我按业务域把路由拆成 express.Router 模块的完整过程。

1. 拆分前的痛点

当时 server.js 已经超过两千行,路由、中间件、错误处理、启动逻辑全部混在一起。每次改一个接口都要小心翼翼地滑动滚动条,生怕误碰到其他模块。更严重的是,不同业务线的接口混排,导致新成员很难快速定位代码位置。

2. Router 模块化拆分方案

我新建了 routes/ 目录,按业务域划分文件,例如 routes/materials.js、routes/repairs.js、routes/reports.js。每个文件内部创建一个 express.Router(),把相关接口挂上去,最后统一 module.exports = router。server.js 里只需要一行 app.use('/api/materials', require('./routes/materials')),结构立刻清晰起来。

3. 中间件顺序踩坑

拆分后遇到的第一个坑是 body-parser 没有生效。原因是 app.js 里先挂载了路由模块,后调用 app.use(express.json())。Express 中间件按注册顺序执行,因此解析中间件必须放在路由之前。调整后顺序为:安全/日志中间件 → 解析中间件 → 业务路由 → 错误处理中间件。

4. 统一错误处理中间件

以前每个路由里都有 try/catch 重复返回 500。拆分后我在 routes 目录外层定义了一个统一错误处理器,捕获所有未处理的异常并按统一格式返回 { success: false, message: '...' }。这样既减少了重复代码,也方便在测试里集中校验错误码。

5. 收益总结

模块化后,server.js 从两千多行降到不足两百行,新增接口只需新建或修改一个路由文件,Review 范围大幅缩小。同时,业务边界清晰了,写单元测试时可以直接针对单个 Router 注入 mock 请求,测试效率也明显提升。

← 返回首页