Featured image of post Monorepo 管理与 Turborepo:扩展开发Featured image of post Monorepo 管理与 Turborepo:扩展开发

Monorepo 管理与 Turborepo:扩展开发

用于 monorepo 管理的 Turborepo 综合指南:缓存系统、任务编排、依赖关系图、远程缓存、管道配置和迁移策略。

介绍

随着 JavaScript monorepos 的增长,构建时间螺旋式上升,CI 管道饱和,开发人员生产力下降。由 Vercel 创建的 Turborepo 通过智能缓存和并行任务执行来解决这些挑战。与 Lerna 或 Nx 不同,Turborepo 专注于成为任务运行程序而不是构建工具,将编译委托给 esbuild、webpack 和 tsc 等工具。

核心架构——缓存系统

Turborepo 的缓存是它的决定性特征。缓存键是根据文件内容、环境变量和依赖关系图计算得出的。缓存以 tar.gz 存档形式存在于 node_modules/.cache/turbo 中,缓存命中/未命中生命周期决定任务是执行还是跳过。

{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"],
      "inputs": ["src/**/*.ts", "src/**/*.tsx"]
    }
  }
}

inputs 配置微调哪些文件影响缓存粒度。 Turborepo 使用内容哈希与 globalHash 进行根级别更改,并使用每任务 hash 进行各个任务。在提交配置更改之前,使用 --dry-run 验证缓存行为。


通过管道配置进行任务编排

turbo.json 管道配置是任务编排的核心。任务依赖、输出目录、环境变量和持久模式都在这里定义。

{
  "pipeline": {
    "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
    "test": { "dependsOn": ["build"] },
    "lint": { "dependsOn": [], "outputs": [] },
    "typecheck": { "dependsOn": ["^build"] }
  }
}

拓扑排序策略确保包的依赖关系先于包本身构建,而 linttypecheck 等独立任务并行运行。对于不应该缓存的任务使用 cache: false ,例如使用修复模式进行 linting。


远程缓存

远程缓存支持在团队成员和 CI 代理之间共享构建工件。 Vercel 的远程缓存、自托管 Turbo Server 和 S3 兼容后端均受支持。

特色Vercel 远程缓存自托管NX云
设置复杂性中等
成本免费套餐可用基础设施成本付费等级
数据控制Vercel 管理完全控制Nx 管理
授权团队代币定制集成代币

身份验证使用 TURBO_TOKENTURBO_TEAM 环境变量。基于环境的缓存命名空间可防止跨环境缓存污染。


依赖图优化

Turborepo 从 package.json 依赖项构造一个 DAG 并将其用于任务调度。 --filter 语法范围运行到特定的包及其依赖项,而 --graph 可视化依赖关系图。

turbo run build --filter=@acme/web...
turbo run build --graph --output=graph.html

减少跨包依赖性、一致地使用工作区协议以及对相关包进行分组都有助于加快构建速度。


迁移策略

从 Lerna 迁移涉及将 lerna run 替换为 turbo run、添加 turbo.json 以及保留现有的 npm 脚本。从 Nx,将 Nx 执行器转换为 turbo.json 中的 shell 命令。从自定义脚本中,识别并行化机会并将 shell 管道转换为 turbo.json 条目。拥有 50 个或更多包的团队在迁移后通常会发现 CI 时间减少了百分之六十到百分之八十。


结论

Turborepo 提供快速、正确且对开发人员友好的 monorepo 任务运行。对于使用 npm、pnpm 或 YARN 工作区且希望更快的 CI 而不采用完整构建系统的团队来说,Turborepo 是一个绝佳的选择。其开源特性、活跃的社区以及即将推出的基于守护进程的文件监视功能使其成为一项可靠的长期投资。