Skip to content

架构策略

项目架构策略

Monorepo 是一种项目开发与管理的策略模式,它代表"单一代码仓库(Monolithic Repository)。在 Monorepo 模式中,所有相关的项目和组件都被存储在一个统一的代码仓库中,而不是分散在多个独立的代码仓库中,这些项目之间还可能会有依赖关系。

项目开发与管理模式

项目管理模式发展到现在,先后有三种项目管理模式的历史进程:

项目开发与管理模式

Monolithic(单体应用)开发模式

在软件开发的早期阶段,通常采用单体应用的开发模式。整个应用程序由一个单一的代码库、构建和部署流程组成。这种模式简单易懂,适合小型项目。

优点:

  • 易于集成和部署。所有的代码在一个仓库里面,不需要特别的集中管理和协调,也可以直接在本地部署调试。
  • 易于重用。所有的代码都在一个仓库中,开发人员开发的时候比较容易发现和重用已有的代码。
  • 易于规范代码。所有的代码在一个仓库当中就可以标准化依赖管理,规范化代码的风格。

缺点:

  • 代码维护性变差,随着功能以及代码量的大幅增加,代码功能耦合性增强。
  • 构建时间过长,任何小修改必须重新构建整个项目,这个过程往往很长。
  • 稳定性差,任意一个功能出现问题,可能导致整个应用挂掉。

Multirepo(多仓多模块)开发模式

为了解决单体应用的扩展性问题,团队开始将项目拆分为多个独立的仓库,每个仓库独立维护自己的代码和构建流程。这种模式更适合大型和复杂的项目,因为它提供了更好的隔离性和独立性,同时可以更灵活地管理多个团队的工作。

优点:

  • 每一个项目都有一个独立的仓库,职责单一。
  • 代码量和复杂性受控,项目由不同的团队独立维护、边界清晰。
  • 单个项目也易于自治开发测试部署和扩展,不需要集中管理集中协调。
  • 利于进行权限控制,可以针对单个仓库来分配权限,权限分配粒度比较细。

缺点:

  • 代码和配置很难共享:每个仓库都需要做一些重复的工程化能力配置(如 eslint/test/ci 等)且无法统一维护,且不利于代码复用。
  • 依赖的治理复杂:模块越来越多,涉及多模块同时改动的场景增加。如何保障底层组件升级后,其引用到的组件也能同步更新到位。这点很难做到,如果没及时升级,各工程的依赖版本不一致,往往会引发一些意想不到的问题。
  • 开发人员缺乏对整个项目的整体认知:开发人员一般只关心自己的服务代码,看不到项目整体,造成缺乏对项目整体架构和业务目标整体性的理解。
  • 存储和构建消耗增加:假如多个工程依赖 pkg-a,那么每个工程下 node_modules 都会重复安装 pkg-a,对本地磁盘内存和本地启动都是个很大的挑战。而且每个模块的发布都是相对独立的,当一次迭代修改较多模块时,总体发布时效就是每个发布流程的串联。对发布者来说是一个非常大的负担。
  • 部署复杂化,每次部署需要一次性部署多个仓库,部署流程复杂,容易出错。
  • 项目移交困难:当一个项目需要移交给其他团队时,需要将多个仓库移交给其他团队,移交过程复杂,容易遗漏出错,基本上需要重新梳理一遍。

Monorepo (单仓多模块)开发模式 框架内采用

现代主流模式

字节跳动、阿里、丁香园、Facebook、Google、Microsoft、Airbnb、Twitter、Uber、Netflix 等公司都在使用 Monorepo 模式进行开发。

回归单体管理:Monorepo 是一种试图回归单体管理优势的方法,但保留了多仓库开发的某些优点。它允许在一个代码库中管理多个项目、组件或服务,提供更好的代码共享和重用性。

现代工具支持:现代的版本控制系统和工具链使得 Monorepo 开发模式更为可行,例如像 PnpmYarnLernaTurborepo 等工具,它们提供了更好的管理、构建和部署多个项目的能力。

优点:

  • 保留 multirepo 的主要优势
  • 代码复用
  • 模块独立管理
  • 分工明确,业务场景独立
  • 代码耦合度降低
  • 管理所有项目的版本控制更加容易和一致,降低了不同项目之间的版本冲突。
  • 可以统一项目的构建和部署流程,降低了配置和维护多个项目所需的工作量。

缺点:

  • Monorepo 可能随着时间推移变得庞大和复杂,导致构建时间增长和管理困难,git clonepull 的成本增加。
  • 权限管理问题:项目粒度的权限管理较为困难,容易产生非owner管理者的改动风险。

Monorepo + 微前端的架构

  • aPaas平台的微应用适配其实就要求我们使用微前端,从兼容集团 aPaas平台的使用要求上,技术底座就要有微前端的能力。
  • 为项目添加应用级别的复用能力。假如一个项目使用了 ABC 三个应用去组合一个应用,其他项目也需要使用这三个应用或者其中的几个应用,那么我们可以将这些应用直接提取出来,作为其他项目可以直接内嵌这个应用,可以极大的提高复用能力
  • 为持续升级做技术铺垫,抽离应用内所有的依赖和公共模块到其他模块内,可以让项目的升级更加的快速和简单。
  • 只聚焦于业务开发,不用关心底层的兼容浏览器的转移、适配各个平台、编译器、ast抽象语法树、这类需要底层技术支持的功能,可以让业务开发者更加的专注于业务开发,不用关心底层的技术架构。