Monorepo与multirepo区别何在?

简介:   **Monorepo是一个新的名词,但不是一个新的概念。**从软件开发最开始,我们已经在开始用这种模式了。这种模式的一个中心思想就是,用一个repo来管理所有的源代码。除了这种模式以外,另一个比较受推崇的模式就是multirepo,也就是用多个repo来管理自己的源代码。

  Monorepo是一个新的名词,但不是一个新的概念。从软件开发最开始,我们已经在开始用这种模式了。这种模式的一个中心思想就是,用一个repo来管理所有的源代码。除了这种模式以外,另一个比较受推崇的模式就是multirepo,也就是用多个repo来管理自己的源代码。

  不需要深刻思考这两种模式,各有利弊。今天我们来分别说一下这两种模式,但会着重来讲使用Monorepo可能会遇到的问题。

  现在比较大型的软件开发公司,比如说Google, Uber, Netflix他们都在使用monorepo。但是对于我们中小型公司或者个人开发者来说,到底需不需要用monorepo,还是选择multirepo?

  好,我们就现在具体谈一下monorepo。在这种模式下,你所有的设计文档,所有的源代码,所有的所有都放在一个repo里面。这样做的好处有这些:

  你的一次提交可以解决所有的问题。

  这个提交可以是添加一个功能,修改一个bug,这个功能添加或者代码修改会涉及很多不同的模块儿,这些模块都可以在一个change request里面做完。

  因为所有的这些修改都在一个repo里面,这样你查找历史,查看这些修改之间的关联都比较容易。

  当然了,这个好处的获取需要所有的程序员和文档提交者都遵循一个统一的格式。

  另一个好处,是所有的人都有访问权限。这样就杜绝了权限申请方面的种种问题。不存在这些代码,某些人看不了的问题。整个开发团队里面没有任何秘密。

  好,上面说了monorepo的好处, 那为什么现在很多人都在用multirepo呢?

  现在就来说说monorepo的坏处。

  Monorepo, 一个最大的问题就是随着程序规模的不断增加,代码量的增加,文档的增加,整个repo会变得越来越大。

  我以前做过一个Nike的项目, 那个项目使用的就是monorepo的模式。那个repo当时的大小是21g。怎么样?你的小心肝还能承受得住吧?

  试想一下,一个程序员只想改一下其中的一个翻译文字,你就需要把这21G大小的整个repo都拿到你的本地来。这个过程一定是欲仙欲死的。现在使用multirepo的人一定会对你说good luck。

  另一个坏处也是上面说的好处,就是权限访问的问题。Monorepo模式下的权限是开放的。代码安全,文档安全,都会是一个需要好好考虑的问题。

  这个方面如果处理不好的话,对整个团队整个项目带来的后果可能是灾难性的。

  像google这样的大公司他们都用自己的代码管理系统,那一个程序员要修改一个模块的代码的时候,他需要把所有的项目代码都下载到本地来,并获取最新的代码。做一个修改以后,check in完成就会进行整个项目的编译。整个项目可能需要两个小时的编译时间,这个时候,这个程序员可以跟别人聊聊天,可以学点东西,这也是很好的一种程序员生活。在monorepo的开发模式下,这是一个非常常见的工作状态。

  为了对这些修改做好标志,每一次一些标志性的修改都会添加一个版本号。对应一个版本号都会有一个版本历史。对应每个版本号又会有一个对应的标签。大部分时间我们只对最新的版本感兴趣。

  接下来我们来看一下multirepo, 在这种模式下,你很少见到一个非常庞大的代码库或者文档库。但这不能说这种模式,就是完美的。它还会有别的其他的问题。

  这种模式的总的设计是一个把一个大的问题分成几个小的问题来解决。通过问题的细化,减少整个问题解决的复杂度,从而让自己的工作更加顺手,更加有保障。

  上面这个设计是不是听起来很熟悉,对了, 它跟微服务架构是一个理念。

  通过这个分解,每一个小部分作为一个单独的repo。每个repo,可以分给不同的小组来开发和管理。每个小组只需要关心这一小部分工作就可以了。每一个小的部分都可以单独的进行买酒测试和开发。这个是好的一个方面。

  下面来说一个坏的方面。因为每个小组可以各自为战。这样就给协同工作带来很大的问题。比如说一个小组的模块进行了升级,导致现有的大系统其他模块儿无法正常工作。这种现象在微服务架构系统的开发中非常常见。

  如果把这个坏的方面再发挥到极致,就是每个组件之间互相依赖互相破坏,这样子你整体系统可能就陷入万劫不复的深渊。也就是说,随着微服务架构,继续把模块儿进细化,每个模块失去了紧密的联系,与此同时又没有很好的管理机制把握全局, 导致整个项目开发失去了控制,这也是很多微服务架构系统失败的原因。

  所以在multirepo的开发过程中,非常重要的一点就是避免过度的细分。一定要有一个机制来把握全局,时刻监控整个开发环境是否正常。

  制定标准是一个很有意思的话题, 虽然说技术上很难争高下, 但是总会辩论出一个最好的方案来,但是最严重的有时候根本不是技术上的问题。这个里面就会有很多说不清道不明的问题了。

  就因为如此,在一些大公司当中,因为人员的素质都比较高,都是高手,常言说一山不容二虎,这里山中有好几只,几十只老虎。在这种情况下,用一只老虎的标准来把握全局是很难的。

  所以宁愿牺牲一些下载时间,编译时间上的代价,最终他们还是继续使用monorepo的模式。

  还有一个在multirepo中不可忽视的一个问题就是为了保证一个功能的完整运行, 即使再小的改动,也有可能对所有的repo进行更新。这是一个非常烦人的过程。

  我工作过的一个multirepo项目,它里面有20多个模块。要想使整个系统工作完整,你需要把这20多个模块都下载到本地来,当然,你可以采用一些比较简洁的方式,比如说docker container的image, 尽可能的减少与过多的模块儿直接的接触。在这种模式模式下我相信你是非常喜欢黑盒模式的。因为模块太多,你根本不想搞清楚它里面到底在干什么。只要能给你工作就行了。一个是太烦人,另外一个是时间太紧张了。

  那么现在的问题就是,上面两种模式哪种更好呢?我的观点是,不管你喜欢哪种模式,选择哪种模式,他们都是你的工具,你要控制他们,而不是他们控制你。

  这种模式的本意都是想让你的工作做得更好。

  Monorepo你需要做的是尽可能的把你的测试案例细分开。这样你在提交一个修改的时候,就不需要把所有的测试都过一遍,那样太费时间了。

  Multirepo对于你自身模块的测试案例,你需要做的是把与你的模块相关的测试案例都放进来。在你提交一个修改的时候,要保证所有的这些案特殊案例都通过。如果需要下载相关模块的修改更新,要尽快通知大家去下载。

  一个很常用的模式是这两种模式的结合。你比如说一个修改,你可能需要修改很多个repo, 那你可以考虑把这多个repo合成一个。

  这个话题还有很多要可以谈的,我们这一期就先谈这些吧。

目录
相关文章
|
6月前
|
JavaScript 前端开发 开发者
js模块化的好处
js模块化的好处
34 0
|
6月前
|
JavaScript 前端开发 程序员
程序员必备技能之JS模块化,改变你的JavaScript开发方式!(一)
程序员必备技能之JS模块化,改变你的JavaScript开发方式!
|
3月前
|
JavaScript 前端开发 编译器
解锁JavaScript模块化编程新纪元:从CommonJS的基石到ES Modules的飞跃,探索代码组织的艺术与科学
【8月更文挑战第27天】随着Web应用复杂度的提升,JavaScript模块化编程变得至关重要,它能有效降低代码耦合度并提高项目可维护性及扩展性。从CommonJS到ES Modules,模块化标准经历了显著的发展。CommonJS最初专为服务器端设计,通过`require()`同步加载模块。而ES Modules作为官方标准,支持异步加载,更适合浏览器环境,并且能够进行静态分析以优化性能。这两种标准各有特色,但ES Modules凭借其更广泛的跨平台兼容性和现代语法逐渐成为主流。这一演进不仅标志着JavaScript模块化的成熟,也反映了整个JavaScript生态系统的不断完善。
51 3
|
24天前
|
缓存 前端开发 JavaScript
前端架构思考:代码复用带来的隐形耦合,可能让大模型造轮子是更好的选择-从 CDN 依赖包被删导致个站打不开到数年前因11 行代码导致上千项目崩溃谈谈npm黑洞 - 统计下你的项目有多少个依赖吧!
最近,我的个人网站因免费CDN上的Vue.js包路径变更导致无法访问,引发了我对前端依赖管理的深刻反思。文章探讨了NPM依赖陷阱、开源库所有权与维护压力、NPM生态问题,并提出减少不必要的依赖、重视模块设计等建议,以提升前端项目的稳定性和可控性。通过“left_pad”事件及个人经历,强调了依赖管理的重要性和让大模型代替人造轮子的潜在收益
|
3月前
|
Rust 开发者
揭秘Rust编程:模块与包的终极对决,谁将主宰代码组织的新秩序?
【8月更文挑战第31天】在软件工程中,模块化设计能显著提升代码的可读性、可维护性和可重用性。Rust 作为现代系统编程语言,其模块和包管理机制为开发者提供了强有力的工具来组织代码。本文通过对比模块和包的概念及使用场景,探讨了 Rust 中的最佳实践。
29 2
|
3月前
|
XML Java Maven
"Maven项目模块化大揭秘!掌握Model间最佳继承设计,让你的代码优雅如诗,项目维护不再愁!"
【8月更文挑战第11天】Maven是Java项目中常用的构建工具,其模块化特性对大型项目的管理至关重要。本文介绍Maven中的继承与聚合机制,指导如何通过继承消除重复配置,以及如何通过聚合统一构建多个模块。遵循单一职责原则,文章建议按功能划分模块,并提供了父POM与子POM的配置示例。此外,还讨论了适度模块化、依赖管理的原则,帮助提升项目的可维护性和扩展性。
51 4
|
3月前
|
开发者 C# Android开发
明白吗?Xamarin与Native的终极对决:究竟哪种开发方式更适合您的项目需求,让我们一探究竟!
【8月更文挑战第31天】随着移动应用开发的普及,开发者面临多种技术选择。本文对比了跨平台解决方案Xamarin与原生开发方式的优势与劣势。Xamarin使用C#进行跨平台开发,代码复用率高,可大幅降低开发成本;但因基于抽象层,可能影响性能。原生开发则充分利用平台特性,提供最佳用户体验,但需维护多套代码库,增加工作量。开发者应根据项目需求、团队技能和预算综合考量,选择最适合的开发方式。
110 0
|
6月前
|
存储 Web App开发 运维
发布、部署,傻傻分不清楚?从概念到实际场景,再到工具应用,一篇文章让你彻底搞清楚
部署和发布是软件工程中经常互换使用的两个术语,甚至感觉是等价的。然而,它们是不同的! • 部署是将软件从一个受控环境转移到另一个受控环境,它的目的是将软件从开发状态转化为生产状态,使得软件可以为用户提供服务。 • 发布是将软件推向用户的过程,应用程序需要多次更新、安全补丁和代码更改,跨平台和环境部署需要对版本进行适当的管理,有一定的计划性和管控因素。
1479 1
|
6月前
|
Web App开发 JavaScript 前端开发
程序员必备技能之JS模块化,改变你的JavaScript开发方式!(二)
程序员必备技能之JS模块化,改变你的JavaScript开发方式!
|
6月前
|
测试技术
Cypress哪些独特的地方
Cypress哪些独特的地方