Skip to content

NestJS 模板

基于 NestJS + TypeScript 的现代化后端开发模板,支持模块化架构、依赖注入、测试和完整的开发工具链。

技术栈

  • NestJS - 基于 Node.js 的企业级应用框架
  • TypeScript - JavaScript 的超集,提供类型安全
  • Express - 基于 Express 的 HTTP 服务器
  • Jest - JavaScript 测试框架
  • Docker - 容器化部署
  • MariaDB - 开源关系型数据库
  • Redis - 内存数据结构存储

快速开始

创建项目

bash
# 初始化项目
vup init my-project

# 进入项目目录
cd my-project

# 添加 NestJS 应用
vup add my-api
# 选择 NestJS 模板

开发

bash
# 安装依赖
pnpm install

# 启动开发服务器(监听文件变化)
pnpm dev:watch

开发服务器将在 http://localhost:9310 启动

构建

bash
# 构建生产版本
pnpm build

# 启动生产服务器
pnpm start:prod

项目结构

my-api/
├── src/
│   ├── app.controller.spec.ts     # 控制器测试
│   ├── app.controller.ts          # 应用控制器
│   ├── app.module.ts              # 应用模块
│   ├── app.service.ts             # 应用服务
│   └── main.ts                    # 应用入口
├── test/
│   ├── app.e2e-spec.ts            # 端到端测试
│   └── jest-e2e.json              # E2E 测试配置
├── docker-compose.yml             # Docker 编排文件
├── nest-cli.json                  # NestJS CLI 配置
├── package.json                   # 项目配置
├── tsconfig.json                  # TypeScript 配置
└── README.md                      # 项目说明

核心特性

🎯 TypeScript 支持

完整的 TypeScript 支持,提供类型安全和智能提示:

typescript
// 服务中使用 TypeScript
@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

🏗️ 模块化架构

基于 NestJS 的模块化架构:

typescript
// 创建新模块
@Module({
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}

💉 依赖注入

完整的 IoC 容器支持:

typescript
// 控制器中使用依赖注入
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

🛣️ 路由系统

基于装饰器的路由定义:

typescript
@Controller('users')
export class UsersController {
  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }
}

🛡️ 守卫和中间件

认证和授权支持:

typescript
// 创建守卫
@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return this.validateRequest(request);
  }
}

// 创建中间件
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log(`${req.method} ${req.path} - ${new Date().toISOString()}`);
    next();
  }
}

🔄 拦截器和管道

请求/响应拦截和数据验证:

typescript
// 创建拦截器
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');
    return next.handle();
  }
}

// 创建管道
@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // 数据验证逻辑
    return value;
  }
}

开发工具

代码质量

  • ESLint - 代码质量检查
  • Prettier - 代码格式化
  • TypeScript - 类型检查

开发命令

bash
# 开发服务器
pnpm dev:watch          # 监听文件变化
pnpm dev                # 普通开发模式
pnpm start:debug        # 调试模式

# 构建和部署
pnpm build              # 构建生产版本
pnpm start:prod         # 启动生产服务器

# 测试
pnpm test               # 运行单元测试
pnpm test:watch         # 监听模式运行测试
pnpm test:cov           # 生成测试覆盖率报告
pnpm test:e2e           # 运行端到端测试

# 代码质量
pnpm lint               # 代码检查
pnpm lint:fix           # 自动修复问题
pnpm format             # 代码格式化

热重载

NestJS 提供极速的热重载体验:

  • 修改 TypeScript 文件时自动重启
  • 保持应用状态
  • 快速编译和启动

测试支持

单元测试

typescript
// 服务测试
describe('AppService', () => {
  let service: AppService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [AppService],
    }).compile();

    service = module.get<AppService>(AppService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  it('should return "Hello World!"', () => {
    expect(service.getHello()).toBe('Hello World!');
  });
});

E2E 测试

typescript
// 端到端测试
describe('AppController (e2e)', () => {
  let app: INestApplication;

  beforeEach(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });

  it('/ (GET)', () => {
    return request(app.getHttpServer())
      .get('/')
      .expect(200)
      .expect('Hello World!');
  });
});

Docker 支持

开发环境

bash
# 启动数据库服务
pnpm docker:db

# 启动应用服务
pnpm docker:app

# 启动所有服务
pnpm docker:up

管理服务

bash
# 停止所有服务
pnpm docker:down

# 重新构建镜像
pnpm docker:build

# 查看服务日志
pnpm docker:logs

Docker Compose 配置

yaml
version: '3.8'

services:
  mariadb:
    image: mariadb:11.3
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
    ports:
      - '9306:3306'

  redis:
    image: redis:7.2-alpine
    ports:
      - '9379:6379'

最佳实践

模块设计

  • 按功能划分模块
  • 保持模块的单一职责
  • 合理使用依赖注入
  • 避免循环依赖

控制器设计

  • 保持控制器的简洁
  • 使用 DTO 进行数据验证
  • 合理使用装饰器
  • 处理异常情况

服务设计

  • 将业务逻辑封装在服务中
  • 使用接口定义服务契约
  • 保持服务的可测试性
  • 避免在服务中处理 HTTP 相关逻辑

测试策略

  • 编写单元测试覆盖核心逻辑
  • 使用 E2E 测试验证 API 接口
  • 保持测试的独立性和可重复性
  • 追求合理的测试覆盖率

部署

静态部署

bash
# 构建生产版本
pnpm build

# 启动生产服务器
pnpm start:prod

Docker 部署

dockerfile
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN pnpm install

COPY . .
RUN pnpm build

EXPOSE 9310

CMD ["pnpm", "start:prod"]

部署到 Vercel

NestJS 应用可以部署到 Vercel。详细的部署配置和步骤请参考 Vercel 部署指南

相关资源