mcpField
N
nodejs-best-practices

nodejs-best-practices

github.com/midudev開発7.0k65 回インストール1 日前に更新
リポジトリ

nodejs-best-practices について

Node.js 開発者向けに、アーキテクチャ、フレームワーク、非同期処理、安全対策の選択を案内するガイドです。定型的な手順を押し付けず、プロジェクトの状況や要件に応じた判断を重視します。

主な機能

  1. 01状況に応じたフレームワーク選定
  2. 02ランタイムとモジュール方式の指針
  3. 03レイヤードアーキテクチャの原則
  4. 04非同期処理とイベントループの推奨事項
  5. 05入力検証とセキュリティチェックリスト
  6. 06テスト戦略とアンチパターン

活用シーン

  1. 01デプロイ先に適したフレームワークの選定
  2. 02成長するアプリケーションの設計
  3. 03非同期処理とイベントループのリスク確認
  4. 04検証・セキュリティ・テストの優先度評価

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/midudev/autoskills --skill nodejs-best-practices

インストール後、Claude Code で/nodejs-best-practicesを入力して読み込まれたか確認します。

詳細

Node.js ベストプラクティス

2025 年における Node.js 開発の原則と意思決定。 コードパターンを暗記するのではなく、考えることを学びましょう。

使用する場面

Node.js のアーキテクチャを決定するとき、フレームワークを選定するとき、非同期パターンを設計するとき、あるいはセキュリティとデプロイのベストプラクティスを適用するときに、このスキルを使用してください。


⚠️ このスキルの使い方

このスキルは、コピーするための固定されたコードではなく、意思決定の原則を教えるものです。

  • 不明な点がある場合は、ユーザーに好みを尋ねる
  • コンテキストに基づいてフレームワークやパターンを選ぶ
  • 毎回同じ解決策をデフォルトにしない

1. フレームワークの選定(2025 年)

決定木
What are you building?
│
├── Edge/Serverless (Cloudflare, Vercel)
│   └── Hono (zero-dependency, ultra-fast cold starts)
│
├── High Performance API
│   └── Fastify (2-3x faster than Express)
│
├── Enterprise/Team familiarity
│   └── NestJS (structured, DI, decorators)
│
├── Legacy/Stable/Maximum ecosystem
│   └── Express (mature, most middleware)
│
└── Full-stack with frontend
    └── Next.js API Routes or tRPC
比較の原則
要因HonoFastifyExpress
最適な用途エッジ、サーバーレスパフォーマンスレガシー、学習
コールドスタート最速高速中程度
エコシステム成長中良好最大
TypeScriptネイティブ優秀良好
学習曲線低い中程度低い
尋ねるべき選定の質問:
  1. デプロイ先は何ですか?
  2. コールドスタート時間は重要ですか?
  3. チームに既存の経験はありますか?
  4. 維持すべきレガシーコードはありますか?

2. ランタイムの考慮事項(2025 年)

ネイティブ TypeScript
Node.js 22+: --experimental-strip-types
├── Run .ts files directly
├── No build step needed for simple projects
└── Consider for: scripts, simple APIs
モジュールシステムの決定
ESM (import/export)
├── Modern standard
├── Better tree-shaking
├── Async module loading
└── Use for: new projects

CommonJS (require)
├── Legacy compatibility
├── More npm packages support
└── Use for: existing codebases, some edge cases
ランタイムの選定
ランタイム最適な用途
Node.js汎用、最大のエコシステム
Bunパフォーマンス、ビルトインのバンドラー
Denoセキュリティ優先、ビルトインの TypeScript

3. アーキテクチャの原則

レイヤード構造の概念
Request Flow:
│
├── Controller/Route Layer
│   ├── Handles HTTP specifics
│   ├── Input validation at boundary
│   └── Calls service layer
│
├── Service Layer
│   ├── Business logic
│   ├── Framework-agnostic
│   └── Calls repository layer
│
└── Repository Layer
    ├── Data access only
    ├── Database queries
    └── ORM interactions
これが重要な理由:
  • テスト容易性:レイヤーを独立してモックできる
  • 柔軟性:ビジネスロジックに触れずにデータベースを差し替えられる
  • 明確さ:各レイヤーが単一の責任を持つ
簡素化すべき場面:
  • 小さなスクリプト → 単一ファイルで OK
  • プロトタイプ → 構造が少なくても許容される
  • 常に尋ねる:「これは成長するか?」

4. エラーハンドリングの原則

集中化されたエラーハンドリング
Pattern:
├── Create custom error classes
├── Throw from any layer
├── Catch at top level (middleware)
└── Format consistent response
エラー応答の考え方
Client gets:
├── Appropriate HTTP status
├── Error code for programmatic handling
├── User-friendly message
└── NO internal details (security!)

Logs get:
├── Full stack trace
├── Request context
├── User ID (if applicable)
└── Timestamp
ステータスコードの選択
状況ステータスいつ
不正な入力400クライアントが無効なデータを送信した
認証なし401認証情報の欠落または無効
権限なし403認証は有効だが、許可されていない
見つからない404リソースが存在しない
競合409重複または状態の競合
バリデーション422スキーマは有効だがビジネスルールに失敗
サーバーエラー500こちらの責任、すべてログに記録する

5. 非同期パターンの原則

それぞれを使う場面
パターン使う場面
async/await逐次的な非同期操作
Promise.all並列の独立した操作
Promise.allSettled一部が失敗する可能性がある並列処理
Promise.raceタイムアウトまたは最初の応答が勝つ場合
イベントループへの意識
I/O-bound (async helps):
├── Database queries
├── HTTP requests
├── File system
└── Network operations

CPU-bound (async doesn't help):
├── Crypto operations
├── Image processing
├── Complex calculations
└── → Use worker threads or offload
イベントループのブロッキングを避ける
  • 本番環境では同期メソッドを決して使わない(fs.readFileSync など)
  • CPU 負荷の高い処理をオフロードする
  • 大きなデータにはストリーミングを使う

6. バリデーションの原則

境界でバリデーションする
Where to validate:
├── API entry point (request body/params)
├── Before database operations
├── External data (API responses, file uploads)
└── Environment variables (startup)
バリデーションライブラリの選定
ライブラリ最適な用途
ZodTypeScript ファースト、型推論
Valibotより小さなバンドル(ツリーシェイク可能)
ArkTypeパフォーマンス重視
Yup既存の React Form での使用
バリデーションの考え方
  • フェイルファスト:早期にバリデーションする
  • 具体的に:明確なエラーメッセージ
  • 信用しない:「内部」データであっても

7. セキュリティの原則

セキュリティチェックリスト(コードではない)
  • 入力バリデーション:すべての入力をバリデーションする
  • パラメータ化クエリ:SQL に文字列連結を使わない
  • パスワードハッシュ:bcrypt または argon2
  • JWT 検証:常に署名と有効期限を検証する
  • レート制限:悪用から保護する
  • セキュリティヘッダー:Helmet.js または同等のもの
  • HTTPS:本番環境では常に
  • CORS:適切に設定する
  • シークレット:環境変数のみ
  • 依存関係:定期的に監査する
セキュリティのマインドセット
Trust nothing:
├── Query params → validate
├── Request body → validate
├── Headers → verify
├── Cookies → validate
├── File uploads → scan
└── External APIs → validate response

8. テスト原則

テスト戦略の選択
種類目的ツール
単体ビジネスロジックnode:test、Vitest
統合API エンドポイントSupertest
E2E全フローPlaywright
テストすべきもの (優先順位)
  1. クリティカルパス: 認証、決済、中核ビジネス
  2. エッジケース: 空の入力、境界値
  3. エラーハンドリング: 失敗したときに何が起こるか?
  4. テストする価値がないもの: フレームワークのコード、自明な getter
組み込みテストランナー (Node.js 22+)
node --test src/**/*.test.ts
├── No external dependency
├── Good coverage reporting
└── Watch mode available

9. 避けるべきアンチパターン

❌ やってはいけないこと:
  • 新しいエッジプロジェクトで Express を使う (Hono を使う)
  • 本番コードで同期メソッドを使う
  • コントローラーにビジネスロジックを置く
  • 入力バリデーションを省略する
  • シークレットをハードコードする
  • バリデーションなしで外部データを信頼する
  • CPU 処理でイベントループをブロックする
✅ やるべきこと:
  • コンテキストに基づいてフレームワークを選ぶ
  • 不明な場合はユーザーに好みを尋ねる
  • 成長するプロジェクトにはレイヤードアーキテクチャを使う
  • すべての入力をバリデーションする
  • シークレットには環境変数を使う
  • 最適化の前にプロファイリングする

10. 意思決定チェックリスト

実装する前に:

  • ユーザーにスタックの好みを尋ねましたか?
  • このコンテキストに合ったフレームワークを選びましたか? (単なるデフォルトではなく)
  • デプロイ先を検討しましたか?
  • エラーハンドリング戦略を計画しましたか?
  • バリデーションのポイントを特定しましたか?
  • セキュリティ要件を検討しましたか?

覚えておいてください: Node.js のベストプラクティスとは、パターンを暗記することではなく、意思決定に関するものです。すべてのプロジェクトは、その要件に基づいて新たに検討される価値があります。

制限事項

  • このスキルは、タスクが上記のスコープに明確に一致する場合にのみ使用してください。
  • 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
  • 必要な入力、権限、安全境界、または成功基準が欠けている場合は、停止して確認を求めてください。

コメント