网站排版图片,是不是该填写完整,郑州心理咨询中心,如何将域名和网站绑定域名原文#xff1a;manav - 2024.10.29
九个月前#xff0c;我们切换到了 monorepo。在此#xff0c;我将介绍我们迄今为止的切换经验。
这并不是一份规范性的建议#xff0c;而是一个经验的分享#xff0c;目的是希望能够帮助其他团队做出明智的决策。
与大多数岔路不同manav - 2024.10.29
九个月前我们切换到了 monorepo。在此我将介绍我们迄今为止的切换经验。
这并不是一份规范性的建议而是一个经验的分享目的是希望能够帮助其他团队做出明智的决策。
与大多数岔路不同我们走过了两条路。因此我会先描述导致我们改变的历史概述我们在类似的情况中已经体验过的非 monorepo 方案并因此能够更好地进行对比。
平台与 monorepo
Ente 的诞生可以追溯到五年前。它原本是一个端到端加密平台用于存储 Vishnu 的所有个人数据但后来发生了两件事 Vishnu 意识到需要这样一个平台的不仅仅是他自己他还意识到要实现他的愿景需要做大量的工作。
于是他从一个人变成了一个团队并且不再试图处理所有的个人数据而是将重点转移到其中的一个方面Ente Photos以此为起点让“飞船”起飞。对外界观察者来说这似乎只是一个照片应用实际上这确实是我们当前的具体目标但背后驱动这一切的是我们对人类隐私权的坚持即所有形式的个人数据都应受到保护。
我为什么要描述这些因为从这个愿景来看Ente 不是一个单一的应用程序而是一个平台将其代码存储在一个 monorepo 中是一个符合理念的选择。
这类似于 Linux 内核。大多数人不了解的是按多项可量化指标衡量全球最大的开源项目——Linux 内核本身——也是一个 monorepo。尽管它被称为“内核”但实际上它是一整个平台包括设备驱动程序等代码组织为 monorepo 正是这种理念的体现。
坚持将 Ente 视为一个平台不仅仅是理念上的选择它也带来了实际的益处。
例如几年前我们意识到还没有一款具有云备份功能的开源端到端加密 OTP 应用程序。于是我们为了自己的使用而构建了一款因为是基于我们为照片应用创建的基础设施实现并不难。
如今这个副产品已成为世界上最受欢迎的具有上述特性的 OTP 应用。这看似是个意外但其实不然我们的计划一直是这样的先建立一个稳固的平台然后逐一处理我们需要的各种定制应用程序以便更好地处理不同形式的数据。
微型代码仓库Microrepos
从理念上讲Ente 作为一个 monorepo 是最合适的选择。但由于产品演变的历史因素最开始并不是这样。硬件设备转变为软件服务器组件在我们有能力进行审计之前是闭源的。像 Auth 这样的周末项目超出了它们的初衷等等。
让我们倒带回两年前仅仅为了选择一个大致对称的时间点。虽然我们在包括开发人员数量在内的所有产品方面都在增长但我们在增加工程人员方面非常谨慎所以开发人员的数量并没有增加太多。因此差不多是同样数量的开发人员在处理相同数量的产品Ente Photos、Ente Auth并同时支持多个平台移动端、网页端、桌面端、服务器端、CLI。
两年前这些代码库分散在十几个仓库中。
到了今年二月我们决定花时间完成服务器端开源的任务。这是一个很自然的时机来控制代码库的分散于是我们借此机会切换到了 monorepo。
因此作为一个规模相似的团队做着类似的工作我们已经体验了约一年分散的微型仓库设置以及约一年集成的 monorepo 设置。
总结
如果要总结区别的话切换到 monorepo 后变化不大而细微的变化都是正面的。
我们对此并不感到意外。其中大多数人对代码仓库的组织方式并不十分在意总体上对这种改变也没有太高的期望。大家的整体感觉是 monorepo 可能会更好所以为什么不试试呢既然没有人反对这个选择我们就这么做了但我们并没有试图通过这次改变“解决”什么问题。
事实上整体上变化不大。我们依然对开发速度感到满意所以它并没有拖慢我们。然而确实有许多小的改进所以接下来的部分我将深入探讨这些改进。
更少的重复劳动
这是最大的实际收益。我们需要做的重复劳动大大减少了。
举个例子考虑以下的 pull request。它修改了用于计算设备上人脸嵌入的机器学习模型。 这个更改影响了1照片移动端应用2照片桌面端应用3照片网页端应用以及4机器学习的基础代码。
在之前的分仓库模式下这将是四个不同的 pull request分别提交到四个不同的仓库中并且需要通过评论将它们联系在一起以供日后参考。
现在这是一份 pull request。容易审查容易合并容易回滚。
更少的子模块
子模块是一个让人恼火但确实有效的解决方案。问题是真实存在的因此需要解决方案而子模块确实是一个合适的解决方案但它们仍然令人恼火。
这就是说我们感谢 git 子模块的存在它是解决实际代码组织问题的一种方法但我们希望不需要使用它们。
Monorepo 减少了那些本应需要子模块的地方因此这也是一个优势。
举个例子之前 Ente Photos 的网页端和桌面端代码库之间是子模块关系。每次需要发布或推动重要的更改到主分支时都会涉及到繁琐的 PR 操作。现在这些都不需要了。这两个相互依赖的代码现在可以在同一个提交中直接引用彼此变更可以原子性地完成。
更多的 Stars
这是最大的营销收益。之前我们的 Stars 分散在十几个仓库中。如果每个仓库有一千个 Stars我们总共有 12k Stars但由于人的心理和 GitHub 推荐算法的工作方式这远不如一个拥有 12k Stars 的单一仓库来的有影响力。
简单
我们在切换时的一个顾虑是这可能会影响开发速度。我们以为会需要发明各种机制和约定来避免互相干扰。
但这些顾虑被证明是多余的。我们没有发明任何东西只是静观其变结果并不需要任何新方案。因此对个人开发者来说这次切换是轻松的因为我们没有要求团队的任何成员改变他们的工作流程。
目前为止也没有“仓库范围”的指导原则除了两个
不要有仓库范围的指导原则不要动根目录文件夹
就是这样。每个文件夹内或者每个子团队内部可以自由选择任何组织方式、编码约定等等。 我意识到这种轻松对我们来说可能是由于团队规模较小以及我们对彼此能力的高度信任。而这两个因素可能无法在其他团队中复制。 长期重构
跨仓库的重构需要比在同一个仓库内的重构更多的勇气。技术上来说两者没有区别但心理上的障碍却有所不同。
举个例子我们已经将许多不同的网页应用合并到一个类似的设置中而无需事先制定详细的计划。这一切都很自然地发生了因为我们能够看到它们“彼此相邻”代码复用的机会变得显而易见。
连接感
这种“在共享空间中工作但不在同一文件夹中工作”的方式让我们比起以前单独或者以子团队的形式在各自的仓库提交代码时感觉更紧密相连。
之前很容易沉浸在各自的工作中这是好事但有时也会让人觉得自己只是在处理一个小部分而无法看到整体这不是好事。
现在大家仍然可以沉浸在自己的“文件夹”中保留了这种沉浸感的好处。但也有额外的微妙提示让我们看到自己的工作是如何与整体相互关联的。因此这是一种双赢的局面。
我所描述的可能有些抽象所以让我举个例子。每当执行 git pull 时会看到团队成员正在处理的所有变更。最近更改的文件名文件中的更改数最近的分支名最近推送的标签。这些单独来看都是低信息量且不精确的信息载体我甚至不会有意识地去看它们。
但随着时间的推移我发现这些“环境提示”无意识地、自动地让我对周围发生的事情有了极好的感知。哪些功能正在开发完成的阶段如何哪些 bug 修复被推送了最近发布了哪些版本。
类似的偶然信息交换也会发生在我打开 pull request 页面时我会不经意间瞥见其他人正在处理的内容。
最棒的是这一切都是颠覆性的、毫不费力的。每个人都在做自己的事而仅仅因为大家都在这个共享的数字空间里工作就自然地产生了一种意识和连接感。
总结
这篇文章已经很长了远超我原本的预期所以就此打住。
我本可以提供一些建议但我认为没有什么特别的技术诀窍是必须的。在切换之前让我感到困扰的一个问题是我们将如何管理 GitHub 工作流但事实证明这很简单因为我们可以将 GitHub 工作流的范围限定为仅在特定文件夹的更改上运行。
从工程师的角度来看回顾性文档如果没有“优缺点”部分是不完整的但到目前为止还没有发现任何对我们有影响的缺点所以请原谅这部分内容的缺失。
从个人角度来说我最喜欢 monorepo 的是它让我感到自己像是“巨轮”的一部分这艘巨轮正在无情地驶向完美并且已经获得了不可阻挡的势头。我现在写的代码不再是一个孤立的 Web 组件或一个 goroutine或一个小的文档修复而是这个单一平台的一部分——一个将超越我生命的平台。