以下是一份详细的Node.js服务端项目开发文档,使用ESM模块系统和TypeScript,涵盖项目初始化、核心架构、安全配置到部署的全流程:
Node.js 服务端项目开发文档
技术栈:Node.js 18+ | TypeScript | Express | Mongoose | ESM
🚀 项目初始化
1. 创建项目结构
mkdir my-node-api
cd my-node-api
npm init -y
2. 安装基础依赖
# 核心依赖
npm install express dotenv cors mongoose helmet morgan
# 开发依赖(TypeScript 支持)
npm install --save-dev typescript @types/node @types/express ts-node @types/cors
3. 启用 ESM 支持
在 package.json 中添加:
{
"type": "module",
"scripts": {
"dev": "ts-node --esm src/index.ts"
}
}
📁 项目目录结构
my-node-api/
├── src/
│ ├── controllers/ # 路由处理逻辑
│ ├── models/ # 数据库模型
│ ├── routes/ # 路由定义
│ ├── services/ # 业务逻辑
│ ├── utils/ # 工具函数
│ ├── config/ # 配置文件
│ ├── middleware/ # 中间件
│ └── index.ts # 入口文件
├── .env # 环境变量
├── tsconfig.json # TypeScript 配置
├── package.json
└── README.md
🛠️ 配置文件
1. tsconfig.json(TypeScript 配置)
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext", // 启用 ESM
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
"sourceMap": true
},
"include": ["src/**/*"]
}
2. .env(环境变量)
PORT=3000
MONGODB_URI=mongodb://localhost:27017/mydb
JWT_SECRET=your_secure_key
📡 服务端核心代码
1. src/index.ts(入口文件)
import express from 'express';
import dotenv from 'dotenv';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import { connectDB } from './config/db.js';
import routes from './routes/index.js';
dotenv.config();
connectDB();
const app = express();
// 中间件
app.use(cors());
app.use(helmet());
app.use(morgan('dev'));
app.use(express.json());
// 路由
app.use('/api', routes);
// 错误处理中间件
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal Server Error' });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
🧩 数据库连接(Mongoose)
src/config/db.ts
import mongoose from 'mongoose';
export const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGODB_URI!);
console.log('MongoDB connected');
} catch (err) {
console.error('MongoDB connection error:', err);
process.exit(1);
}
};
🌐 路由设计
1. src/routes/index.ts(路由聚合)
import express from 'express';
import userRoutes from './user.routes.js';
const router = express.Router();
router.use('/users', userRoutes);
export default router;
2. src/routes/user.routes.ts
import { Router } from 'express';
import { getUsers, createUser } from '../controllers/user.controller.js';
const router = Router();
router.get('/', getUsers);
router.post('/', createUser);
export default router;
📚 控制器示例
src/controllers/user.controller.ts
import { Request, Response } from 'express';
import UserModel from '../models/User.model.js';
export const getUsers = async (req: Request, res: Response) => {
const users = await UserModel.find();
res.json(users);
};
export const createUser = async (req: Request, res: Response) => {
const user = new UserModel(req.body);
await user.save();
res.status(201).json(user);
};
🔐 安全配置
1. JWT 鉴权中间件
// src/middleware/auth.ts
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
export const authenticate = (req: Request, res: Response, next: NextFunction) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Access denied' });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!);
req.user = decoded;
next();
} catch (err) {
res.status(400).json({ error: 'Invalid token' });
}
};
🧪 测试与调试
1. 测试用例(Jest + Supertest)
// __tests__/user.test.ts
import request from 'supertest';
import app from '../src/index.js';
describe('GET /api/users', () => {
it('responds with JSON', async () => {
const res = await request(app).get('/api/users');
expect(res.statusCode).toBe(200);
expect(res.header['content-type']).toMatch(/json/);
});
});
🛡️ 错误处理
1. 自定义错误类
// src/utils/HttpError.ts
export class HttpError extends Error {
constructor(public status: number, message: string) {
super(message);
this.name = 'HttpError';
}
}
2. 全局错误捕获
// src/index.ts
app.use((err: HttpError, req: Request, res: Response, next: NextFunction) => {
res.status(err.status || 500).json({ error: err.message });
});
📦 构建与部署
1. 编译 TypeScript
npx tsc
2. 生产环境启动
NODE_ENV=production node dist/index.js
3. PM2 进程管理
pm2 start dist/index.js --name "my-api"
🚢 Docker 部署
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "dist/index.js"]
📋 开发规范
1. ESLint + Prettier
// .eslintrc.json
{
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"rules": {
"semi": ["error", "never"]
}
}
此文档覆盖了从零搭建到生产部署的全流程,强调模块化设计和最佳实践,可直接用于团队协作参考。
Node.js后端项目完整搭建指南
655

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



