monorepo重拾Cloudprg2024/07/28 07:30:16阅读3分钟

前言

在了解monorepo之前,先问自己几个问题:

  1. monorepo解决了什么问题?
  2. 在monorepo之前是如何管理多个项目的?
  3. 如果要作项目迁移,如何转化为monorepo架构?
  4. 市面上有哪些monorepo框架?

概念

一种管理多个项目到同个仓库中的软件开发策略。意为在将多个项目统一集合在一个仓库中进行管理。

monorepo优化了什么部分?

  • 代码复用易提取:如多个子项目中拥有共需的组件或工具,则可以提取出来专门做一个lib来提供。
  • 本地依赖易于引用&调试: 只需要在子包本地的打包配置中设置alias ,及path.resolve依赖 路径,就能引用&便于调试。
  • 统一代码规范配置:比如ts.config都可以继承或引用包目录中的
  • 依赖库提升全局: 像learna nx支持将子包的依赖都提升至顶层。

monorepo有哪些坑?

  • 幽灵依赖:npm/yarn 子包直接引用顶层依赖,并且自身package.json没有注明该依赖使用。导致后期相关的顶层依赖移除后,使用报错。(pnpm解决了这个问题)
  • 安装耗时长:随着项目的迭代扩展,多个子包依赖增长,新项目install地时间会逐渐增长; 方案上考虑将相同依赖提升到顶部安装。
  • 构建耗时长: 多个项目构建往往是串行|全量构建;方案上考虑改为增量构建或并行构建。

turborepo/lerna/nx

市面上的monorepo框架,例如 lerna/nx 提供了这样的能力(具体不展开)。 构建顺序: 假设目前有p1,p2两个子包,依赖于lib依赖。构建上流程是:

  1. p1 p2 lib执行软连接(link)
  2. lib ->p1 ->p2 串行构建(build)
  3. lib p1 p2 串行测试(test) 上述框架将会优化构建流程。

框架构建优化思路

  • 并行构建(all): 自动分析关联关系,并以优先级排序以最大化并行性能(p1 p2 lib会同时 link test ;lib优先构建 ,随后p1 p2并行构建)
  • 增量构建(nx): 只构建改动部分
  • 分布式构建(nx): 多个任务自动分布在CI代理中(由多个远程构建机器)
  • 本地&远程缓存(nx): 构建的内容将被缓存在本地(比如 node_modules/.cache/turbo/),也可以考虑 CI/CD或团队共享打包缓存,推送至云端,构建时拉取。

如何缓存构建内容的

  • 检测依赖hash值:会检测上次构建依赖是否有文件发生变化,如果没有变化,将使用缓存的构建结果。
  • 依赖图:维护了一个依赖图,知道项目之间的依赖关系,如果依赖不变,则也可以使用缓存的构建结果。

如何实现子包依赖提升至顶层的?

先在每个子项目运行 npm install,等所有依赖都安装好后,将他们移动到顶层的 node_modules。 那存在不同版本的相同依赖怎么办? 取常用版本的那个,并抛出警告。 那如果部分子包的依赖执行了旧版api怎么办?

  • 修改 package.json中的workspaces , 指定packages/*
  • learna/nx 修改包管理客户端(npmClient) ,以及启用 workplaces
{ "npmClient": "yarn", "useWorkspaces": true }

总结

  • monorepo解决了 多仓库难以管理 问题,包括 规范配置、git代码提交、依赖重复安装、本地依赖调试困难、代码复用性差等问题
  • 一般pnpm monorepo够用,如果项目逐渐扩大,可以考虑 lerna+ pnpm workspace平滑过渡,不过目前nx已经接替了lerna的更新。
  • 市面上的 lerna / nx / turborepo/ Rush 都可以考虑使用,看开发需求

参考

标签:
评论(0)
暂无评论
暂无评论
留言板