nodejs-best-practices

nodejs-best-practices

熱門

Node.js 開發原則與決策方法。框架選擇、非同步模式、安全性與架構。教你思考,而非複製。

4.2萬星標
6745分支
更新於 2026/7/1
SKILL.md
readonlyread-only
name
nodejs-best-practices
description

Node.js 開發原則與決策方法。框架選擇、非同步模式、安全性與架構。教你思考,而非複製。

Node.js 最佳實務

2025 年 Node.js 開發的原則與決策方法。
學會思考,而非死記程式碼模式。

使用時機

當你需要進行 Node.js 架構決策、選擇框架、設計非同步模式,或應用安全性與部署最佳實務時,使用此技能。


⚠️ 如何使用此技能

此技能教導決策原則,而非固定的程式碼複製。

  • 若不清楚使用者偏好,請主動詢問
  • 根據情境選擇框架/模式
  • 不要每次都預設使用同一種解決方案

1. 框架選擇(2025)

決策樹

你在建置什麼?
│
├── Edge/Serverless(Cloudflare、Vercel)
│   └── Hono(零依賴、超快冷啟動)
│
├── 高效能 API
│   └── Fastify(比 Express 快 2-3 倍)
│
├── 企業級/團隊熟悉度
│   └── NestJS(結構化、依賴注入、裝飾器)
│
├── 既有/穩定/最大生態系
│   └── Express(成熟、最多中介軟體)
│
└── 前後端全端
    └── Next.js API Routes 或 tRPC

比較原則

因素 Hono Fastify Express
最佳用途 Edge、Serverless 效能 既有系統、學習
冷啟動 最快 中等
生態系 成長中 良好 最大
TypeScript 原生支援 極佳 良好
學習曲線 中等

選擇時需提問:

  1. 部署目標是什麼?
  2. 冷啟動時間是否關鍵?
  3. 團隊是否有既有經驗?
  4. 是否有需要維護的既有程式碼?

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 Schema 有效但商業規則失敗
伺服器錯誤 500 我方錯誤,記錄所有資訊

5. 非同步模式原則

各模式使用時機

模式 使用時機
async/await 循序非同步操作
Promise.all 平行獨立操作
Promise.allSettled 平行操作,部分可能失敗
Promise.race 逾時或取第一個回應

事件循環認知

I/O 密集型(非同步有幫助):
├── 資料庫查詢
├── HTTP 請求
├── 檔案系統
└── 網路操作

CPU 密集型(非同步無幫助):
├── 加密操作
├── 圖片處理
├── 複雜計算
└── → 使用 worker threads 或卸載

避免阻塞事件循環

  • 生產環境絕不使用同步方法(如 fs.readFileSync)
  • 卸載 CPU 密集型工作
  • 處理大量資料時使用串流

6. 驗證原則

在邊界驗證

驗證位置:
├── API 進入點(請求主體/參數)
├── 資料庫操作前
├── 外部資料(API 回應、檔案上傳)
└── 環境變數(啟動時)

驗證函式庫選擇

函式庫 最佳用途
Zod TypeScript 優先、型別推論
Valibot 較小套件(可 tree-shake)
ArkType 效能關鍵
Yup 既有 React Form 使用

驗證哲學

  • 快速失敗:及早驗證
  • 明確具體:清晰的錯誤訊息
  • 不信任:即使是「內部」資料

7. 安全性原則

安全檢查清單(非程式碼)

  • [ ] 輸入驗證:所有輸入皆驗證
  • [ ] 參數化查詢:SQL 不使用字串串接
  • [ ] 密碼雜湊:使用 bcrypt 或 argon2
  • [ ] JWT 驗證:務必驗證簽章與過期時間
  • [ ] 速率限制:防止濫用
  • [ ] 安全標頭:使用 Helmet.js 或同等方案
  • [ ] HTTPS:生產環境全面啟用
  • [ ] CORS:正確設定
  • [ ] 機密資訊:僅使用環境變數
  • [ ] 相依套件:定期稽核

安全心態

不信任任何事物:
├── 查詢參數 → 驗證
├── 請求主體 → 驗證
├── 標頭 → 驗證
├── Cookie → 驗證
├── 檔案上傳 → 掃描
└── 外部 API → 驗證回應

8. 測試原則

測試策略選擇

類型 目的 工具
單元測試 商業邏輯 node:test、Vitest
整合測試 API 端點 Supertest
端到端測試 完整流程 Playwright

測試重點(優先順序)

  1. 關鍵路徑:認證、付款、核心商業邏輯
  2. 邊界情況:空輸入、邊界值
  3. 錯誤處理:失敗時會發生什麼?
  4. 不值得測試:框架程式碼、瑣碎的 getter

內建測試執行器(Node.js 22+)

node --test src/**/*.test.ts
├── 無需外部相依
├── 良好的涵蓋率報告
└── 支援監看模式

9. 應避免的反模式

❌ 不要:

  • 在新的 Edge 專案使用 Express(請用 Hono)
  • 在生產程式碼使用同步方法
  • 將商業邏輯放在控制器中
  • 跳過輸入驗證
  • 硬編碼機密資訊
  • 不經驗證就信任外部資料
  • 用 CPU 工作阻塞事件循環

✅ 要:

  • 根據情境選擇框架
  • 若不清楚使用者偏好,請主動詢問
  • 成長中的專案使用分層架構
  • 驗證所有輸入
  • 使用環境變數儲存機密資訊
  • 先分析再最佳化

10. 決策檢查清單

實作前:

  • [ ] 是否詢問使用者技術棧偏好?
  • [ ] 是否根據此情境選擇框架?(而非預設)
  • [ ] 是否考慮部署目標?
  • [ ] 是否規劃錯誤處理策略?
  • [ ] 是否識別驗證點?
  • [ ] 是否考慮安全需求?

記住:Node.js 最佳實務關乎決策,而非死記模式。每個專案都應根據其需求重新審視。

限制

  • 僅在任務明確符合上述範圍時使用此技能。
  • 請勿將輸出視為環境特定驗證、測試或專家審查的替代品。
  • 若缺少必要輸入、權限、安全邊界或成功標準,請停止並要求釐清。