Monorepo

❌现有的架构可能会遇到什么问题

分散的git仓库

随着时间的沉淀,项目数量在飞速增长,增加了项目的工程管理难度

怎么区分来源呢?

  • 通过git目录划分
  • 通过项目命名

新员工入职的时候需要,需要下载代码并安装所需的依赖。在这种情况下,初始设置将很复杂(可能会遇到环境不一致),在文档通常不完整情况下,可能需要寻求帮助。

代码复用

在多个项目间涉及公共组件、公共函数或公共配置(如各种config)时候,代码复用就成了问题。

解决方案:

  • copy 相关代码
  • 抽取公共逻辑发布npm包

开发体验

项目开发时

多个 git 仓库管理起来天然是麻烦的。对于功能类似的模块,如果拆成了多个仓库,无论对于多人协作还是独立开发,都需要打开多个仓库页面。

组件开发时

  1. 进入 npm 包项目,执行 npm link
  2. 进去 app 应用,执行 npm link package
  3. 调试完成后,执行 npm unlink package
    在这里插入图片描述

工作流

在当前的工作流中,每个仓库都需要做一些重复的工程化能力配置(如 eslint/prettier/ci 等)且无法统一维护,当有工程上的升级时,需要手动更新所有仓库的配置。

Code Review、Merge Request 从各自模块仓库执行,比较割裂。

🤔️什么是 Monorepo

monorepo 是一种将多个项目代码存储在一个仓库里的软件开发策略
在这里插入图片描述

Monorepo 能带来什么

统一工作流

首先是 工作流的一致性 ,由于所有的项目放在一个仓库当中,复用起来非常方便,如果有依赖的代码变动,那么用到这个依赖的项目当中会立马感知到。并且所有的项目都是使用最新的代码,不会产生其它项目版本更新不及时的情况,对开发调试而言都带来了方便

降低基建成本

其次是 项目基建成本的降低 ,所有项目复用一套标准的工具和规范,无需切换开发环境,如果有新的项目接入,也可以直接复用已有的基建流程,比如 CI 流程、构建和发布流程。这样只需要很少的人来维护所有项目的基建,维护成本也大大减低

提升团队协作效率

再者, 团队协作也更加容易 ,一方面大家都在一个仓库开发,能够方便地共享和复用代码,方便检索项目源码,另一方面,git commit 的历史记录也支持以功能为单位进行提交,之前对于某个功能的提交,需要改好几个仓库,提交多个 commit,现在只需要提交一次,简化了 commit 记录,方便协作

Monorepo遇到的问题

权限问题

由于单仓的管理模式,使用Monorepo将无法简单的控制各个模块代码的访问限制,任何有权限访问该仓库的人员将有权限访问所有的代码工程,这可能会导致部分安全问题。

性能问题

当仓库的代码规模非常的巨大,达到GB/TB的级别,会增大开发环境的代码下载成本,以及本地硬盘的压力,执行git status也可能需要花费数秒甚至数分钟的时间。并且,当代码工程很多且活跃数量也很多的情况,会加大分支管理策略和各个代码工程版本管理的压力。

Monorepo 方案

考虑使用 turborepo 构建方案 和 pnpm 包管理方案

turborepo 构建方案

TurboRepo 的出现,正是解决 Monorepo 慢的问题

在这里插入图片描述

多任务并行处理

Turbo支持多个任务的并行运行,我们在对多个子包,编译打包的过程中,turbo会同时进行多个任务的处理

在传统的 monorepo 任务运行器中,就像lerna或者yarn自己的内置workspaces run命令一样,每个项目的script生命周期脚本都以拓扑方式运行(这是“依赖优先”顺序的数学术语)或单独并行运行。根据 monorepo 的依赖关系图,CPU 内核可能处于空闲状态——这样就会浪费宝贵的时间和资源。

什么是拓扑 ? 拓扑 Topological Order 是一种排序 拓扑排序是依赖优先的术语, 如果 A 依赖于 B,B 依赖于 C,则拓扑顺序为 C、B、A。

比如一个较大的工程往往被划分成许多子工程,我们把这些子工程称作活动(activity)。在整个工程中,有些子工程(活动)必须在其它有关子工程完成之后才能开始,也就是说,一个子工程的开始是以它的所有前序子工程的结束为先决条件的

为了可以了解turbo多么强大,下图比较了turbovslerna任务执行时间线:

在这里插入图片描述

turbo它能够有效地安排任务类似于瀑布可以同时异步执行多个任务,而lerna一次只能执行一项任务 所以turbo的 性能不言而喻。

增量构建

TurboRepo 的基本原则是从不重新计算以前完成的工作, Turborepo 会记住你构建的内容并跳过已经计算过的内容,在多次构建开发时,这也就意味更少的构建耗时。

pnpm 包管理方案

pnpm(performant npm)本质上就是一个包管理器,这一点跟 npm/yarn 没有区别,但它作为杀手锏的优势在于:

  • 解决幽灵依赖
  • 包安装速度极快;
  • 磁盘空间利用非常高效。

👻解决幽灵依赖
在这里插入图片描述

package.json
// project
{"name": "test","version": "1.0.0","main": "lib/index.js","dependencies": {"A": "1.0.0","B": "1.0.0","C": "1.0.0"},
}// c package
{"name": "C","version": "1.0.0","main": "lib/index.js","dependencies": {// "A": "2.0.0","D": "1.0.0"},
}

npm1npm2 中呈现出的是嵌套结构,比如下面这样:

node_modules
├── A@1.0.0
├── B@1.0.0
└── C@1.0.0└── node_modules└── D@1.0.0

这样的设计会存在什么问题:

  1. 依赖层级太深,会导致文件路径过长的问题,尤其在 window 系统下。
  2. 大量重复的包被安装,文件体积超级大。比如跟 A 同级目录下有一个 B, 两者都依赖于同一个版本的lodash,那么 lodash 会分别在两者的 node_modules 中被安装,也就是重复安装。

从 npm3 开始,包括 yarn,都着手来通过扁平化依赖的方式来解决这个问题

相比之前的嵌套结构,现在的目录结构类似下面这样:

node_modules
├── A@1.0.0
├── B@1.0.0
├── C@1.0.0
└── D@1.0.0

未定义在其 package.json 文件中的D包,可以直接被引用到

pnpm 使用符号链接将项目的直接依赖项添加到模块目录的根目录中。

.pnmp 为虚拟存储目录,该目录通过 <package-name>@<version> 来实现相同模块不同版本之间隔离和复用,由于它只会根据项目中的依赖生成,并不存在提升,所以它不会存在之前提到的 幽灵依赖问题!

node_modules
├── A -> .pnmp/A@1.0.0
├── B -> .pnmp/B@1.0.0
└── C -> .pnmp/C@1.0.0node_modules└── D -> .pnmp/D@1.0.0

在这里插入图片描述

速度快

pnpm 安装包的速度究竟有多快?先以 React 包为例来对比一下:

在这里插入图片描述

可以看到,作为黄色部分的 pnpm,在绝多大数场景下,包安装的速度都是明显优于 npm/yarn,速度会比 npm/yarn 快 2-3 倍。

高效利用磁盘空间

当使用 npm 时,如果你有 100 个项目,并且所有项目都有一个相同的依赖包,那么, 你在硬盘上就需要保存 100 份该相同依赖包的副本。然而,如果是使用 pnpm,依赖包将被存放在一个统一的位置,因此:

  1. 如果你对同一依赖包需要使用不同的版本,则仅有 版本之间不同的文件会被存储起来。例如,如果某个依赖包包含 100 个文件,其发布了一个新 版本,并且新版本中只有一个文件有修改,则 pnpm update 只需要添加一个 新文件到存储中,而不会因为一个文件的修改而保存依赖包的 所有文件。
  2. 所有文件都保存在硬盘上的统一的位置。当安装软件包时, 其包含的所有文件都会硬链接自此位置,而不会占用 额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的 依赖包。

🌰Monorepo 实践

对于一个新的项目,可以运行下面的命令来生成全新的代码仓库

pnpm dlx create-turbo@latest

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/17700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕设 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉…

【技术讨论】RF环境搭建手册

简要整理下环境搭建的步骤&#xff0c;以便快速、准确的搭建测试环境。 一、环境搭建 一、Python 2.7 1、 不要用Python3.6&#xff0c;很多库3.6中还没有&#xff0c;wxPython官方只支持Python 2。 2、 环境变量配置后需要重启才能生效。 3、 环境变量添加C:\Python27\Sc…

一文详解:自动化测试工具——Selenium

前言 Selenium是一个用于Web应用程序测试的工具。是一个开源的Web的自动化测试工具&#xff0c;最初是为网站自动化测试而开发的&#xff0c;类型像我们玩游戏用的按键精灵&#xff0c;可以按指定的命令自动操作&#xff0c;不同是Selenium可以直接运行在浏览器上&#xff0c;…

明明已经安装字体,但IDEA、CLION无法找到思源黑体/Source Hans Sans的问题解决

IDEA、CLION的Jetbrain系列软件不支持非TrueType的中文字体&#xff0c;而Adobe官方给出的字体却不是TrueType的&#xff0c;所以便会导致Jetbrain系软件无法找到已安装的中文字体&#xff0c;因此我们需要安装TrueType的字体 请在以下Github链接中下载&#xff1a; TrueType思…

HDFS中数据迁移的使用场景和考量因素

HDFS中数据迁移的使用场景和考量因素 数据迁移使用场景数据迁移要素考量HDFS分布式拷贝工具-DistCpdistcp的优势性能命令 数据迁移使用场景 冷热集群数据同步、分类存储集群数据整体搬迁 当公司业务迅速的发展&#xff0c;导致的当前的服务器数量资源出现临时紧张的时候&#…

python-网络爬虫.Request

Request python中requests库使用方法详解&#xff1a; 一简介&#xff1a; Requests 是Python语言编写&#xff0c;基于urllib&#xff0c; 采用Apache2 Licensed开源协议的 HTTP 库。 与urllib相比&#xff0c;Requests更加方便&#xff0c;处理URL资源特别流畅。 可以节约我…

解读随机森林的决策树:揭示模型背后的奥秘

一、引言 随机森林[1]是一种强大的机器学习算法&#xff0c;在许多领域都取得了显著的成功。它由多个决策树组成&#xff0c;而决策树则是构建随机森林的基本组件之一。通过深入解析决策树&#xff0c;我们可以更好地理解随机森林模型的工作原理和内在机制。 决策树是一种树状结…

JavaEE简单示例——在使用Tomcat的时候可能出现的一些报错

简单介绍&#xff1a; 在我们之前使用Tomcat的时候&#xff0c;经常会出现在启动的时候因为一些报错导致项目无法正常的启动&#xff0c;我们就对一些比较常见的报错来看一下可能导致的原因&#xff0c;以及出现报错之后如何去解决。 严重: Failed to initialize end point a…

小程序商品如何上传视频

小程序商品展示的方式在不断创新&#xff0c;除了传统的图片展示&#xff0c;视频成为了吸引用户注意力的重要方式之一。今天就讲解一下&#xff0c;商家怎么上传商品视频。 1. 商家需要准备好商品视频。商家可以自己拍摄商品的使用演示视频、产品介绍视频等&#xff0c;也可以…

shell脚本:使用mysqldump实现分库分表备份

一.什么是分库分表备份 分库分表备份是一种数据库备份策略&#xff0c;用于处理大型数据库系统中的数据分布和备份需求。当数据库的数据量非常大时&#xff0c;单个数据库可能无法满足性能和可扩展性的要求。为了解决这个问题&#xff0c;使用分库分表技术将数据库拆分成多个库…

北漂Java程序员入职五个月的收获总结

&#x1f468;‍&#x1f4bb;博主主页&#xff1a;小尘要自信 &#x1f468;‍&#x1f4bb;本文专栏&#xff1a;Java程序员的成长 &#x1f468;‍&#x1f4bb;上一篇文章&#xff1a;告别过去&#xff0c;拥抱未来&#xff1a;一个Java开发者的成长之路 &#x1f468;‍&a…

LRU缓存淘汰算法详解与实现

目录 1.什么是LRU算法 2.LRU算法原题描述 3.LRU算法设计 4.LRU算法细节分析 5.代码实现 1.什么是LRU算法 就是一种缓存淘汰策略。 计算机的缓存容量有限&#xff0c;如果缓存满了就要删除一些内容&#xff0c;给新内容腾位置。但问题是&#xff0c;删除哪些内容呢&#…

tinkerCAD案例:31. 3D 基元形状简介

tinkerCAD案例&#xff1a;31. 3D 基元形状简介 1 将一个想法从头脑带到现实世界是一次令人兴奋的冒险。在 Tinkercad 中&#xff0c;这将从一个新的设计开始。 在新设计中&#xff0c;简单的原始形状可以通过不同的方式组合成更复杂的形状。 在这个项目中&#xff0c;你将探索…

【个人笔记】Linux 服务管理两种方式service和systemctl

service命令与systemctl 命令 service 命令与传统的 SysVinit 和 Upstart 初始化系统相关。较早期的 Linux 发行版&#xff08;如早期的 Ubuntu、Red Hat 等&#xff09;使用了这些初始化系统。service 命令用于启动、停止、重启和查询系统服务的状态。虽然许多现代 Linux 发行…

小红书2020校招测试开发后端笔试题卷三

//完全背包求组合数 #include <iostream> #include<vector> #include<set> #include<map> #include<algorithm> using namespace std; int value[300]; // vector<int>vis; // vector<int>vis1; map<vector<int>,int>m…

web前端开发工程师工作的岗位职责(合集)

web前端开发工程师工作的岗位职责1 职责&#xff1a; 1、根据设计图进行前端页面开发并设计编写业务交互脚本 2、优化前端页面&#xff0c;保证良好的用户体验以及不同浏览器的兼容性 3、web前沿技术研究和新技术调研&#xff0c;将主流的特效应用到业务场景中 4、配合后台…

安装Apache遇到的问题

安装Apache服务 httpd -k install -n Apache2.4 #-n后面表示自定义访问名称 问题1&#xff1a; 此时去 windows 的开始摁扭里找到控制器右键管理员运行 问题2&#xff1a; 命令行没用对 应该用&#xff1a; .\httpd -k install -n Apache2.4 #-n后面表示自定义访问名称

kafka常用命令

目录 Kafka通用命令 进入Kafka 1.进入kafka容器 2.进入kafka目录 查看Topic信息 1.查看所有Topic的列表 2.查看单个Topic的信息 查看ConsumerGroup信息 1.查看所有ConsumerGroup的列表 2.查看单个ConsumerGroup的信息 读取Topic中的数据 向Topic写入数据 Kafka通用…

快速响应,上门维修小程序让您享受无忧生活

随着科技的不断发展和智能手机的普及&#xff0c;上门维修小程序成为了现代人生活中越来越重要的一部分。上门维修小程序通过将维修服务与互联网相结合&#xff0c;为用户提供了更加便捷、高效的维修服务体验。下面将介绍上门维修小程序开发的优势。   提供便捷的预约方式&am…

神经网络原理概述

文章目录 1.神经元和感知器1.1.什么是感知器1.2.什么是单层感知器1.3.多层感知机&#xff08;Multi-Layer Perceptron&#xff0c;MLP&#xff09; 2.激活函数2.1.单位阶跃函数2.2.sigmoid函数2.3.ReLU函数2.4.输出层激活函数 3.损失函数4.梯度下降和学习率5.过拟合和Dropout6.…