MultiRepo 和 Monorepo:代码管理的演进与选择

一、Monorepo 介绍

Monorepo 是一种项目代码管理方式,指单个仓库中管理多个项目,有助于简化代码共享、版本控制、构建和部署等方面的复杂性,并提供更好的可重用性和协作性。Monorepo 提倡了开放、透明、共享的组织文化。

二、Monorepo 演进

阶段一:单仓库巨石应用, 一个 Git 仓库维护着项目代码,随着迭代业务复杂度的提升,项目代码会变得越来越多,越来越复杂,大量代码构建效率也会降低,最终导致了单体巨石应用,这种代码管理方式称之为 Monolith

阶段二:多仓库多模块应用 ,将项目拆解成多个业务模块,并在多个 Git 仓库管理,模块解耦,降低了巨石应用的复杂度,每个模块都可以独立编码、测试、发版,代码管理变得简化,构建效率也得以提升,这种代码管理方式称之为 MultiRepo-Multi Repository。

阶段三:单仓库多模块应用 ,随着业务复杂度的提升,模块仓库越来越多,MultiRepo这种方式虽然从业务上解耦了,但增加了项目工程管理的难度,随着模块仓库达到一定数量级,会有几个问题:跨仓库代码难共享;分散在单仓库的模块依赖管理复杂(底层模块升级后,其他上层依赖需要及时更新,否则有问题);增加了构建耗时。于是将多个项目集成到一个仓库下,共享工程配置,同时又快捷地共享模块代码,成为趋势,这种代码管理方式称之为 MonoRepo-Mono Repository。

三、Monorepo 项目管理策略对比

场景 Monolithic 架构 MultiRepo多仓库多模块应用 MonoRepo单仓库多模块应用
代码共享 ✅ 编码方便、代码复用度高❌ 项目增多后,启动十分缓慢,开发效率降低,调试成本较高 ✅ 代码隔离,开发者只需关注自己负责的仓库 ❌ 代码复用能力差。各项目独立管理,代码很难共享,存在重复造轮子的问题。可以使用包管理平台(如 npm)或 模块联邦实现,较复杂。 ✅ 一个仓库中多个相关项目,很容易看到整个代码库的变化趋势。✅ 启动快速,调试方便✅ 代码共享比较容易(直接使用工作区 workspace)
依赖管理 ✅ 统一的工程配置,新项目可以直接进入开发,无需复杂的工程配置 ❌ 多个仓库都有自己的 node_modules,存在依赖重复安装情况,占用磁盘内存大。 ✅ 统一的工程配置,多项目代码都在一个仓库中,相同版本依赖提升到顶层只安装一次,节省磁盘内存,
开发迭代 ❌ 代码体积庞大,不利于阅读和重构 ✅ 仓库体积小,模块划分清晰,可维护性强。 ❌ 多仓库来回切换(编辑器及命令行),项目多的话效率很低。 ✅ 代码复用高。❌ 多项目在一个仓库中,代码体积较大,git clone时间较长。 ✅ 依赖调试方便,依赖包迭代场景下,借助工具自动 npm link,直接使用最新版本依赖,简化了操作流程。
工程配置 ✅ 各项目的依赖版本统一❌ 依赖升级困难,所有项目都使用同一依赖,升级的成本、风险很高。 ✅ 单个项目升级依赖不会影响到其他项目❌ 各项目构建、打包、代码校验都各自维护,不一致时会导致代码差异或构建差异。 ✅ 各项目依赖版本可以统一,也可以保持不同,相当灵活。 共同依赖可以提升到 root,方便依赖管理✅ 便于统一批量升级各项目依赖
构建部署 ❌ 项目增多后,构建、部署速度变得越来越慢 ✅ 单独的部署环境 ✅ 各项目可以单独部署

四、 如何选择?

3.1 适合使用 MultiRepo (仓库多模块应用) 的场景

  1. 模块独立性强

    • 模块之间几乎没有依赖关系,或者依赖关系很弱。
    • 每个模块可以独立开发、测试和部署。
  2. 团队规模大

    • 不同的团队负责不同的模块,团队之间的协作较少。
    • 需要对模块设置严格的权限管理。
  3. 技术栈多样性

    • 不同模块使用了不同的技术栈。

3.2 适合使用 MonoRepo (单仓库多模块应用) 的场景

  1. 模块依赖关系强

    • 模块之间共享大量代码或依赖。
    • 跨模块的变更较多,需要统一管理。
  2. 团队规模小到中型

    • 团队规模较小,成员需要频繁协作。
    • 权限管理需求较低。
  3. 统一的技术栈

    • 所有模块使用相同的技术栈(如前端所有模块使用 Vue 或 React)。
  4. 需要高效的开发和测试

    • 希望通过统一的工具链和依赖管理提升开发效率。
    • 希望通过增量构建和测试优化 CI/CD 流程。

五、Monorepo 的一些问题

1、幽灵依赖

问题:npm/yarn 安装依赖时,存在依赖提升,某个项目使用的依赖,并没有在其 package.json 中声明,也可以直接使用,这种现象称之为 "幽灵依赖";随着项目迭代,这个依赖不再被其他项目使用,不再被安装,使用幽灵依赖的项目,会因为无法找到依赖而报错。

方案 :基于 npm/yarn 的 Monorepo 方案,依然存在 "幽灵依赖" 问题,我们可以通过 pnpm 彻底解决这个问题

2、依赖安装耗时长

问题 :MonoRepo 中每个项目都有自己的 package.json 依赖列表,随着 MonoRepo 中依赖总数的增长,每次 install 时,耗时会较长。

方案 :相同版本依赖提升到 Monorepo 根目录下,减少冗余依赖安装;使用 pnpm 按需安装及依赖缓存。

六、工程搭建 pnpm+workspace+vite+ts+vue

采用MonoRepo管理单仓库多模块应用的方式,结合pnpm、Vite、Vuet和TypeScript的技术栈,可以形成一个高效、模块化和现代化的前端项目。以下是项目的整体设计方案:

1、项目背景

XXX项目X年前搭建采用单仓库巨石应用Monolith, 一个 Git 仓库维护着项目代码,随着迭代业务复杂度的提升,项目代码会变得越来越多,越来越复杂,大量代码构建效率也会降低,最终导致了单体巨石应用

面临着陈旧的架构和过时的组件库,任何微小的升级都可能引发全局性的影响。新技术和功能的应用受限,维护困难,且无法实现有效的统一管理。这些问题都迫切需要我们进行系统的重构。

XXXXX现状分析:

痛点 分析 方案
**单仓库巨石应用(Monolith)&&**多仓库多模块应用 所有的前端代码都维护在一个工程中,随着时间的推移和业务的增长,代码基础变得庞大和复杂。尽管目前用了iframe的方式,多仓库多模块应用**,**但是iframe嵌入的模块都散落在各个git仓库,难以维护,公共模块也难以公用。 MonoRepo方案
技术栈老旧 项目采用的是Vue2技术栈,但使用了老旧的架构和过时的组件库,这限制了新技术的采用和现有功能的扩展。 每个模块单独部署构建,按需应用自己模块的版本
代码维护困难 历史代码中缺乏规范的TypeScript写法,使得类型系统的优势没有得到充分发挥,增加了维护难度和出错概率。 MonoRepo方案

升级的必要性:

| 提升点 | 分析 |
|--------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|
| 单仓库多模块应用 | 随着业务复杂度的提升,模块仓库越来越多,MultiRepo这种方式虽然从业务上解耦了,但增加了项目工程管理的难度,随着模块仓库达到一定数量级,会有几个问题:跨仓库代码难共享;分散在单仓库的模块依赖管理复杂(底层模块升级后,其他上层依赖需要及时更新,否则有问题);增加了构建耗时。于是将多个项目集成到一个仓库下,共享工程配置,同时又快捷地共享模块代码,成为趋势,这种代码管理方式称之为 MonoRepo-Mono Repository。 |
| 提高构建效率 | 现有的单体应用构建效率低下,需要通过模块化和微前端技术将应用拆分,实现更快的构建和部署。 |
| 技术栈现代化 | 更新到最新的Vue版本,采用最新的前端技术和工具,以便更好地应对未来业务的需求和挑战。 |
| 代码质量提升 | 通过引入更严格的TypeScript规范和代码规范工具(如ESLint、Prettier),提升代码质量,减少bug发生率。 |
| 用户体验优化 | 通过性能优化措施(如代码分割、懒加载、资源优化等)改善页面加载速度和交互平滑度,提升用户体验。 | |

2、项目范围和目标

解决XXXX项目中历史逻辑混乱、技术栈老旧等问题, 缩短XXXXX项目整体需求交付时长。

简化代码共享、版本控制、构建和部署等方面的复杂性,并提供更好的可重用性和协作性。

建设一个统一工程建设标准、促进跨项目代码复用、从而实现开发效率提升、减少维护成本与简化项目管理、高效、稳定、可持续发展的系统,为后续业务发展和技术架构升级打下基础,具体目标可分为:

  1. 提高人效
  2. 提高加载性能
  3. 提高稳定性
  4. 可维护可扩展性
相关推荐
启山智软12 小时前
供应链商城核心功能模块清单
java·前端·开源
徐同保12 小时前
Claude Code提示词案例(开发复杂动态路由详情页面)
前端
Σdoughty12 小时前
python第三次作业
开发语言·前端·python
是萧萧吖12 小时前
每日一练——有效的括号
java·开发语言·javascript
gpldock22213 小时前
Flutter App Templates Deconstructed: A 2025 Architectural Review
开发语言·javascript·flutter·wordpress
Ivanqhz13 小时前
现代异构高性能计算(HPC)集群节点架构
开发语言·人工智能·后端·算法·架构·云计算·边缘计算
白中白1213813 小时前
Vue系列-2
前端·javascript·vue.js
DisonTangor13 小时前
智谱开源基于GLM-V编码器-解码器架构的多模态OCR模型——GLM-OCR
架构·开源·ocr
jin42135213 小时前
React Native鸿蒙跨平台完成闪屏页作为移动应用的入口级页面,实现的二手置换应用闪屏页SecondhandSplash
javascript·react native·react.js·ecmascript·harmonyos
CHU72903513 小时前
一番赏盲盒小程序前端功能:层级乐趣与便捷服务的双向赋能
前端·小程序