前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Monorepo 还没搞懂吗?一文搞定!

Monorepo 还没搞懂吗?一文搞定!

作者头像
前端修罗场
发布2022-07-29 08:03:48
3.4K0
发布2022-07-29 08:03:48
举报
文章被收录于专栏:Web 技术

monorepo 是什么

monorepo 是一个版本控制的代码存储库,包含许多项目。虽然这些项目可能是相关的,但它们在逻辑上通常是独立的,并由不同的团队运行。

有些公司将所有代码放在一个存储库中,供所有人共享。Monorepos 可以达到巨大的尺寸。例如,谷歌理论上拥有有史以来最大的代码存储库,每天有数十个提交,超过80 tb。其他使用 Monorepos 的公司还有微软、Facebook和Twitter。

Monorepos有时被称为单块存储库,但它们不应该与单块体系结构混淆,后者是用于编写自包含应用程序的软件开发实践。这方面的一个例子是处理网站、API端点和后台作业的 Ruby on Rails monolith

Monorepos vs. multirepos

monorepo相反的是multirepo,其中每个项目都保存在一个完全独立的、版本控制的存储库中。multirepo——是我们大多数人在开始一个新项目时所做的。

multimonorepo 就是将所有的项目移动到一个存储库中。

当然,这只是开始。当我们开始重构和整合时,困难就来了。

代码语言:javascript
复制
$ mkdir monorepo
$ git init
$ mv ~/src/app-android10 ~/src/app-android11 ~/src/app-ios .
$ git add -A
$ git commit -m "My first monorepo"

Multirepos 不是微服务的同义词;一个不需要另一个。事实上,我们稍后将讨论将monorepos和微服务相结合的公司。一个monorepo可以托管任意数量的微服务,只要您仔细地设置了用于部署的持续集成和交付(CI/CD)管道

爱上 Monorepos

乍一看,在monoreposmultirepos之间的选择似乎不是什么大问题,但这是一个决定,将深刻影响您的公司的开发工作流程。至于它们的好处,我们可以列举一些:

  • 可见性:每个人都可以看到其他人的代码。这个属性可以带来更好的协作和跨团队贡献——不同团队的开发人员可以修复你代码中的错误,而你甚至不知道它的存在。
  • 更简单的依赖项管理:共享依赖项很简单。几乎不需要包管理器,因为所有模块都托管在同一个存储库中。
  • 单一来源的真理:每个依赖的一个版本意味着不存在版本冲突和依赖地狱。
  • 一致性:当您将所有代码库放在一个地方时,执行代码质量标准和统一风格会更容易。
  • 共享时间线:api或共享库中的破坏性更改会立即暴露出来,迫使不同的团队提前沟通并联合起来。每个人都在努力跟上变化。
  • 原子提交:原子提交使大规模重构更容易。开发人员可以在一次提交中更新多个包或项目。
  • 隐式CI:由于所有代码已经统一在一个地方,因此可以保证持续集成。
  • 统一CI/CD:您可以对回购协议中的每个项目使用相同的CI/CD部署流程。
  • 统一构建流程:我们可以为回购协议中的每个应用程序使用共享的构建流程。

Monorepos 也有讨厌的一面

随着monorepos的增长,我们在版本控制工具、构建系统和持续集成管道方面达到了设计极限。这些问题会让公司走multirepo路线:

  • 性能差:monorepos很难扩展。像git blame这样的命令可能会花费不合理的长时间,ide开始滞后,生产力受到影响,并且在每次提交上测试整个回购变得不可行。
  • 坏掉的主机:坏掉的主机会影响在monorepo工作的每个人。这可以看作是灾难性的,也可以看作是保持测试整洁和更新的良好动机。
  • 学习曲线:如果存储库跨越许多紧密耦合的项目,那么新开发人员的学习曲线会更陡峭。
  • 大量的数据:monorepos每天都可以提交大量的数据。
  • 所有权:维护文件的所有权更具挑战性,因为Git或Mercurial等系统没有内置的目录权限。
  • 代码审查:通知可能变得非常嘈杂。例如,GitHub的通知设置有限,不适合拉取请求和代码审查的雪崩。

您可能已经注意到,大多数这些问题都是技术性的。在接下来的部分中,我们将了解那些坚持使用monorepos的公司是如何通过投资工具、添加集成和编写自定义解决方案来解决大多数问题的。

这不仅仅与技术有关

选择存储库策略不仅是一个技术问题,而且涉及到人们如何交流。正如康威定律所言,沟通对于打造伟大的产品至关重要:

任何设计系统的组织所产生的设计,其结构是该组织通信结构的复制品。 -梅尔文·e·康威

虽然multirepo允许每个团队独立管理他们的项目,但他们也设置了协作障碍。通过这种方式,他们可以充当眼罩,使开发人员只关注他们所拥有的部分,而忘记了整体情况。

另一方面,monorepo就像一个中心枢纽,一个市场广场,每个开发人员、工程师、测试人员和业务分析师都可以在这里会面和交谈。Monorepos鼓励对话,帮助我们消除隔阂。

Monorepo 文化

Monorepo 已经存在很长时间了。三十年来,FreeBSD一直使用CVS以及后来的subversion monorepos进行开发和包分发。

许多开源项目已经成功地使用了monorepos。例如:

  • Laravel:一个用于web开发的PHP框架。
  • Symfony:用PHP编写的另一个MVC框架。有趣的是,他们已经为每个Symfony工具和库创建了只读存储库。这种方法被称为分拆回购。
  • NixOS:这个Linux发行版使用monorepo来发布包。
  • Babel: web开发中常用的JavaScript编译器。monorepo拥有完整的项目及其所有插件。 此外,React、Ember和Meteor等前端框架都使用monorepos

然而,真正的问题是商业软件是否能从monorepo布局中受益。考虑到这些优点和缺点,让我们来听听几家尝试过它们的公司的经验。

Airbnb 和 monorail

Airbnb最初的版本被称为“monorail”。它是一个完整的Ruby on Rails应用程序。当公司开始呈指数级增长时,代码库也紧随其后。当时,Airbnb推行了一项新颖的发布政策,称为民主发布,这意味着任何开发者都可以在任何时间发布产品。

随着Airbnb的扩张,民主程序的限制受到了考验。合并变化变得越来越难。Jens的团队实施了姑息性措施,如合并队列和增强监控。这些措施在一段时间内有所帮助,但从长远来看还不够。

Airbnb的工程师们为保住“monorail”进行了一场英勇的战斗,但最终,经过数周的争论,他们决定将该应用程序拆分为微服务。因此,他们创建了两个monorepos:一个用于前端,一个用于后端。两者都包含数百个服务、文档、用于部署的Terraform和Kubernetes资源以及所有维护工具

当被问及monorepo布局的亮点时,他们说道:

“我们不想处理所有这些微服务之间的版本依赖性。使用monorepo,你可以在两个微服务之间通过一次提交进行更改[..]我们可以围绕单个存储库构建所有的工具。最大的卖点是你可以同时对多个微服务进行修改。我们运行一个脚本,然后检测monorepo中哪些应用程序受到了影响,然后部署这些应用程序。我们的主要好处是源代码控制。”

投资工具

如果我们必须从所有这些故事中吸取一个教训,那就是正确的工具是有效的monorepos的关键——构建和测试需要重新考虑。我们可以使用智能构建系统来理解项目结构,并只对自上次提交以来发生变化的部分进行操作,而不是每次更新都重新构建完整的repo。

我们大多数人没有谷歌或Facebook那样的资源。我们该怎么办?幸运的是,许多大公司已经开放了他们的构建系统:

  • Bazel:由谷歌发布,部分基于他们自己的构建系统(Blaze)。Bazel支持多种语言,能够进行大规模的构建和测试。
  • Buck: Facebook的开源快速构建系统。支持基于多种语言和平台的不同构建。
  • Pants: Pants构建系统是与Twitter、Foursquare和Square合作创建的。目前,它只支持Python,还有更多的语言正在开发中。
  • RushJS:微软针对JavaScript的可扩展的monorepo管理器,能够从单个存储库构建和部署多个包。

Monorepos得到了越来越多的关注,特别是在JavaScript中,如下面的项目所示:

  • Lerna: JavaScript的monorepo管理工具。与React、Angular或Babel等流行框架集成。
  • Yarn工作区:用一条命令在多个地方安装和更新Node.js的依赖关系。
  • ultra-runner: JavaScripts monorepo管理脚本。插头与纱线,pnpm和Lerna。支持并行建设。
  • Monorepo builder:安装和更新PHP monorepos包。

扩大存储库

源代码控制是monorepos的另一个痛点。这些工具可以帮助你扩展存储库:

  • 虚拟文件系统为Git (VFS):增加了对Git的流支持。VFS根据需要从Git存储库下载对象。最初创建这个项目是为了管理Windows代码库(最大的Git存储库)。只能在Windows下工作,但MacOS已经宣布支持。
  • 大文件存储:Git的开源扩展,为大文件添加了更好的支持。一旦安装完毕,你就可以跟踪任何类型的文件,并无缝地将它们上传到云存储中,释放你的存储库,使推送和提取速度更快。
  • Mercurial:作为Git的替代品,Mercurial是一个分布式版本控制工具,它关注的是速度。Facebook使用Mercurial,并在过去几年里推出了许多加速补丁。
  • Git CODEOWNERS:允许您定义哪个团队拥有存储库中的子目录。当有人打开一个pull请求或推入一个受保护的分支时,代码所有者会自动被请求检查。GitHub和GitLab支持此功能。

Monorepo管理的最佳实践

基于monorepo故事的集合,我们可以定义一组最佳实践:

  • 定义一个统一的目录组织以方便发现。
  • 维护分支。保持分支小,考虑采用基于主干的开发。
  • 为每个项目使用固定依赖项。一次性升级所有依赖项,迫使每个项目跟上依赖项。为真正例外的情况保留例外。
  • 如果您正在使用Git,请学习如何使用浅克隆和filter-branch来处理大容量存储库。
  • 寻找像Bazel或Buck这样的智能构建系统来加速构建和测试。
  • 当需要限制对某些项目的访问时,请使用CODEOWERS
  • 使用云CI/CD平台(比如Semaphore)来大规模测试和部署应用程序。

该使用 monorepos 吗

视情况而定。没有适合每个用例的直接答案。一些公司可能会选择monorepo一段时间,然后决定他们需要切换到 multirepos 或反之,而另一些公司可能会选择混合。如果有疑问,可以考虑一下,从 monorepo 到 multirepos 通常比反向更容易。但永远不要忘记,归根结底,这与技术无关,而是与工作文化和沟通有关。所以,根据你想要的工作方式来决定。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端修罗场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • monorepo 是什么
  • Monorepos vs. multirepos
  • 爱上 Monorepos
  • Monorepos 也有讨厌的一面
  • 这不仅仅与技术有关
  • Monorepo 文化
    • Airbnb 和 monorail
      • 投资工具
        • 扩大存储库
          • Monorepo管理的最佳实践
          • 该使用 monorepos 吗
          相关产品与服务
          持续集成
          CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档