rn+expo+mysql+nodejs 从零实战开发上架APP(3)nodejs环境搭建

Node.js后端项目完整搭建指南

以下是一份详细的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"]
  }
}


此文档覆盖了从零搭建到生产部署的全流程,强调模块化设计和最佳实践,可直接用于团队协作参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值