文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

前端Monorepo大仓代码按需拉取技术实现原理

2024-11-30 11:24

关注

1、背景与难点

目前,前端平台探索大仓研发模式,通过Monorepo大仓的技术,整合前端平台现有应用的仓库代码,使得各业务域应用质量衡量标准统一,通用基础组件以及工具函数能够快速复用,当基础通用功能出现问题的时候,能快速地在各应用中升级,提升研发工作效率,节省人效。

我们知道在普通的项目开发中进行 git 的克隆和拉取不会遇到什么问题。但是随着我们代码的不断扩充,代码仓库内容会变得越来越大,需要几个G甚至几十上百G的磁盘空间时,如果把所有代码都pull到本地属实是个不现实的方式,不仅是我们没有这么大的磁盘空间,而且还有网络流量的占用问题以及网络速度问题都是没有办法解决。而且,如果Git仓库特别大,每次执行Git命令,等待时间会特别长。对于这些问题,我们做了相关的技术调研。

2、技术调研

我们调研了下Facebook和Google大仓代码按需拉取的实现,其使用方式大致如下:

Facebook

mercurial:是一个分布式版本控制工具(类似Git,是Matt Mackall开发),采用的是基于内容寻址的技术。当对一个文件进行修改时,mercurial 不会直接修改文件本身,而是创建一个新版本,该版本包括指向之前版本的引用以及所做修改的差异。这样,就可以在没有改变之前版本的基础上构建新版本,同时正确地跟踪文件的变化历史。

Vscode工具:支持下载局部代码 & 全局代码检索等能力

像Facebook和Google都是自研的类似Git的工具,如果我们自己自研的话,成本会很大。所以,目前是另辟蹊径选择了基于 git 的sparse checkout 来实现。Git在2.25及以上版本提供了sparse checkout的能力,能够实现代码的按需拉取。

3、实现原理

3.1 git sparse checkout的原理

3.1.1 sparse checkout定义

所谓稀疏检出就是,Git本地库检出时不检出全部,只将指定的文件从Git本地库检出到Git工作区,而其他未指定的文件则不予检出(即使这些文件存在于工作区,其修改也会被忽略)。

3.1.2 sparse checkout原理

当开启sparse checkout功能的时候, Git 从远程仓库下载整个仓库对象的元数据(metadata),而不是下载所有的文件。具体来说,Git下载仓库时,首先下载仓库的基础元数据对象(如提交对象、树和blob等),然后将基础数据对象整合成commit对象,并下载相关的历史记录。在这个过程中,Git会逐步下载和存储文件的有关信息(例如文件名、大小和内容哈希值),但并不会立即下载所有文件的内容。只有当执行检出命令时,Git才会根据指定的分支或标签,从远程仓库下载所需的文件的实际内容。

Git 实现这个稀疏检出,是靠一个skip-worktree的标识, 即在 index (即Git暂存区)中为每个文件提供一个名为 skip-worktree 的标志位,默认这个标志位处于关闭状态。如果开启该标志位,则无论Git工作区对应的文件存在是否,或者是否被修改,Git都认为Git工作区该文件的版本是最新的、无变化的。Git通过配置文件 .git/info/spare-checkout 定义一个要检查的目录和或文件列表,当前Git的基于合并(git merge、git checkout)等命令能够根据该配置文件更新的index中文件的 skip-worktree 表示位,实现Git本地库文件的稀疏检出。

3.2 基于sparse checkout的CLI实现

我们先来看下在 git 中手动使用sparse checkout 操作的一般步骤 :

第一步,git 初始化
git init


第二步,设置remote仓库地址
git remote add orgin git@pkg.xxx.com:du-monorepo/XXXXX.git


第三步,初始化
git sparse-checkout init —cone


第四步,添加目录
git sparse-checkout add xxx/xx ...


第五步,检出
git pull orgin master

为了更方便地使用 sparse checkout 特性,我们开发了命令行工具,集合封装了按需检出相关的操作步骤。

3.2.1 cli 操作步骤

  1. 命令行执行 dx init
  2. 选择业务域
  3. 选择项目
  4. 检出目标项目

这里面所做的就是把稀疏检出的操作流程集合在了统一的命令行里面了,便于操作。本质上还是差不多上文demo里面所描述的内容。

图片

上图是前端大仓目前已经迁移的全部应用目录结构,可以看到不同的业务域下有不同的应用,比如客服的研发只关注客服的应用,商家的研发只关注商家的应用,通过上面的CLI操作步骤只需拉取对应目录下的代码就可以了,流程效果如下:

3.2.2 实现流程

图片

如上图所示,整个cli 是基于Pipline 的设计模式,Pipeline模式为管道模式,也称为流水线模式。通过预先设定好的一系列的阶段来处理输入的数据,每个阶段的输出即是下一个阶段的输入(Pipeline其实是使用了责任链模式的思想)。模型图如下:

图片

Pipeline设计模式的精髓在于它的可配置化,并且嵌套可拓展。在使用Pipeline时,如果想调换Valve的顺序,或者某些业务是不是用某个Valve,都是可以在外部配置的。这样就可以很灵活地适配多样化的业务,针对不同的业务配置不同的处理流程,扩展性、灵活性比较强。

3.3 基于sparse checkout的VSCode插件实现

3.3.1 大仓VsCode插件组成要素

大仓VsCode插件由【启动按钮】、主侧边栏【HELP】以及【Monorepo管理面板】三个要素组成

插件组成要素

3.3.2 插件实现原理

下面介绍下这三个元素以及元素间联动的代码实现。

代码结构

插件基本架构

启动按钮是在package.json里配置的,配置项为contributes.viewsContainers.viewsContainers,可以配置按钮的id,和icon

图片

当点击启动按钮后,就会激活插件,并执行activate的钩子函数,activate需要在名为extension.ts的文件中实现并导出:

图片

当插件被销毁时,会调用extension.ts导出的deactivate钩子函数,在这个钩子里可以进行一些资源的销毁。

其中activate执行了打开【Monorepo管理面板】的代码,这样插件在启动时就会自动打开面板。

该元素也是在package.json中配置的,配置项为:contributes.viewsWelcome,可以在content配置项中配置内容,绑定视图,并为按钮的点击事件绑定响应指令,这里绑定的指令是自定义指令:monorepo-init-extend.startClone。

图片

在extension.ts中注册自定义指令:monorepo-init-extend.startClone,以及执行该指令的响应。

图片

可以看到该指令将创建并打开【Monorepo管理面板】,从而实现主侧边栏【HELP】和【Monorepo管理面板】之间的联动效果。当用户点击【HELP】中的【请选择应用】时,就会执行该指令并打开【Monorepo管理面板】。

Monorepo管理面板是通过在VSCode中创建一个webviewPanel,并注入html模版来实现的。并且插件和webview之间可以通过postMessage api来进行通信。如在【Monorepo管理面板】中,当点击了【确定】按钮,就会通过postMessage将所选应用的信息通过postMessage发送给插件,插件将这些信息作为执行初始化或代码追加指令的参数,借助稀疏检出的命令行工具,执行相应的指令,即可按需拉取代码到本地。在插件执行完指令后,就会将相应的反馈信息通过postMessage发送给【Monorepo管理面板】。

Monorepo管理面板中树形结构的应用列表数据是通过前端统一配置中心获取的,支持动态可配置:

图片

4、技术挑战

基于Git的代码按需拉取虽然实现了,但是基于Git的文件系统是存在弊端的:

Git 仍需要读取不相关的文件或目录:这是因为 Git 文件系统使用的是内容寻址(content-addressable)的存储方式,即每个对象的名称都是由其内容(也就是文件的具体内容)计算出的 SHA-1 校验和。每个提交(commit)都是一个完整的目录树(tree)对象,其中包含了所有的文件和子目录。由此,在执行稀疏检出时,Git 需要读取整个目录树(包括不相关的文件和目录)以计算出其 SHA-1 校验和和对象名,然后根据用户的请求将需要的文件和目录进行检出。

由于 Git 文件系统是基于快照(snapshot)记录历史记录的,每个提交都包含整个代码库的目录树对象和其中所有文件的快照,那么如果使用稀疏检出机制来指定只检出部分文件或者目录,那么在检查或恢复历史版本的时候,只能访问和操作现在存在的文件或目录。因为那些之前被筛选过去的文件或目录现在不在当前检出的代码库中,所以无法直接访问它们的历史版本。

5、总结

本文主要对于git sparse checkout 的原理和在其之上的应用——大仓按需拉取cli和 vscode按需拉取插件展开讲解,实现了初版的基础能力,当然不可避免也存在着一些问题,当下的按需检出实现方案可能不是最终极的解决办法,但它却是最适合我们当下业务进程的方案。后面还会继续迭代和优化,同时关注git官方能力的改善以及我们自身对未来满足需求能力上的前置探索。


来源:得物技术内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯