
关于
Node.js 开发原则与决策方法。框架选型、异步模式、安全和架构。注重思维方式而非照搬代码。
name: nodejs-best-practices description: "Node.js 开发原则与决策制定。框架选择、异步模式、安全性和架构。教你思考,而非复制。" risk: unknown source: community date_added: "2026-02-27"
Node.js 最佳实践
2025年 Node.js 开发的原则与决策制定。 学会思考,而非死记代码模式。
何时使用
在做 Node.js 架构决策、选择框架、设计异步模式或应用安全和部署最佳实践时使用此技能。
如何使用此技能
此技能教授决策制定原则,而非固定的可复制代码。
- 不确定时向用户询问偏好
- 根据上下文选择框架/模式
- 不要每次都默认使用相同的解决方案
1. 框架选择 (2025)
决策树
你在构建什么?
│
├── Edge/Serverless (Cloudflare, Vercel)
│ └── Hono(零依赖,超快冷启动)
│
├── 高性能 API
│ └── Fastify(比 Express 快 2-3 倍)
│
├── 企业级/团队熟悉度
│ └── NestJS(结构化、DI、装饰器)
│
├── 遗留/稳定/最大生态系统
│ └── Express(成熟,最多中间件)
│
└── 全栈含前端
└── Next.js API Routes 或 tRPC
比较原则
| 因素 | Hono | Fastify | Express | |------|------|---------|---------| | 最适合 | Edge, serverless | 性能 | 遗留项目, 学习 | | 冷启动 | 最快 | 快 | 中等 | | 生态系统 | 增长中 | 良好 | 最大 | | TypeScript | 原生 | 优秀 | 良好 | | 学习曲线 | 低 | 中等 | 低 |
选择时要问的问题:
- 部署目标是什么?
- 冷启动时间是否关键?
- 团队是否有现有经验?
- 是否有需要维护的遗留代码?
2. 运行时考虑 (2025)
原生 TypeScript
Node.js 22+: --experimental-strip-types
├── 直接运行 .ts 文件
├── 简单项目无需构建步骤
└── 适用于:脚本、简单 API
模块系统决策
ESM (import/export)
├── 现代标准
├── 更好的 tree-shaking
├── 异步模块加载
└── 用于:新项目
CommonJS (require)
├── 遗留兼容性
├── 更多 npm 包支持
└── 用于:现有代码库、某些边缘情况
运行时选择
| 运行时 | 最适合 | |--------|--------| | Node.js | 通用,最大生态系统 | | Bun | 性能,内置打包器 | | Deno | 安全优先,内置 TypeScript |
3. 架构原则
分层结构概念
请求流程:
│
├── 控制器/路由层
│ ├── 处理 HTTP 细节
│ ├── 在边界进行输入验证
│ └── 调用服务层
│
├── 服务层
│ ├── 业务逻辑
│ ├── 框架无关
│ └── 调用仓储层
│
└── 仓储层
├── 仅数据访问
├── 数据库查询
└── ORM 交互
为什么这很重要:
- 可测试性:独立模拟各层
- 灵活性:无需触及业务逻辑即可更换数据库
- 清晰性:每层都有单一职责
何时简化:
- 小脚本 → 单文件即可
- 原型 → 较少结构可接受
- 始终问自己:"这会增长吗?"
4. 错误处理原则
集中式错误处理
模式:
├── 创建自定义错误类
├── 从任何层抛出
├── 在顶层捕获(中间件)
└── 格式化一致的响应
错误响应哲学
客户端获得:
├── 适当的 HTTP 状态码
├── 用于程序化处理的错误代码
├── 用户友好的消息
└── 不包含内部细节(安全!)
日志获得:
├── 完整堆栈跟踪
├── 请求上下文
├── 用户 ID(如适用)
└── 时间戳
状态码选择
| 情况 | 状态码 | 何时使用 | |------|--------|----------| | 错误输入 | 400 | 客户端发送了无效数据 | | 未认证 | 401 | 缺少或无效的凭证 | | 无权限 | 403 | 有效认证,但不允许 | | 未找到 | 404 | 资源不存在 | | 冲突 | 409 | 重复或状态冲突 | | 验证失败 | 422 | 模式有效但业务规则失败 | | 服务器错误 | 500 | 我们的错,记录所有信息 |
5. 异步模式原则
何时使用各模式
| 模式 | 使用场景 |
|------|----------|
| async/await | 顺序异步操作 |
| Promise.all | 并行独立操作 |
| Promise.allSettled | 并行且部分可失败 |
| Promise.race | 超时或第一个响应获胜 |
事件循环意识
I/O 密集型(异步有帮助):
├── 数据库查询
├── HTTP 请求
├── 文件系统
└── 网络操作
CPU 密集型(异步无帮助):
├── 加密操作
├── 图像处理
├── 复杂计算
└── → 使用 worker threads 或卸载
避免阻塞事件循环
- 生产环境中永远不要使用同步方法(fs.readFileSync 等)
- 卸载 CPU 密集型工作
- 对大数据使用流式处理
