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:dev | watch 模式:改代码自动重新编译重启 | 日常开发主力命令 |
npm run start:debug | watch + 开启调试端口,可接 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 lint | oxlint 静态检查 | 提交前 |
npm run format | Prettier 批量格式化 | 提交前 |
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)加载。它带来三个连锁反应,后面章节会反复遇到:
- TS 编译配置必须用
"module": "nodenext"(见第 8 章); - 源码里的相对导入必须带
.js后缀,如import { AppModule } from './app.module.js'——即使源文件是.ts; - 顶层可以直接写
await(main.ts正是这么做的)。
七 运行
bash
npm run start:dev- 访问
bash
http://localhost:3000/