architecture, engineering,

一分钟读论文:《Monorepo:多声体文献综述》

Unbug By Unbug Follow Mar 11, 2023 · 1 min read
一分钟读论文:《Monorepo:多声体文献综述》
Share this

互联网大厂热衷于 Monorepo 的原因是什么,Monorepo 能否解决超级应用的代码管理通病?巴西米纳斯吉拉斯联邦大学和巴西拉夫拉斯联邦大学合著的论文《Monorepo: A Multivocal Literature Review》 论文通过对主要来源于20+灰色文献(如博客、演讲、视频等)的多声体文献综述,提供一个关于 Monorepo 的定义、特征、优势和挑战的概述。

  • Google:Google 的 Monorepo 包含了超过 20 亿行代码,超过 25 万个项目,超过 9 万名开发者。Google 使用自己开发的版本控制系统 Piper 和构建工具 Bazel 来管理 Monorepo 。
  • Facebook:Facebook 的 Monorepo 包含了超过 6.2 亿行代码,超过 6.5 万个项目,超过 1.2 万名开发者。Facebook 使用 Mercurial 和 Buck 来管理 Monorepo 。
  • Twitter:Twitter 的 Monorepo 包含了超过 3.5亿行代码,超过1.7万个项目,超过3千名开发者。Twitter 使用 Git 和 Pants 来管理 Monorepo 。
  • Microsoft:Microsoft 的 Monorepo 包含了 Windows 操作系统的所有代码,约为3亿行。Microsoft 使用自己开发的版本控制系统 GVFS 和构建工具 MSBuild 来管理 Monorepo 。

论文研究的问题和结论

RQ1: Monorepo 有哪些定义和特征?

3个定义:

  • 完全 Monorepo:指将所有代码(包括第三方库)都存放在一个版本控制系统中的实践。这种类型的 Monorepo 通常需要强大的工具支持和规范的流程来管理代码。例如,谷歌就使用了完全 Monorepo 。
  • 部分 Monorepo:指将所有自己开发的代码都存放在一个版本控制系统中,但是第三方库则存放在其他地方(如包管理器)的实践。这种类型的 Monorepo 相对于完全 Monorepo 来说,更容易迁移和集成。例如,Facebook就使用了部分 Monorepo 。
  • 混合 Monorepo:指将一些相关或相互依赖的代码存放在一个版本控制系统中,但是其他不相关或独立的代码则存放在其他地方(如多个版本控制系统)的实践。这种类型的 Monorepo 可以根据项目或团队的需求灵活地调整代码组织方式。例如,微软就使用了混合 Monorepo 。

6个主要特征:

  • 代码量:指 Monorepo 中存放的代码行数或文件数。一般来说, Monorepo 中有大量的代码,可能达到数百万行或数千个文件。
  • 模块化:指 Monorepo 中如何划分和组织不同功能或领域的代码。一般来说, Monorepo 采用层次化、树状或图状等结构来划分模块,并通过命名空间、目录、标签等方式来标识模块。
  • 工具支持:指用于管理和操作 Monorepo 中代码的软件工具。一般来说,由于 Monorepo 涉及到大量复杂且频繁变化的代码,因此需要高效且专业的工具支持,如版本控制系统、构建系统、测试系统、部署系统等。
  • 团队协作:指多个开发者如何在同一个 Monorepo 中共享和修改代码的方式。一般来说, Monorepo 需要有明确且统一的协作规范,如分支策略、提交规则、审查流程等,以避免冲突和错误。
  • 版本管理:指如何为 Monorepo 中不同模块或产品定义和维护版本号或标签的方法。一般来说, Monorepo 可以采用统一版本号(即所有模块或产品共享同一个版本号)或者独立版本号(即每个模块或产品有自己的版本号)。统一版本号可以简化依赖管理和部署流程,但是可能导致不必要的更新和测试。独立版本号可以提高灵活性和可追溯性,但是可能增加复杂度和不一致性。
  • 部署方式:指如何将 Monorepo 中的代码打包和发布到目标平台或环境的方法。一般来说, Monorepo 可以采用单一部署(即将所有代码打包成一个可执行文件或容器)或者多元部署(即将不同模块或产品分别打包成多个可执行文件或容器)。单一部署可以保证代码的完整性和一致性,但是可能影响性能和扩展性。多元部署可以提高效率和灵活性,但是可能引入依赖问题和兼容问题。

RQ2: Monorepo 有哪些优势?

  • 简化依赖管理指由于 Monorepo 中所有代码都在一个地方,因此可以避免跨项目、跨团队、跨平台等不同层面上的依赖问题。例如,开发者可以轻松地查看、修改、测试、重构任何代码而无需担心破坏其他项目或组件;构建系统可以自动地解析、更新、验证所有依赖而无需额外的配置或工具;部署系统可以快速地发布所有代码而无需考虑版本匹配或兼容性。
  • 促进代码重用指由于 Monorepo 中所有代码都在一个地方,因此可以方便地实现、发现、共享、复用各种功能或领域的代码。例如,开发者可以直接调用已有的函数、类、模块等而无需重新编写或导入;构建系统可以利用缓存或增量编译来加速构建过程;部署系统可以利用镜像或差异打包来减少部署大小
  • 支持大规模协作指由于 Monorepo 中所有代码都在一个地方,因此可以方便地实现、监控、协调多个开发者、团队、项目之间的协作。例如,开发者可以轻松地查看、评审、合并其他开发者的代码而无需切换或同步不同的版本控制系统;构建系统可以自动地触发、执行、报告所有相关的测试和分析而无需人工干预或通知;部署系统可以统一地管理、发布、回滚所有相关的产品或服务而无需额外的协商或协议。
  • 提高代码质量指由于 Monorepo 中所有代码都在一个地方,因此可以有效地保证、提高代码的可读性、可维护性、可测试性等质量属性。例如,开发者可以遵循统一的编码规范和风格而无需适应不同的项目或团队;构建系统可以强制执行统一的质量标准和检查而无需配置不同的工具或插件;部署系统可以确保统一的安全性和稳定性而无需考虑不同的平台或环境。

RQ3: Monorepo 有哪些挑战?

  • 管理复杂度指由于 Monorepo 中存放了大量且多样化的代码,因此需要面对各种复杂且难以解决的管理问题。例如,开发者需要处理频繁且庞大的变更集合,并及时解决可能出现的冲突和错误;构建系统需要处理长时间且消耗资源的构建任务,并优化构建速度和效率;部署系统需要处理多种且不兼容的部署平台和环境,并保证部署正确性和安全性。
  • 适应变化指由于 Monorepo 中涉及了多个开发者、团队、项目、产品等,因此需要不断地适应各种内部和外部的变化需求。例如,开发者需要跟进新的技术或工具的引入或更新,并及时调整自己的代码或工作流程;构建系统需要支持新的功能或领域的添加或删除,并及时更新构建规则或策略;部署系统需要应对新的市场或用户的需求或反馈,并及时修改部署计划或方案。

RQ4: Monorepo 与其他软件开发实践之间有哪些关系?

  • 使用虚拟文件系统:指通过使用一种特殊的文件系统,可以将 Monorepo 中的所有文件都映射到开发者的本地机器上,但只有当开发者访问或修改某个文件时,才会真正地下载或上传该文件。这样可以减少网络传输和存储空间的开销,同时保证开发者能够随时访问或修改 Monorepo 中的任何文件。
  • 使用增量构建:指通过使用一种特殊的构建系统,可以根据 Monorepo 中的变更集合,只构建和测试受影响的代码部分,而不是整个 Monorepo 。这样可以减少构建时间和资源消耗,同时保证构建结果的正确性和完整性。
  • 使用模块化设计:指通过使用一种特殊的设计方法,可以将 Monorepo 中的代码按照功能、领域、层次等划分为多个模块,并定义好模块之间的依赖关系和接口规范。这样可以提高代码的可读性、可维护性、可复用性等质量属性,同时降低代码之间的耦合度和冲突概率。

延伸阅读:论文《大企业的 Monorepo 和 polyrepo 问题》的发现:

  • 下载仓库的时间过长由于 Monorepo 包含了所有项目和服务的代码,它们的体积往往非常庞大,这就导致下载或克隆仓库的时间非常长,给开发者带来不便。
  • 搜索或查找文件的速度慢由于 Monorepo 包含了数以百万计的源文件,使用普通的工具或方法来搜索或查找文件会非常慢和沮丧,需要使用特殊的索引或缓存技术来提高效率。
  • 缺乏良好的代码模块化由于 Monorepo 让所有项目和服务共享同一个代码空间,这就降低了对代码模块化和封装性的要求,可能导致代码结构混乱、耦合度高、可维护性低等问题。
  • 依赖关系管理困难由于 Monorepo 让所有项目和服务共享同一个依赖树,这就增加了对依赖关系管理的复杂度和风险,可能出现版本冲突、循环依赖、更新延迟等问题。
  • 构建过程难以协调由于 Monorepo 涉及到大量不同类型、不同平台、不同技术栈的项目和服务,这就需要使用统一而灵活的工具和方法来协调构建过程,同时考虑性能、安全、可扩展性等因素。
  • 测试周期变得复杂由于 Monorepo 中修改一个公共代码可能影响到多个应用组件,这就需要进行更多更细致的测试工作,同时也要处理源码冲突合并等问题。
  • 维护成本高由于 Monorepo 包含了大量不同类型、不同平台、不同技术栈的项目和服务,它们需要使用特殊的工具和方法来管理版本控制、构建、测试、部署等过程,这些工具和方法往往需要自己开发或改造,而且随着Monorepo 的增长,它们也需要不断地优化和更新,这就增加了 Monorepo 的维护成本。
  • 迁移难度大由于 Monorepo 依赖于特殊的工具和方法,如果想要从 Monorepo 迁移到多仓库或者其他版本控制系统,就需要进行大量的重构和适配工作,这就增加了 Monorepo 的迁移难度。
  • 安全风险高由于 Monorepo 让所有项目和服务共享同一个代码空间,如果有人恶意修改或删除一些关键代码或数据,可能会影响到整个系统的稳定性和安全性。因此, Monorepo 需要有严格的权限控制和审计机制来保证代码质量和安全性。

Releated