若手開発者にとって、Node.js バックエンドの構築で最も難しい側面の 1 つは、コード自体を記述することではなく、スケーラブルな方法でコードを編成することです。今日は、アプリケーションのテンプレートとして使用できる、本番環境に対応した Node.js プロジェクト構造について説明します。
非構造化コードの問題
本題に入る前に、本が本棚にランダムに配置されている図書館で、特定の本を見つけようとしているところを想像してみてください。イライラしますよね?同じことがコードにも当てはまります。適切な構造がなければ、Node.js アプリケーションはすぐにスパゲッティ コードの迷路となり、維持や拡張が困難になる可能性があります。
より良い方法: 最新の Node.js プロジェクト構造
多くの成功した企業が使用しているプロフェッショナル レベルの Node.js プロジェクト構造を詳しく見てみましょう:
?バックエンド/
§─? src/
│ ── ? @types # TypeScript の型定義
│ ━─? config # 設定ファイル
│ ── ?コントローラ # リクエストハンドラ
│ ── ?エンティティ # データベース モデル/エンティティ
│ ── ? helper # ヘルパー/ユーティリティ関数
│ ── ?ミドルウェア # Express ミドルウェア
│ ── ?ルート # API ルート定義
│ ── ?サービス # ビジネスロジック
│ ── ? type # 追加の型定義
│ ── ? utils # ユーティリティ関数
━──? app.ts # アプリケーションエントリーポイント
━──? .eslintrc.js # ESLint 構成
━──? .prettierrc # Prettier 設定
━──? Dockerfile # Docker 構成
━──? package.json # プロジェクトの依存関係
━──? tsconfig.json # TypeScript 設定
━──? .dockerignore # Docker はルールを無視します
━──? .env # 環境変数
━──? docker-compose.yml #Docker Compose 構成
各コンポーネントを理解する
1. @types と types ディレクトリ
`// @types/express/index.d.ts declare namespace Express { export interface Request { user?: { id: string; role: string; }; } }`
これらのフォルダーには TypeScript の型定義が含まれています。 @types フォルダーには通常、外部モジュールの宣言が含まれ、types フォルダーにはアプリケーション固有の型が含まれます。
2.構成ディレクトリ
// config/database.ts export const dbConfig = { host: process.env.DB_HOST, port: process.env.DB_PORT, username: process.env.DB_USER, // … other configuration };
このディレクトリにはすべての構成ファイルが格納され、さまざまな環境 (開発、ステージング、運用) の管理が容易になります。
3.コントローラー
// controllers/userController.ts export class UserController { async getUser(req: Request, res: Response) { try { const user = await userService.findById(req.params.id); res.json(user); } catch (error) { res.status(500).json({ error: error.message }); } } }
コントローラーは HTTP リクエストとレスポンスを処理し、ルートとサービス間のブリッジとして機能します。
4.エンティティ
typescript// entity/User.ts @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() username: string; @Column() email: string; }
エンティティ ディレクトリにはデータベース モデルが含まれており、通常は TypeORM や Sequelize などの ORM を使用します。
5.サービス
services/userService.ts export class UserService { async createUser(userData: CreateUserDto) { const user = new User(); Object.assign(user, userData); return await this.userRepository.save(user); } }
サービスにはビジネス ロジックが含まれており、コントローラーから分離されています。
6.ミドルウェア
`// @types/express/index.d.ts declare namespace Express { export interface Request { user?: { id: string; role: string; }; } }`
ミドルウェアは、認証、ロギング、エラー処理などの横断的な問題を処理します。
ベストプラクティスとヒント
1.単一の責任: 各ディレクトリには明確な単一の目的がある必要があります。ビジネス ロジックとルート定義を混同しないでください。
2.依存関係の注入: 依存関係の注入を使用すると、コードのテストと保守が容易になります。
// config/database.ts export const dbConfig = { host: process.env.DB_HOST, port: process.env.DB_PORT, username: process.env.DB_USER, // … other configuration };
3.環境構成: 環境固有の変数には .env ファイルを使用し、バージョン管理には決してコミットしないでください。
4. Docker 統合: Dockerfile と docker-compose.yml の存在は、コンテナ化のサポートを示し、環境間でデプロイの一貫性を確保します。
避けるべき一般的な落とし穴
循環依存関係: モジュール間に循環依存関係を作成しないように注意してください。
大容量ファイル: ファイルが大きくなりすぎる場合は、処理が過剰になっている可能性があります。より小さな、焦点を絞ったモジュールに分割します。
一貫性のないエラー処理: アプリケーション全体で一貫したエラー処理戦略を確立します。
結論
長期的な保守性とスケーラビリティには、適切に構造化された Node.js アプリケーションが不可欠です。この構造は、アプリケーションの成長に合わせて構築できる強固な基盤を提供します。目標は単に動作させることではなく、保守可能でスケーラブルで、楽しく作業できるようにすることであることを忘れないでください。
次回新しい Node.js プロジェクトを開始するときは、この構造をテンプレートとして使用することを検討してください。これにより、数え切れないほどのリファクタリング時間が節約され、コードベースが初日からよりプロフェッショナルなものになります。
プロのヒント: この構造でテンプレート リポジトリを作成すると、同じ組織で新しいプロジェクトを迅速にブートストラップできます。
以上がNode.js バックエンド スケーラブルなアプリの構築: プロジェクト構造の実践ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。