项目结构与目录组织规范
项目结构与目录组织规范
Express项目的结构与目录组织对代码的可维护性和可扩展性至关重要。合理的目录结构能让团队成员快速理解项目架构,减少沟通成本,同时便于后期功能扩展和维护。
基础目录结构
典型的Express项目基础目录结构如下:
project-root/
├── node_modules/
├── src/
│ ├── controllers/
│ ├── models/
│ ├── routes/
│ ├── middlewares/
│ ├── services/
│ ├── utils/
│ ├── config/
│ ├── public/
│ ├── views/
│ └── app.js
├── tests/
├── .env
├── .gitignore
├── package.json
└── README.md
核心目录详解
controllers目录
存放业务逻辑处理层,负责接收请求参数、调用服务层处理业务并返回响应:
// src/controllers/userController.js
const userService = require('../services/userService');
exports.getUser = async (req, res) => {
try {
const user = await userService.getUserById(req.params.id);
res.json(user);
} catch (error) {
res.status(500).json({ error: error.message });
}
};
models目录
定义数据模型和数据库交互逻辑,通常与ORM(如Sequelize、Mongoose)配合使用:
// src/models/userModel.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
username: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true }
}, { timestamps: true });
module.exports = mongoose.model('User', userSchema);
routes目录
定义API路由,将请求路由到对应的控制器:
// src/routes/userRoutes.js
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
router.get('/:id', userController.getUser);
router.post('/', userController.createUser);
router.put('/:id', userController.updateUser);
module.exports = router;
进阶目录组织
按功能模块划分
对于大型项目,可以采用功能模块划分的方式:
src/
├── modules/
│ ├── auth/
│ │ ├── auth.controller.js
│ │ ├── auth.model.js
│ │ ├── auth.routes.js
│ │ └── auth.service.js
│ ├── user/
│ │ ├── user.controller.js
│ │ ├── user.model.js
│ │ ├── user.routes.js
│ │ └── user.service.js
│ └── product/
│ ├── product.controller.js
│ ├── product.model.js
│ ├── product.routes.js
│ └── product.service.js
├── core/
│ ├── database.js
│ ├── server.js
│ └── middleware.js
└── app.js
配置管理
将配置信息集中管理,支持不同环境配置:
// src/config/index.js
require('dotenv').config();
module.exports = {
app: {
port: process.env.PORT || 3000,
env: process.env.NODE_ENV || 'development'
},
db: {
uri: process.env.MONGODB_URI,
options: {
useNewUrlParser: true,
useUnifiedTopology: true
}
},
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: '24h'
}
};
中间件组织
中间件应该单独组织,便于复用和管理:
// src/middlewares/authMiddleware.js
const jwt = require('jsonwebtoken');
const config = require('../config');
module.exports = (req, res, next) => {
const token = req.header('Authorization')?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'Access denied' });
}
try {
const decoded = jwt.verify(token, config.jwt.secret);
req.user = decoded;
next();
} catch (error) {
res.status(400).json({ error: 'Invalid token' });
}
};
实用工具组织
将通用工具函数集中管理:
// src/utils/response.js
exports.success = (res, data, status = 200) => {
res.status(status).json({
success: true,
data
});
};
exports.error = (res, message, status = 400) => {
res.status(status).json({
success: false,
error: message
});
};
应用入口文件
主应用文件应该保持简洁,主要负责初始化工作:
// src/app.js
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const config = require('./config');
const routes = require('./routes');
const app = express();
// 中间件
app.use(cors());
app.use(helmet());
app.use(morgan('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 路由
app.use('/api', routes);
// 错误处理
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal Server Error' });
});
module.exports = app;
测试目录结构
测试目录应该镜像源代码结构:
tests/
├── unit/
│ ├── controllers/
│ ├── models/
│ └── services/
├── integration/
│ ├── routes/
│ └── middlewares/
└── e2e/
├── api/
└── auth/
静态资源管理
静态资源应该组织在public目录下:
public/
├── images/
├── css/
├── js/
└── uploads/
视图模板组织
如果使用模板引擎,视图文件应该合理组织:
views/
├── layouts/
│ └── main.hbs
├── partials/
│ ├── header.hbs
│ └── footer.hbs
├── home/
│ └── index.hbs
└── user/
├── profile.hbs
└── edit.hbs
环境变量管理
使用.env文件管理环境变量,并通过dotenv加载:
# .env
PORT=3000
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/myapp
JWT_SECRET=mysecretkey
包管理规范
package.json应该合理组织脚本和依赖:
{
"scripts": {
"start": "node src/app.js",
"dev": "nodemon src/app.js",
"test": "jest",
"lint": "eslint .",
"format": "prettier --write ."
},
"dependencies": {
"express": "^4.18.2",
"mongoose": "^7.0.3"
},
"devDependencies": {
"nodemon": "^2.0.22",
"eslint": "^8.36.0",
"prettier": "^2.8.7"
}
}
文档与说明
项目根目录应该包含必要的文档文件:
- README.md:项目概述、安装说明、使用指南
- CHANGELOG.md:版本变更记录
- API_DOC.md:API接口文档
- .editorconfig:统一编辑器配置
- .eslintrc:代码风格检查配置
- .prettierrc:代码格式化配置
大型项目扩展结构
对于企业级应用,可以考虑更复杂的结构:
src/
├── api/
│ ├── v1/
│ │ ├── modules/
│ │ └── routes.js
│ └── v2/
│ ├── modules/
│ └── routes.js
├── core/
│ ├── exceptions/
│ ├── logging/
│ ├── database/
│ └── utils/
├── jobs/
├── migrations/
├── seeders/
└── app.js
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:中间件的最佳实践总结
下一篇:环境配置与多环境管理