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. 严格依赖隔离 —— 事务模块中 @nestjs/typeorm 与 typeorm 版本必须精确匹配,pnpm 的符号链接结构能防止意外提升。
2. 锁文件冲突少 —— pnpm-lock.yaml 的合并冲突比 yarn.lock 更容易手动解决。
3. 磁盘效率高 —— 多个 NestJS 微服务项目可共享全局存储,节省 CI 缓存空间。

2.4 环境配置决策流程

以下 SVG 图展示了从版本选型到包管理器落地的完整决策路径,帮助你在新项目中快速建立一致的环境基线:

环境配置决策流程 环境配置决策流程 开始环境配置 选择 Node.js 版本 Node.js 18 LTS Node.js 20 LTS 配置 TypeScript 严格模式 选择包管理器 pnpm(推荐) yarn berry npm 说明: 事务边界治理项目优先选择 pnpm + Node.js 18/20 LTS + TypeScript strict:true。 yarn berry 的 PnP 模式适合 Docker 镜像瘦身,但需额外配置 @nestjs/cli 兼容性。

2.5 初始化命令速查

完成决策后,按以下顺序执行环境初始化:

  1. 确认 Node.js 版本: node -v 应输出 v18.20.4 或 v20.12.2
  2. 安装 pnpm: npm install -g pnpm@9.15.4
  3. 创建 NestJS 项目: pnpm dlx @nestjs/cli new transaction-demo --package-manager pnpm --strict
  4. 验证 TypeScript 配置: 检查 tsconfig.json 中 strict: true 已生效
  5. 安装事务相关依赖: pnpm add @nestjs/typeorm typeorm pg reflect-metadata
验证清单:
  • pnpm ls -r --depth=0 — 确认依赖树无重复版本
  • npx tsc --noEmit — 确认严格模式编译通过
  • pnpm audit — 确认无高危漏洞