2. 环境准备:Node.js 与 npm 版本选择、TypeScript 严格模式配置、pnpm/yarn 包管理器对比
事务边界治理对运行时环境的一致性要求极高。Node.js 的 LTS 版本、npm 的锁定机制、TypeScript 的严格类型检查以及包管理器的依赖解析策略,任何一个环节的偏差都可能导致事务回滚异常或连接池泄漏。本节从版本选型、类型安全、依赖管理三个维度搭建可复现的基准环境。
2.1 Node.js 与 npm 版本选择策略
NestJS 官方要求 Node.js ≥ 16,但结合事务场景下的 async_hooks 稳定性与 --experimental-vm-modules 支持,推荐使用 Node.js 18 LTS 或 20 LTS。npm 版本随 Node.js 捆绑,但需额外关注 package-lock.json 的 v2/v3 格式差异。
| Node.js 版本 | npm 捆绑版本 | 事务相关特性 | 推荐场景 |
|---|---|---|---|
| 18 LTS (18.20.x) | 10.x | async_hooks 稳定,--experimental-loader 支持 ESM |
生产环境首选,兼容 NestJS 10.x |
| 20 LTS (20.12.x) | 10.x | 内置 node:test,V8 引擎优化 |
新项目推荐,支持 TypeScript 5.x |
| 22 (当前) | 11.x | 实验性 --experimental-strip-types |
仅用于尝鲜,不建议事务生产环境 |
版本锁定建议: 在项目根目录创建
.nvmrc 文件,内容写入 18.20.4 或 20.12.2,配合 nvm use 确保团队环境一致。npm 版本通过 npm install -g npm@10.8.2 固定。
2.2 TypeScript 严格模式配置
事务边界治理依赖精确的类型推断——@Transactional() 装饰器的返回值类型、EntityManager 的泛型参数、QueryRunner 的链接状态,都需要 TypeScript 严格模式来捕获潜在的类型泄漏。以下配置直接作用于 tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
关键开关解读:
strictNullChecks— 防止EntityManager返回null时未处理,导致事务内空指针。strictPropertyInitialization— 强制实体类所有属性在构造函数中赋值,避免事务回滚后部分字段为undefined。exactOptionalPropertyTypes— 区分undefined与未定义,对@Optional()装饰器参数校验至关重要。noUnusedParameters— 事务拦截器中未使用的@ExecutionContext参数会被标记,减少运行时隐式依赖。
常见陷阱: 如果项目中使用了
@nestjs/typeorm 或 @nestjs/mongoose,请确保 strictPropertyInitialization 与 ORM 实体类的 @Column({ nullable: true }) 配合正确。否则编译时会报“属性没有初始化”错误,需要显式使用 ! 非空断言或构造函数赋值。
2.3 pnpm / yarn 包管理器对比
在事务边界治理场景中,依赖安装速度、node_modules 结构、锁文件冲突解决能力直接影响 CI/CD 流水线的稳定性。以下从五个维度对比主流包管理器:
| 对比维度 | pnpm (v9.x) | yarn (v4.x / berry) | npm (v10.x) |
|---|---|---|---|
| 依赖存储方式 | 内容寻址存储 + 硬链接 | 扁平化 node_modules + PnP 模式 |
扁平化 node_modules |
| 锁文件 | pnpm-lock.yaml |
yarn.lock |
package-lock.json |
| 安装速度 | 极快(缓存命中率 > 90%) | 快(零安装模式更快) | 中等 |
| 事务场景优势 | 严格隔离依赖,避免幽灵依赖 | PnP 模式减少 I/O,适合 Docker 构建 | 生态最广,兼容性最好 |
| CI/CD 磁盘占用 | 低(全局存储复用) | 中(PnP 模式极低) | 高(重复安装) |
推荐选择: 本课程所有示例基于 pnpm。原因在于:
1. 严格依赖隔离 —— 事务模块中
2. 锁文件冲突少 ——
3. 磁盘效率高 —— 多个 NestJS 微服务项目可共享全局存储,节省 CI 缓存空间。
1. 严格依赖隔离 —— 事务模块中
@nestjs/typeorm 与 typeorm 版本必须精确匹配,pnpm 的符号链接结构能防止意外提升。2. 锁文件冲突少 ——
pnpm-lock.yaml 的合并冲突比 yarn.lock 更容易手动解决。3. 磁盘效率高 —— 多个 NestJS 微服务项目可共享全局存储,节省 CI 缓存空间。
2.4 环境配置决策流程
以下 SVG 图展示了从版本选型到包管理器落地的完整决策路径,帮助你在新项目中快速建立一致的环境基线:
2.5 初始化命令速查
完成决策后,按以下顺序执行环境初始化:
- 确认 Node.js 版本:
node -v应输出v18.20.4或v20.12.2 - 安装 pnpm:
npm install -g pnpm@9.15.4 - 创建 NestJS 项目:
pnpm dlx @nestjs/cli new transaction-demo --package-manager pnpm --strict - 验证 TypeScript 配置: 检查
tsconfig.json中strict: true已生效 - 安装事务相关依赖:
pnpm add @nestjs/typeorm typeorm pg reflect-metadata
验证清单:
pnpm ls -r --depth=0— 确认依赖树无重复版本npx tsc --noEmit— 确认严格模式编译通过pnpm audit— 确认无高危漏洞