Express + TypeScript 后端通用标准规范

这是一套零业务耦合、企业级、生产就绪Express + TypeScript 后端通用标准规范 。这是国内互联网公司通用的后端骨架,任何项目都能直接用,包含:目录结构、代码分层、配置、中间件、错误处理、数据库、接口规范、部署脚本。


一、终极标准目录结构(核心)

复制代码
project-root/
├── .env                      # 本地环境变量(不上传Git)
├── .env.production           # 生产环境变量(不上传Git)
├── .env.example              # 环境变量示例(上传Git)
├── .gitignore                # Git忽略配置
├── package.json              # 依赖&脚本
├── tsconfig.json             # TypeScript 标准配置
├── prisma/                   # 数据库ORM(通用)
│   ├── schema.prisma
│   └── migrations/
└── src/                      # 源码根目录
    ├── config/               # 全局配置
    │   └── index.ts          # 环境/跨域/常量配置
    ├── middleware/           # 通用中间件
    │   ├── error.middleware.ts  # 全局错误处理
    │   ├── logger.middleware.ts # 请求日志
    │   └── validate.middleware.ts # 参数校验
    ├── utils/                # 工具函数
    │   └── response.ts       # 统一响应格式
    ├── types/                # TS类型定义
    │   └── index.ts
    ├── prisma/               # Prisma客户端单例(最佳实践)
    │   └── client.ts
    ├── routes/               # 路由层(只定义接口)
    │   ├── index.ts          # 路由总入口
    │   └── user.route.ts     # 模块路由示例
    ├── controllers/          # 控制器层(只处理请求/响应)
    │   └── user.controller.ts
    ├── services/             # 服务层(核心业务逻辑)
    │   └── user.service.ts
    └── index.ts              # 项目入口文件

二、核心配置文件(直接复制)

1. package.json 标准脚本

复制代码
{
  "name": "express-ts-standard",
  "scripts": {
    "dev": "nodemon src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js",
    "prisma:generate": "prisma generate",
    "prisma:migrate": "prisma migrate dev",
    "prisma:deploy": "prisma migrate deploy"
  },
  "dependencies": {
    "@prisma/client": "^5.0.0",
    "cors": "^2.8.5",
    "express": "^4.18.2",
    "express-validator": "^7.0.0",
    "dotenv": "^16.3.1"
  },
  "devDependencies": {
    "@types/cors": "^2.8.13",
    "@types/express": "^4.17.17",
    "@types/node": "^20.3.0",
    "nodemon": "^2.0.22",
    "prisma": "^5.0.0",
    "ts-node": "^10.9.1",
    "typescript": "^5.1.0"
  }
}

2. tsconfig.json 标准配置

复制代码
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

3. .env.example(Git 提交用)

复制代码
# 服务
PORT=3000
NODE_ENV=development

# 数据库
DATABASE_URL="postgresql://user:pass@localhost:5432/db"

三、代码分层规范(最重要!解耦、可维护)

分层规则(固定不变)

  1. 路由层 (routes):只定义接口地址、请求方法
  2. 控制器层 (controllers):只接收请求、返回响应
  3. 服务层 (services)所有业务逻辑、数据库操作都在这里
  4. 工具 / 中间件 / 配置:通用能力

四、标准代码文件(通用骨架)

1. 入口文件 src/index.ts

复制代码
import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import { errorMiddleware } from './middleware/error.middleware';
import routes from './routes';

// 加载环境变量
dotenv.config();
const app = express();

// 通用中间件
app.use(cors());
app.use(express.json());

// 路由
app.use('/api', routes);

// 全局错误处理(必须放在最后)
app.use(errorMiddleware);

// 启动服务
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`🚀 Server running on port ${PORT}`);
});

2. 统一响应工具 src/utils/response.ts

复制代码
import { Response } from 'express';

// 通用成功响应
export const success = <T>(res: Response, data: T, msg = '请求成功') => {
  return res.json({ code: 200, message: msg, data });
};

// 通用失败响应(给错误中间件用)
export class ApiError extends Error {
  constructor(public code: number, public message: string) {
    super(message);
  }
}

3. 全局错误中间件 src/middleware/error.middleware.ts

复制代码
import { Request, Response, NextFunction } from 'express';
import { ApiError } from '../utils/response';

export const errorMiddleware = (
  err: Error | ApiError,
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const code = err instanceof ApiError ? err.code : 500;
  const message = err.message || '服务器错误';
  
  res.status(code).json({ code, message, data: null });
};

4. Prisma 单例 src/prisma/client.ts

复制代码
import { PrismaClient } from '@prisma/client';

const globalForPrisma = globalThis as { prisma?: PrismaClient };

export const prisma = globalForPrisma.prisma || new PrismaClient();

if (process.env.NODE_ENV !== 'production') {
  globalForPrisma.prisma = prisma;
}

export default prisma;

5. 路由总入口 src/routes/index.ts

复制代码
import { Router } from 'express';
import userRoute from './user.route';

const router = Router();
router.use('/user', userRoute);

export default router;

6. 模块路由 src/routes/user.route.ts

复制代码
import { Router } from 'express';
import { getUserList, createUser } from '../controllers/user.controller';

const router = Router();
router.get('/', getUserList);
router.post('/', createUser);

export default router;

7. 控制器 src/controllers/user.controller.ts

复制代码
import { Request, Response } from 'express';
import { success } from '../utils/response';
import { userService } from '../services/user.service';

// 获取用户列表
export const getUserList = async (req: Request, res: Response) => {
  const data = await userService.getList();
  success(res, data);
};

// 创建用户
export const createUser = async (req: Request, res: Response) => {
  const data = await userService.create(req.body);
  success(res, data, '创建成功');
};

8. 服务层(业务 + 数据库)src/services/user.service.ts

复制代码
import prisma from '../prisma/client';
import { ApiError } from '../utils/response';

export const userService = {
  // 查询列表
  async getList() {
    return await prisma.user.findMany();
  },

  // 创建用户
  async create(body: any) {
    const { email } = body;
    const exists = await prisma.user.findUnique({ where: { email } });
    
    if (exists) throw new ApiError(400, '邮箱已存在');
    return await prisma.user.create({ data: body });
  }
};

五、Prisma 数据库标准流程(通用)

复制代码
# 1. 初始化
npx prisma init

# 2. 编写模型 schema.prisma

# 3. 生成客户端
npm run prisma:generate

# 4. 本地创建表
npm run prisma:migrate --name init

# 5. 生产部署(唯一命令)
npm run prisma:deploy

六、通用接口响应规范(所有项目统一)

复制代码
// 成功
{ "code": 200, "message": "请求成功", "data": [...] }

// 失败
{ "code": 400/401/403/500, "message": "错误信息", "data": null }

七、开发 / 生产规范

本地开发

复制代码
npm run dev

生产部署

复制代码
npm run build
npm run prisma:deploy
npm start

八、10 条黄金通用规则

  1. 永远分层:路由 → 控制器 → 服务 → 数据库
  2. 控制器无业务逻辑
  3. 服务层单例、纯逻辑、可测试
  4. 全局统一错误处理
  5. 统一响应格式
  6. Prisma 单例连接
  7. 环境变量不提交 Git
  8. 生产只用 prisma migrate deploy
  9. TS 严格模式开启
  10. 所有异步函数必须用 async/await + 错误捕获

总结

这是 Express + TS 后端的工业级标准规范

  • 目录固定
  • 分层清晰
  • 无业务耦合
  • 生产就绪
  • 任何后端项目都能直接套用
相关推荐
kyriewen2 小时前
你的数据该在哪儿拿?Next.js三种姿势一次讲清
前端·javascript·next.js
傻啦嘿哟2 小时前
管好PPT的“骨架”:用Python控制页面与文档属性
开发语言·javascript·c#
朝阳392 小时前
react【实战】搜索框(含联动动画,清空按钮)
前端·javascript·react.js
gCode Teacher 格码致知2 小时前
Javascript提高:一个彩色小球在画布边界内反弹并留下渐变轨迹-由Deepseek产生
开发语言·javascript
sinat_255487812 小时前
数组·学习笔记
java·javascript·笔记
涵涵(互关)3 小时前
语法大全-only-writer
开发语言·前端·vue.js·typescript
gCode Teacher 格码致知3 小时前
Javascript提高:国际化 API(Intl 对象)详解-由Deepseek产生
开发语言·javascript·ecmascript
靳向阳3 小时前
【无标题】
前端·javascript·vue.js
涵涵(互关)3 小时前
GoView各项目文件中的相关语法
前端·vue.js·typescript