Skip to content

Nest 快速入门 ​

(前置) 安装 ​

  • 使用管理员身份运行
bash

npm i -g @nestjs/cli
  • 创建项目
bash

nest new basic_1

一、项目定位 ​

本项目是 NestJS 官方的 TypeScript 起步模板(starter repository),由 nest new 命令生成的标准骨架。它本身只实现了一个功能:

启动一个 HTTP 服务器,访问 GET / 时返回字符串 Hello World!

功能虽少,但它完整包含了 Nest 应用的所有核心要素——模块(Module)、控制器(Controller)、服务(Service/Provider)、依赖注入(DI)、单元测试、端到端测试、工程化配置。把这套骨架吃透,后续再学数据库、鉴权、微服务等复杂内容,都只是在这套骨架上"挂肉"。

二、目录结构 ​

basic_1/
├── src/                          # 业务源码
│   ├── main.ts                   # 应用入口:创建并启动 Nest 应用
│   ├── app.module.ts             # 根模块:组装控制器、服务、子模块
│   ├── app.controller.ts         # 根控制器:定义 GET / 路由
│   ├── app.service.ts            # 根服务:提供 getHello() 业务逻辑
│   └── app.controller.spec.ts    # 控制器的单元测试
├── test/
│   └── app.e2e-spec.ts           # 端到端测试:真实发起 HTTP 请求
├── package.json                  # 依赖清单与 npm scripts
├── tsconfig.json                 # TS 编译配置(装饰器、ESM、严格模式)
├── tsconfig.build.json           # 生产构建专用的 TS 配置(排除测试)
├── nest-cli.json                 # Nest CLI 配置
├── vitest.config.ts              # 单元测试配置(匹配 *.spec.ts)
├── vitest.config.e2e.ts          # e2e 测试配置(匹配 *.e2e-spec.ts)
├── .prettierrc                   # Prettier 格式化规则
├── .oxlintrc.json                # oxlint 检查规则
├── .gitignore                    # Git 忽略规则
└── README.md                     # 官方说明文档

文件命名约定(Nest 社区通行规范) ​

  • *.module.ts:模块定义
  • *.controller.ts:控制器(处理 HTTP 入口)
  • *.service.ts:服务(业务逻辑)
  • *.spec.ts:单元测试(与被测文件放在同一目录)
  • *.e2e-spec.ts:端到端测试(集中放在 test/ 目录)

三、核心模块之间的关系 ​

本项目只有三个"业务角色",但它们的协作方式就是 Nest 一切应用的缩影:

        ┌─────────────────── AppModule(根模块)───────────────────┐
        │                                                          │
        │   controllers: [AppController]   providers: [AppService] │
        │   imports:     [ObserveModule]                           │
        │                                                          │
        │      AppController ──构造注入──> AppService               │
        │      (接收请求,定义路由)      (实现业务逻辑)          │
        └──────────────────────────────────────────────────────────┘
                            ▲
                            │ NestFactory.create(AppModule)
                        main.ts(入口,启动 HTTP 服务,监听 3000 端口)
  • main.ts:唯一的"主动执行"文件,负责把 AppModule 交给框架,启动服务器。
  • AppModule:应用的"装配图",告诉 Nest 有哪些控制器、哪些服务、引入哪些功能模块。
  • AppController:只关心 HTTP 层——什么路径、什么方法、返回什么;不写业务逻辑。
  • AppService:只关心业务逻辑——这里逻辑只有一行 return 'Hello World!'。
  • ObserveModule:第三方功能模块,挂载后自动收集链路追踪和运行时指标。

四、一次请求的完整生命周期 ​

当你在浏览器访问 http://localhost:3000/:

浏览器 GET /
   │
   ▼
Express(platform-express 适配器)收到请求
   │
   ▼
Nest 路由匹配:路径 "/" + 方法 GET ──找到──> AppController.getHello()
   │                                            (由 @Get() 装饰器注册)
   ▼
getHello() 内部调用 this.appService.getHello()
   │                                            (appService 由 DI 容器注入)
   ▼
AppService.getHello() 返回 "Hello World!"
   │
   ▼
Nest 将返回值序列化,Express 发回响应:200 OK, body = "Hello World!"

五、代码讲解:package.json 的 scripts ​

json
"scripts": {
  "build": "nest build",
  "deploy": "nest deploy",
  "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
  "start": "nest start",
  "start:dev": "nest start --watch",
  "start:debug": "nest start --debug --watch",
  "start:prod": "node dist/main",
  "lint": "oxlint src/ test/",
  "test": "vitest run",
  "test:watch": "vitest",
  "test:cov": "vitest run --coverage",
  "test:debug": "vitest --inspect-brk --no-file-parallelism",
  "test:e2e": "vitest run --config ./vitest.config.e2e.ts"
}

逐条解释:

命令作用什么时候用
npm run start编译并启动一次快速验证能否运行
npm run start:devwatch 模式:改代码自动重新编译重启日常开发主力命令
npm run start:debugwatch + 开启调试端口,可接 VS Code 断点排查疑难问题
npm run build只编译到 dist/,不启动准备部署产物
npm run start:prod直接运行编译产物 dist/main.js生产环境
npm run test跑一遍全部单元测试后退出CI / 提交前检查
npm run test:watch测试 watch 模式,改代码自动重跑写测试时
npm run test:cov测试 + V8 覆盖率报告检查测试覆盖情况
npm run test:e2e用 e2e 专用配置跑端到端测试验证接口真实行为
npm run lintoxlint 静态检查提交前
npm run formatPrettier 批量格式化提交前
npm run deploy调用 @nestjs/mau 部署到 AWS上线时(第 9 章展开)

六、关键概念:ESM 与 "type": "module" ​

package.json 第 7 行:

json
"type": "module"

这决定了 Node 把 .js 文件当作 ES Module(import/export)而不是 CommonJS(require/module.exports)加载。它带来三个连锁反应,后面章节会反复遇到:

  1. TS 编译配置必须用 "module": "nodenext"(见第 8 章);
  2. 源码里的相对导入必须带 .js 后缀,如 import { AppModule } from './app.module.js'——即使源文件是 .ts;
  3. 顶层可以直接写 await(main.ts 正是这么做的)。

七 运行 ​

bash

npm run start:dev
  • 访问
bash
http://localhost:3000/