在使用 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'); // 中间件设置 app.use(express.json()); // 路由设置 app.use('/api', routes); // 启动服务器 const PORT = config.port || 3000; app.listen(PORT, () => { console.log(`服务器在端口 ${PORT} 上运行`); }); module.exports = app;
bin
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 === 'tring'? 'Pipe ' port : 'Port ' port; switch (error.code) { case 'EACCES': console.error(bind + '要提升权限'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + '被占用'); process.exit(1); break; default: throw error; } } function onListening() { const addr = server.address(); const bind = typeof addr === 'tring'? 'pipe ' addr : 'port ' addr.port; debug('在 ' bind + '监听'); }
config
config
目录包含您应用程序的配置文件,例如数据库连接、服务器设置和环境变量。
示例:config/index.js
module.exports = { port: process.env.PORT || 3000, db: { host: 'localhost', port: 27017, name: 'ydatabase' } };
controllers
控制器包含处理传入请求并生成响应的逻辑。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({ 消息: err.message }); } };
middleware
中间件函数用于在请求到达控制器之前处理请求。它们可以处理诸如身份验证、日志记录和请求验证等任务。
示例:middleware/auth.js
module.exports = (req, res, next) => { const token = req.header('Authorization'); if (!token) return res.status(401).json({ 消息: '访问被拒绝' }); try { const verified = jwt.verify(token, process.env.JWT_SECRET); req.user = verified; next(); } catch (err) { res.status(400).json({ 消息: '无效令牌' }); } };
models
模型定义了您数据的结构并处理与数据库的交互。每个模型文件通常对应于不同的数据实体(例如,客户、产品)。
示例:models/customer.js
const mongoose = require('mongoose'); const customerSchema = new mongoose.Schema({ 名称: { 类型: String, 必需: true }, 电子邮件: { 类型: String, 必需: true, 唯一: true }, 创建时间: { 类型: Date, 默认: Date.now } }); module.exports = mongoose.model('Customer', customerSchema);
routes
路由定义了应用程序不同部分的路径,并将它们映射到相应的控制器。
示例:routes/api.js
const express = require('express'); const router = express.Router(); const customerController = require('../controllers/customer'); router.get('/customers', customerController.getAllCustomers); module.exports = router;
public
public
目录包含直接提供给客户端的静态文件,如 CSS、JavaScript 和图像。
示例:目录结构
public/ ├── css/ ├── js/ ├── images/
views
视图是为客户端呈现 HTML 的模板。使用像 EJS、Pug 或 Handlebars 这样的模板引擎,您可以生成动态 HTML。
示例:views/index.ejs
<!DOCTYPE html> <html> <head> <title>我的应用程序</title> <link rel="stylesheet" href="/css/styles.css"> </head> <body> <h1>欢迎来到我的应用程序</h1> <div id="content"> <%- content %> </div> </body> </html>
tests
tests
目录包含用于确保您的应用程序正常工作的测试文件。测试通常分为单元测试、集成测试和端到端(e2e)测试。
示例:目录结构
tests/ ├── unit/ ├── integration/ ├── e2e/
utils
实用函数和辅助模块存储在utils
目录中。这些函数执行整个应用程序中使用的常见任务,如验证和格式化。
示例:utils/validation.js
exports.isEmailValid = (email) => { const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(String(email).toLowerCase()); };
node_modules
node_modules
目录包含项目所需的所有依赖项。此目录由 npm(或 yarn)管理,并包括从 npm 注册表安装的包。
结论
使用 Express.js 构建结构良好的 Node.js 应用程序可增强可维护性、可扩展性和协作性。结构中的每个目录和文件都有特定的用途,从处理配置和定义路由到管理中间件和呈现视图。通过有效地组织代码库,您可以轻松构建强大且可扩展的应用程序。
请注意,在尝试获取相关网页内容时,出现了网页解析失败或加载超时的问题,请您检查网页或稍后重试。