你写了几个 Node.js 项目,发现每次都在重复这些动作:
-
创建 app.js、写一遍路由、中间件、错误处理
-
加入数据库、日志、env 配置,又要复制一遍
-
不同项目目录结构各不相同,换人就头疼
是时候造一个属于自己的「项目模板」了!
本篇我们讲解如何构建一个可快速初始化、可多人协作、可长期演进的:
Node.js 项目模板工程(支持 Koa/Express、TS/JS)
一、我们要解决什么问题?
|
标 |
为什么 |
|---|---|
|
✅ 结构统一 |
团队成员都能快速理解项目目录 |
|
✅ 开箱即用 |
新建项目无需重复配置 |
|
✅ 易扩展 |
插件机制 / 插件式中间件 |
|
✅ 可维护 |
配置清晰、职责分层、约定优于配置 |
二、推荐目录结构
project-template/
├── src/
│ ├── app.js # 应用初始化
│ ├── routes/ # 路由模块
│ ├── controllers/ # 控制器逻辑
│ ├── middlewares/ # 通用中间件
│ ├── services/ # 业务服务层
│ ├── utils/ # 工具函数
│ ├── config/ # 配置管理(env、db、jwt 等)
│ ├── db/ # 数据模型 / ORM 实例
│ └── index.js # 启动入口
├── scripts/ # 初始化脚本 / 模拟数据生成
├── tests/ # 单测 / 接口测试
├── .env / .env.example # 环境变量文件
├── pm2.config.js # PM2 启动配置
├── Dockerfile # Docker 部署文件
└── README.md
三、核心功能模块封装建议
统一加载路由(支持路由自动注册)
// routes/index.js
const fs = require('fs');
module.exports = (app) => {
fs.readdirSync(__dirname).forEach(file => {
if (file !== 'index.js') {
const route = require(`./${file}`);
app.use(route.routes()).use(route.allowedMethods());
}
});
};
错误处理中间件封装
module.exports = async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = err.status || 500;
ctx.body = { message: err.message };
ctx.app.emit('error', err, ctx);
}
};
配置管理(自动加载 .env)
require('dotenv').config();
module.exports = {
port: process.env.PORT || 3000,
dbUri: process.env.DB_URI,
jwtSecret: process.env.JWT_SECRET,
};
四、构建初始化脚手架命令(可选)
如果你希望别人通过命令行初始化一个你的项目:
-
创建一个 bin/create-app.js
-
使用 inquirer 获取用户输入
-
使用 fs-extra 复制模板目录
-
发布到 npm,添加 bin 字段:
"bin": {
"create-myapp": "./bin/create-app.js"
}
五、TS 版本建议结构(可选)
-
使用 ts-node-dev 启动开发
-
tsconfig.json 配置 aliases、模块路径
-
每层模块写明 interface / type,配合 zod 做校验与推导
-
使用 path alias 简化引用:
"paths": {
"@controllers/*": ["./src/controllers/*"]
}
六、模板打包与发布方式
-
私用模板可直接 Git clone / zip 分享
-
可发布至 GitHub + 添加使用文档
-
可发布为 npm 包(用于 CLI 初始化)
推荐使用方式:
npx degit yourname/node-template my-new-app
总结
一套高质量的 Node.js 项目模板不只是“能用”,而是:
-
清晰(结构可读)
-
模块化(职责分层)
-
可维护(插件化设计)
-
可复制(快速落地)
“重复的工作自动化,复杂的结构标准化”,这才是真正工程师的打开方式。
1226

被折叠的 条评论
为什么被折叠?



