Express.js を使用して Node.js アプリケーションを開発する場合、コードベースを効果的に構造化することは、保守性、スケーラビリティ、コラボレーションのしやすさにとって非常に重要です。適切に組織化されたプロジェクト構造により、複雑さを管理できるため、コードの移動と理解が容易になります。このブログでは、Express.js アプリケーションの一般的なフォルダー構造を調べ、各ディレクトリとファイルの目的を説明します。
プロジェクト構造の概要
Express.js アプリケーションの一般的なフォルダー構造は次のとおりです:
? ├── ? app.js ├── ? bin ├── ? config ├── ? controllers │ ├── ? customer.js │ ├── ? product.js │ └── ... ├── ? middleware │ ├── ? auth.js │ ├── ? logger.js │ └── ... ├── ? models │ ├── ? customer.js │ ├── ? product.js │ └── ... ├── ? routes │ ├── ? api.js │ ├── ? auth.js │ └── ... ├── ? public │ ├── ? css │ ├── ? js │ ├── ? images │ └── ... ├── ? views │ ├── ? index.ejs │ ├── ? product.ejs │ └── ... ├── ? tests │ ├── ? unit │ ├── ? integration │ ├── ? e2e │ └── ... ├── ? utils │ ├── ? validation.js │ ├── ? helpers.js │ └── ... └── ? node_modules
各ディレクトリとファイルの説明
app.js
app.js ファイルはアプリケーションのエントリ ポイントです。ここで、Express アプリの初期化、ミドルウェアのセットアップ、ルートの定義、サーバーの起動を行います。これを Web アプリケーションのコントロール センターと考えてください。
const express = require('express'); const app = express(); const config = require('./config'); const routes = require('./routes'); // Middleware setup app.use(express.json()); // Routes setup app.use('/api', routes); // Start server const PORT = config.port || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); module.exports = app;
ビン
通常、bin ディレクトリには、Web サーバーを起動するためのスクリプトが含まれています。これらのスクリプトは、環境変数を設定したり、さまざまな環境 (開発、実稼働など) を管理したりするために使用できます。
例: bin/www
#!/usr/bin/env node const app = require('../app'); const debug = require('debug')('your-app:server'); const http = require('http'); const port = normalizePort(process.env.PORT || '3000'); app.set('port', port); const server = http.createServer(app); server.listen(port); server.on('error', onError); server.on('listening', onListening); function normalizePort(val) { const port = parseInt(val, 10); if (isNaN(port)) return val; if (port >= 0) return port; return false; } function onError(error) { if (error.syscall !== 'listen') throw error; const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } function onListening() { const addr = server.address(); const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); }
構成
config ディレクトリには、データベース接続、サーバー設定、環境変数など、アプリケーションの構成ファイルが保持されます。
例: config/index.js
module.exports = { port: process.env.PORT || 3000, db: { host: 'localhost', port: 27017, name: 'mydatabase' } };
コントローラー
コントローラーには、受信リクエストを処理し、応答を生成するためのロジックが含まれています。通常、controllers ディレクトリ内の各ファイルは、アプリケーションの異なる部分 (顧客、製品など) に対応します。
例:controllers/customer.js
const Customer = require('../models/customer'); exports.getAllCustomers = async (req, res) => { try { const customers = await Customer.find(); res.json(customers); } catch (err) { res.status(500).json({ message: err.message }); } };
ミドルウェア
ミドルウェア関数は、リクエストがコントローラーに到達する前に処理するために使用されます。認証、ロギング、検証リクエストなどのタスクを処理できます。
例: middleware/auth.js
module.exports = (req, res, next) => { const token = req.header('Authorization'); if (!token) return res.status(401).json({ message: 'Access Denied' }); try { const verified = jwt.verify(token, process.env.JWT_SECRET); req.user = verified; next(); } catch (err) { res.status(400).json({ message: 'Invalid Token' }); } };
モデル
モデルはデータの構造を定義し、データベースとの対話を処理します。各モデル ファイルは通常、異なるデータ エンティティ (顧客、製品など) に対応します。
例: models/customer.js
const mongoose = require('mongoose'); const customerSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true }, createdAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('Customer', customerSchema);
ルート
ルートは、アプリケーションのさまざまな部分へのパスを定義し、それらを適切なコントローラーにマップします。
例:routes/api.js
const express = require('express'); const router = express.Router(); const customerController = require('../controllers/customer'); router.get('/customers', customerController.getAllCustomers); module.exports = router;
公開
パブリック ディレクトリには、クライアントに直接提供される CSS、JavaScript、画像などの静的ファイルが含まれています。
例: ディレクトリ構造
public/ ├── css/ ├── js/ ├── images/
ビュー
ビューは、クライアント用に HTML をレンダリングするテンプレートです。 EJS、Pug、Handlebars などのテンプレート エンジンを使用して、動的な HTML を生成できます。
例: views/index.ejs
<!DOCTYPE html> <html> <head> <title>My App</title> <link rel="stylesheet" href="/css/styles.css"> </head> <body> <h1>Welcome to My App</h1> <div id="content"> <%- content %> </div> </body> </html>
テスト
testing ディレクトリには、アプリケーションが正しく動作することを確認するためのテスト ファイルが含まれています。多くの場合、テストは単体テスト、統合テスト、エンドツーエンド (e2e) テストに編成されます。
例: ディレクトリ構造
tests/ ├── unit/ ├── integration/ ├── e2e/
ユーティリティ
ユーティリティ関数とヘルパー モジュールは utils ディレクトリに保存されます。これらの関数は、アプリケーション全体で使用される検証や書式設定などの一般的なタスクを実行します。
例: utils/validation.js
exports.isEmailValid = (email) => { const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(String(email).toLowerCase()); };
ノードモジュール
node_modules ディレクトリには、プロジェクトに必要なすべての依存関係が含まれています。このディレクトリは npm (または Yarn) によって管理され、npm レジストリからインストールされたパッケージが含まれます。
結論
Express.js を使用して適切に構造化された Node.js アプリケーションは、保守性、拡張性、コラボレーションを強化します。構造内の各ディレクトリとファイルは、構成の処理やルートの定義からミドルウェアの管理やビューのレンダリングまで、特定の目的を果たします。コードベースを効果的に編成することで、堅牢でスケーラブルなアプリケーションを簡単に構築できます。
以上がNode.js (Express.js) でバックエンド コードを構造化する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。