nodejs-best-practices
Node.js開発における原則と意思決定をサポートするスキルです。フレームワーク選定・非同期パターン・セキュリティ・アーキテクチャ設計など、コードのコピーではなく「考え方」を身につけることを重視します。
description の原文を見る
Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
SKILL.md 本文
Node.js Best Practices
2025年のNode.js開発における原則と意思決定。 コードパターンの暗記ではなく、考える力を学ぶ。
使用時機
Node.jsのアーキテクチャ決定、フレームワーク選択、非同期パターン設計、セキュリティやデプロイのベストプラクティス適用時に使用します。
⚠️ このスキルの使い方
このスキルは、固定されたコードを教えるのではなく、意思決定の原則を教えます。
- 不明な点は用者に選好を聞く
- フレームワーク/パターンを文脈に基づいて選択
- 毎回同じソリューションにデフォルトしない
1. フレームワーク選択 (2025)
意思決定ツリー
何を構築していますか?
│
├── エッジ/サーバーレス (Cloudflare, Vercel)
│ └── Hono (ゼロ依存、超高速なコールドスタート)
│
├── 高性能API
│ └── Fastify (Expressより2~3倍高速)
│
├── エンタープライズ/チーム経験
│ └── NestJS (構造化、DI、デコレータ)
│
├── レガシー/安定/最大エコシステム
│ └── Express (成熟、最多のミドルウェア)
│
└── フロントエンドを含むフルスタック
└── Next.js API Routes または tRPC
比較の原則
| 要素 | Hono | Fastify | Express |
|---|---|---|---|
| 最適用途 | エッジ、サーバーレス | パフォーマンス | レガシー、学習 |
| コールドスタート | 最速 | 高速 | 中程度 |
| エコシステム | 成長中 | 良好 | 最大 |
| TypeScript | ネイティブ | 優秀 | 良好 |
| 学習曲線 | 低 | 中程度 | 低 |
選択時の質問:
- デプロイ先はどこか?
- コールドスタート時間は重要か?
- チームに既存経験があるか?
- 保守するレガシーコードはあるか?
2. ランタイム考慮事項 (2025)
ネイティブ TypeScript
Node.js 22+: --experimental-strip-types
├── .tsファイルを直接実行
├── シンプルなプロジェクトではビルドステップ不要
└── 対象: スクリプト、シンプルなAPI
モジュールシステムの決定
ESM (import/export)
├── モダン標準
├── ツリーシェイキングが優れている
├── 非同期モジュール読み込み
└── 用途: 新規プロジェクト
CommonJS (require)
├── レガシー互換性
├── より多くのnpmパッケージがサポート
└── 用途: 既存コードベース、一部のエッジケース
ランタイム選択
| ランタイム | 最適用途 |
|---|---|
| Node.js | 汎用、最大のエコシステム |
| Bun | パフォーマンス、組み込みバンドラー |
| Deno | セキュリティファースト、組み込みTypeScript |
3. アーキテクチャの原則
レイヤード構造の概念
リクエストフロー:
│
├── コントローラー/ルートレイヤー
│ ├── HTTP特有の処理を処理
│ ├── 境界での入力検証
│ └── サービスレイヤーを呼び出し
│
├── サービスレイヤー
│ ├── ビジネスロジック
│ ├── フレームワークに依存しない
│ └── リポジトリレイヤーを呼び出し
│
└── リポジトリレイヤー
├── データアクセスのみ
├── データベースクエリ
└── ORMの相互作用
なぜこれが重要か:
- テスト容易性: レイヤーを独立してモック
- 柔軟性: ビジネスロジックに触れずにデータベースを入れ替え
- 明確性: 各レイヤーは単一の責任を持つ
簡略化するとき:
- 小規模スクリプト → 単一ファイルでOK
- プロトタイプ → 構造を減らすことが許容可能
- 常に聞く: 「これは成長するだろうか?」
4. エラーハンドリングの原則
集中管理されたエラーハンドリング
パターン:
├── カスタムエラークラスを作成
├── どのレイヤーからでもスロー
├── トップレベル(ミドルウェア)でキャッチ
└── 一貫したレスポンス形式
エラーレスポンスの哲学
クライアントが得るもの:
├── 適切なHTTPステータス
├── プログラム的な処理用のエラーコード
├── ユーザーフレンドリーなメッセージ
└── 内部詳細なし (セキュリティ!)
ログが記録するもの:
├── 完全なスタックトレース
├── リクエストコンテキスト
├── ユーザーID (該当する場合)
└── タイムスタンプ
ステータスコード選択
| 状況 | ステータス | 時期 |
|---|---|---|
| 不正な入力 | 400 | クライアントが無効なデータを送信 |
| 認証なし | 401 | 認証情報が欠落または無効 |
| 権限なし | 403 | 有効な認証だが許可されていない |
| 見つからない | 404 | リソースが存在しない |
| 競合 | 409 | 重複または状態の競合 |
| 検証 | 422 | スキーマは有効だがビジネスルールが失敗 |
| サーバーエラー | 500 | こちら側の不具合、すべてをログ |
5. 非同期パターンの原則
各パターンを使う時期
| パターン | 使う時期 |
|---|---|
async/await | 順序付き非同期操作 |
Promise.all | 並列の独立した操作 |
Promise.allSettled | 並列で一部が失敗する可能性がある場合 |
Promise.race | タイムアウトまたは最初のレスポンスが勝つ |
イベントループの認識
I/O バウンド (非同期が役立つ):
├── データベースクエリ
├── HTTPリクエスト
├── ファイルシステム
└── ネットワーク操作
CPU バウンド (非同期は役立たない):
├── 暗号化操作
├── 画像処理
├── 複雑な計算
└── → ワーカースレッドを使用または処理を委譲
イベントループブロッキングの回避
- プロダクションで同期メソッドを使用しない (fs.readFileSync等)
- CPU集約的な作業を委譲
- 大容量データのストリーミングを使用
6. 検証の原則
境界で検証
検証する場所:
├── APIエントリーポイント (リクエストボディ/パラメータ)
├── データベース操作の前
├── 外部データ (APIレスポンス、ファイルアップロード)
└── 環境変数 (スタートアップ)
検証ライブラリ選択
| ライブラリ | 最適用途 |
|---|---|
| Zod | TypeScriptファースト、型推論 |
| Valibot | より小さいバンドル (ツリーシェイク可能) |
| ArkType | パフォーマンスが重要 |
| Yup | 既存のReact Form利用 |
検証の哲学
- 早期に失敗: 早期に検証
- 具体的に: 明確なエラーメッセージ
- 信頼しない: 「内部」データでさえも
7. セキュリティの原則
セキュリティチェックリスト (コードではなく)
- 入力検証: すべての入力が検証されている
- パラメータ化クエリ: SQLの文字列連結なし
- パスワードハッシング: bcryptまたはargon2
- JWT検証: 常に署名と有効期限を検証
- レート制限: 悪用から保護
- セキュリティヘッダー: Helmet.jsまたは同等品
- HTTPS: プロダクションでは必須
- CORS: 適切に設定
- シークレット: 環境変数のみ
- 依存関係: 定期的に監査
セキュリティの考え方
何も信頼しない:
├── クエリパラメータ → 検証
├── リクエストボディ → 検証
├── ヘッダー → 検証
├── クッキー → 検証
├── ファイルアップロード → スキャン
└── 外部API → レスポンスを検証
8. テストの原則
テスト戦略選択
| タイプ | 目的 | ツール |
|---|---|---|
| ユニット | ビジネスロジック | node:test, Vitest |
| 統合 | APIエンドポイント | Supertest |
| E2E | 完全なフロー | Playwright |
何をテストするか (優先順位)
- 重要なパス: 認証、支払い、中核ビジネス
- エッジケース: 空の入力、境界
- エラーハンドリング: 物事が失敗したときはどうなるか?
- テストする価値なし: フレームワークコード、自明なゲッター
組み込みテストランナー (Node.js 22+)
node --test src/**/*.test.ts
├── 外部依存なし
├── 良好なカバレッジレポート
└── ウォッチモード利用可能
9. 避けるべきアンチパターン
❌ してはいけない:
- 新規エッジプロジェクトでExpressを使う (Honoを使用)
- プロダクションコードで同期メソッドを使う
- コントローラーにビジネスロジックを置く
- 入力検証をスキップ
- シークレットをハードコード
- 検証なしで外部データを信頼
- CPU作業でイベントループをブロック
✅ すべき:
- 文脈に基づいてフレームワークを選択
- 不明な点はユーザーに選好を聞く
- 成長するプロジェクトにはレイヤード構造を使用
- すべての入力を検証
- シークレットには環境変数を使用
- 最適化する前にプロファイル
10. 決定チェックリスト
実装する前に:
- ユーザーのスタック選好を聞いた?
- このコンテキストに対してフレームワークを選択した? (デフォルトではなく)
- デプロイ先を考慮した?
- エラーハンドリング戦略を計画した?
- 検証ポイントを特定した?
- セキュリティ要件を考慮した?
覚えておいてください: Node.jsのベストプラクティスはパターンの暗記ではなく、意思決定についてです。すべてのプロジェクトは、その要件に基づいた新鮮な検討に値します。
制限事項
- このスキルは、上記で説明されたスコープと明確に一致する場合にのみ使用してください。
- 出力を環境固有の検証、テスト、またはエキスパートレビューの代替として扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が欠落している場合は、立ち止まって明確化を求めてください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- sickn33
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/sickn33/antigravity-awesome-skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。