Flutter 正在切换成 Monorepo 和支持 workspaces

其实关于 Monorepo 和 workspaces 相关内容在之前《Dart 3.5 发布,全新 Dart Roadmap Update》 和 《Flutter 之 ftcon24usa 大会,创始人分享 Flutter 十年发展史》 就有简单提到过,而目前来说刚好看到 flaux 这个新进展,所以就再展开来聊聊目前 Flutter 里进行中的 Monorepo 和 workspaces。

其实如果你不跑引擎,不提 PR 或者不看源码,那 monorepo 调整对你来说应该没什么正向影响。

monorepo

可能有人还没听说过 monorepo,先介绍下 monorepo(mono repository) ,它是一种项目代码的管理方式,就是将多个项目存储在一个 repo 中,在 monorepo 里多个项目的所有代码都存储在单个仓库里,这个集中式存储库包含 repo 中的所有组件、库和内部依赖项等。

monorepos 也不是什么新概念,很早之前 Google、Meta、Microsoft、 Twitter 等公司都在大规模使用 monorepos ,比如 ReactVscodeBabel 都使用了 monorepo,如下图所示可以看出来他们在形式和结果的区别:

更多可见原文:https://blog.bytebytego.com/p/ep62-why-does-google-use-monorepo

使用 monorepo 的最主要原因之一是简化代码管理,由于所有代码都存储在单个存储库中,因此可以更轻松地跟踪更改、保持版本一致性等,例如 Meta 的工程师曾就表示过:

Meta 的 monorepo 包含公司的大部分代码,可以轻松访问所有代码对开发人员的效率非常重要,工程师可以更深入地了解其依赖关系,调试整个堆栈中的问题,并实施功能或错误修复,所有这些都触手可及······

······版本控制是使用多个存储库时最复杂的问题之一,每个存储库都是独立的,团队可以自由决定要采用的依赖项版本,但是由于每个存储库都按照自己的节奏发展,这些不一致会导致项目可能包含同一依赖项的多个版本,从而导致后续版本控制的各种冲突·····

https://www.growingdev.net/p/what-it-is-like-to-work-in-metas

所以 monorepo 不仅仅只是将所有源代码“紧密放在一起”,更是确保存储库中各个库和应用相互兼容的重要工具:

简单点说人话就是:将现在 Flutter 项目下的 flutter/engineflutter/buildrootflutter/flutter 这三个存储库合并到单个 flutter/flutter 存储库中

采用 monorepo 对于目前 Flutter 来说有着许多好处,例如更方便的 CI 和更容易协作,同时提高代码共享的能力,例如在现在的 flutter/flutter 项目下,由于 flutter/flutter flutter/engine 是两个独立项目,所以经常可以看到一堆”无意义“的 Roll Engine PR 的记录存在:

“Roll Flutter Engine from····” 主要是为了更改 framework 引用的 engine 的版本,每次 engine 有新的提交的时候,都会在 framework 自动创建一个 PR,更新 engine ,当所有测试通过时,PR 就会自动合并。

而如果使用 monorepo , flutter/flutter flutter/engine 将不再是相互隔离的 repo ,在 CI 和版本管理上都会更轻便可控,例如一开始文章提到的 flutter/flaux ,就是目前 Flutter 正在测试合并流程的项目,在最终合并到主flutter/flutter 之前验证 monorepo 的仓库。

也就是 flutter/engine 这个 repo 最终会在未来的某个时间点被 Archive ,虽然这和 Flutter 以前解释说不适用 monorepo 的原因相违背, 但是这个阶段来看,Flutter 还是需要选择 monorepo。

对于 monorepo 而已,所有依赖都是一个来源,所以意味着不存在版本冲突和依赖地狱,同时 monorepo 还支持原子提交,在大规模重构里开发人员可以在一次提交中更新多个包或项目。

其实目前 pub 上很多项目都在使用类似 monorepo 的结构,例如 riverpod 、cfug/dio 、ubuntu/app-center 、Flame-Engine/Flame 等项目都在使用 melos 做 monorepos 管理,而 Flutter 这次也是通过自定义对应的 CI 基础能力来更新以支持合并后的 repo 构建,也就是 Flutter 针对 monorepo 结构自定义了一套新的 CI 系统,事实上 monorepo 核心之一,就是在于 CI 的搭建还有项目结构分层的处理上

更多可见:https://melos.invertase.dev/~melos-latest/#projects-using-melos 、https://github.com/orgs/flutter/projects/182/

总结

总结起来,Flutter 迁移到 monorepo 的好处在于:

  • 提交原子性:engine、framework 和 buildroot 的变更可以一起提交,更好管理

  • 减少依赖 :可以减少大量内部版本依赖和冲突问题,大规模减少类似 Roll 类型的历史提交等

  • 简化 PR:用户可以更直观和方便提交 PR,包括这个 PR 需要从 engine 到 framework 多方调整的时候

  • 更方便测试: engine 和 framework 可以在同套 CI 下测试调整

当然 monorepo 也带来了新的问题,例如一个 repo 下多个 Dart 项目的解析问题,这就不得不说下面的 workspaces 概念。

workspaces

在 Dart 3.5 的时候,Dart Roadmap 就提出了 pub workspaces 概念,核心就是在 monorepo 中实现多个相邻包的共享解析,比如「共享解析」可以解决类似编辑器中的 Analyzer 占用空间过大问题,因为它可以减少单独的上下文 context。

analysis_options.yaml 下的大量规则引入也会增加内存上涨,事实上 Dart Analyzer 的上下文数量一直是内存消耗大户。

在 dart#53874 提到过,由于 monorepo 结构化的原因,Analyzer 在工作的时候最终会为每个包及其所有依赖项加载了多个重复的 analysis contexts,从而导致 monorepo 里每个包 analysis 时在内存中生成了多个副本,最终出现内存占用过大问题:

而解决方案就是在这些 repo 中为每个依赖项创建一个共享解决方案,也就是这里提到的 pub workspaces ,通过 workspaces ,项目在 monorepo 中可以实现多个相邻包的共享解析,通过共享 Analyzer 等工具在分析每个包之间共享上下文,从而节省大量内存。

也就是 workspaces 可以让 monorepo 创建共享版本来优化依赖项解析速度和内存。

例如,你可以通过 workspace 关键字启用 workspaces 并引入对应的 packages 结构:

name: workspace
environment:sdk: ^3.5.0
workspace:- packages/package_a- packages/package_b

然后在 packages/package_a/pubspec.yamlpackages/package_b/pubspec.yaml 添加一行 resolution: workspace

name: package_a
environment:sdk: 3.5.0
resolution: workspacedependencies:# You can depend on packages inside the workspace:package_b: ^1.2.4 # This version constraint will be checked against the local version
dev_dependencies:test: ^1.0.0

此时你的项目就已经处于 workspace 的工作模式下,而 workspaces 主要是支持 workspaces 下 monorepo 的包之间的共享解析,例如在仓库中的任意位置运行 flutter pub get ,项目会将产生一个共享解析,具体表现为:只会在 root pubspec.yaml 同级目录生成 一个 root pubspec.lock

另外,通过 dart pub deps 也可以更清晰看到整个 workspace 的依赖关系,也可以更好管理和同步依赖,结合 monorepo 结构或者 melos 等工具的能力,会让整个项目更直观可控:

最后

可以看到 monorepo 和 workspaces 属于相辅相成的存在,而 monorepo 也不是单纯就是把东西放到一个 repo ,更多涉及项目结构的分层,包的细化还有最关键的 CI 工具支持等,同时 monorepo 也可以更好管理所有项目的依赖关系,甚至支持增量构建等等。

总的来说 monorepo 并不是什么新鲜东西,只是到了这个阶段 Flutter 所需要做的一个调整,之前采用 multi repo 是规划里把多个 repo 当作独立产品,而现在是作为一个整体项目来管理的情况下,自然选择 monorepo 更合适。

参考资料

  • https://github.com/dart-lang/sdk/issues/53875

  • https://github.com/dart-lang/pub-dev/pull/7762

  • https://github.com/dart-lang/pub/issues/4391

  • https://github.com/dart-lang/pub/issues/4127

  • https://docs.google.com/document/d/1UEEAGdWIgVf0X7o8WPQCPmL4LSzaGCfJTM0pURoDLfE/edit?resourcekey=0-c5CMaOoc_pg3ZwJKMAM0og&tab=t.0

  • https://github.com/flutter/engine/blob/main/pubspec.yaml

  • https://github.com/orgs/flutter/projects/182

  • https://github.com/flutter/flaux

  • https://github.com/flutter/cocoon

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

expand,None索引,permute【pytorch】

torch.expand 输入必须是一个向量或等价形式,扩展的最后一个维度与输入大小一致 当输入形状为(1,1,1,1,1,……,3)_4时。 expand的最后一位输入向量的元素个数(长度)(3&…

GEE | 对Landsat 8 影像进行缨帽变换

基于Landsat 8 影像的缨帽变换 var roi ee.FeatureCollection(users/yongweicao11/Dongguan2022); // Landsat 8 的缨帽变换系数矩阵var Landsat8TC ee.Array([[0.3029, 0.2786 , 0.4733, 0.5599, 0.5082, 0.1872],[-0.2941, -0.2435, -0.5424, 0.7276, 0.0713, -0.1608],[0.…

Obsidian的Vim插件设置配置全流程 -- 脱离鼠标拥抱Vim神教

Obsidian的Vim插件设置配置全流程 -- 脱离鼠标拥抱Vim神教 参考文章引言1. vim 及 vimrc 介绍2. 开启 Obsidian 内置的 Vim3. vimrc 插件的获取和安装4. vimrc 插件的设置5. vimrc 配置文件的设置附件 参考文章 vim 常见操作 Obsidian插件安装教程 引言 vim 很好用&#xff…

6.《双指针篇》---⑥和为S的两个数字(中等但简单)(牛客)

题目传送门 方法一:暴力解法。双循环 方法二:双指针(推荐) 1.定义一个顺序表,定义左右双指针 2.while循环。判断array[left] array[right] 的值。 3.若等于则将这两个值加入数组。并break 4.若大于则right-- 5.若小于…

LeetCode994. 腐烂的橘子(2024秋季每日一题 54)

在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一: 值 0 代表空单元格;值 1 代表新鲜橘子;值 2 代表腐烂的橘子。 每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直到单元格中没有…

【51蛋骗鸡一个独立按键控制流水灯开关】2022-1-18

缘由一个独立按键控制流水灯开关-编程语言-CSDN问答 #include<reg52.h>//头文件 sbit k1P3^7;// void main() //主函数 {unsigned char sj0, ls0;unsigned int ys0;P00;/*P0255;*/while(1){if(!k1&&!sj){if(!ls){ls1;/*P00;*/}else ls0;while(!k1);}if(…

shodan(五)连接Mongodb数据库Jenkinsorg、net、查看waf命令

声明&#xff1a;学习素材来自b站up【泷羽Sec】&#xff0c;侵删&#xff0c;若阅读过程中有相关方面的不足&#xff0c;还请指正&#xff0c;本文只做相关技术分享,切莫从事违法等相关行为&#xff0c;本人一律不承担一切后果 引言&#xff1a; 1.Shodan 是一个专门用于搜索连…

lvgl白屏问题(LCD长时间白屏)和优化lvgl

开机白屏时间过长 -- 这里我们不考虑是lvgl占的内存太大的问题&#xff0c;这里考虑的是为什么lcd屏幕启动后会有长时间的白屏。 首先我们要了解lvgl的相关操作&#xff0c;主要集中在一个函数中。只有程序执行到了这个函数&#xff0c;lvgl的屏幕才会显现出来 总结来说就是l…

公网ip和弹性公网ip有什么区别?哪个更好

公网ip和弹性公网ip有什么区别&#xff1f;公网IP和弹性公网IP都是用于互联网通信的IP地址&#xff0c;但它们在灵活性、成本和管理方式上有所不同。公网IP是直接分配给设备的静态IP地址&#xff0c;适用于需要固定外部访问的场景&#xff0c;但可能面临安全风险和设置复杂性。…

DevOps-课堂笔记

各种 aaS 类比于计算机网络的 OSI 参考模型&#xff0c;一个软件应用项目需要不同的支撑层&#xff0c;例如从下至上大概需要&#xff1a; 硬件层面的服务器针对硬件做弹性分配的虚拟化机制&#xff0c;例如虚拟机在虚拟化环境内运行的 OS支撑软件应用的中间件&#xff0c;例…

游戏想实习但定位不清的问题

国内的游戏大厂包括腾讯、网易、盛趣游戏、西山居、米哈游、莉莉丝、完美世界、游族、心动、叠纸、三七、TapTap、Tap4fun、字节跳动、哔哩哔哩、funplus、巨人、IGG、沐瞳等。而国外的游戏大厂则有育碧、EA、拳头、supercell、暴雪、R星、卡普空、任天堂、波兰蠢驴等。 一般来…

Dubbo使用Nacos作为注册中心

使用 Nacos 作为注册中心实现自动服务发现 本示例演示 Nacos 作为注册中心实现自动服务发现&#xff0c;示例基于 Spring Boot 应用展开&#xff0c;可在此查看 完整示例代码 1 基本配置 1.1 增加依赖 增加 dubbo、nacos-client 依赖&#xff1a; <dependencies><…

css基础

文章目录 基础 基础 配置网页的cion图标 在网站根目录下放置 favicon.ico 文件&#xff0c;浏览器在加载网页的时候会自动加载的。这个图片只能是 ico 格式&#xff0c;并且只能叫这个名字 如: css项目的根目录下 刷新网站没有生效&#xff0c;需要强制刷新&#xff0c;shif…

Lucene的Directory的详细使用与性能测试(6)

文章目录 第6章 Directory6.1 Directory介绍6.1.1 FSDirectory1&#xff09;SimpleFSDirectory&#xff1a;2&#xff09;NIOFSDirectory&#xff1a;3&#xff09;MMapDirectory&#xff1a;4&#xff09;FSDirectory子类对比 6.2.2 RAMDirectory 6.2 Directory性能测试环境搭…

HTML+javaScript+CSS

文章目录 HTMLjavaScriptCSS属性区块表单层叠样式表选择器常用属性盒子模型相关属性浮动float定位&#xff08;position&#xff09; JS操作节点事件点击事件onclick()聚焦事件、失焦事件鼠标移入移出事件 定时任务延迟定时任务重复定时任务 判断哪个单选框被选中设置按钮失效冒…

Linux系统每日定时备份mysql数据

一、创建存储脚本的文件夹 创建文件夹&#xff0c;我的脚本放在/root/dbback/mysql mkdir ... cd /root/dbback/mysql 二、编写脚本 vi backup_mysql.sh 复制脚本内容 DB_USER"填写用户名" DB_PASSWORD"填写密码" DB_NAME"数据库名称" # …

【计算机网络】零碎知识点(易忘 / 易错)总结回顾

一、计算机网络的发展背景 1、网络的定义 网络是指将多个计算机或设备通过通信线路、传输协议和网络设备连接起来&#xff0c;形成一个相互通信和共享资源的系统。 2、局域网 LAN 相对于广域网 WAN 而言&#xff0c;局域网 LAN 主要是指在相对较小的范围内的计算机互联网络 …

数据同步的技术支持有哪些?

数据同步是指将不同系统、设备或应用程序中的数据进行实时或定期的更新、复制和传输的过程。通过数据同步&#xff0c;可以确保数据的一致性和可用性&#xff0c;避免数据的丢失或错误。常见的数据同步技术包括推式同步、拉式同步、ETL工具同步等。 一、推式数据同步 定义&…

Kaggle入门指南(Kaggle竞赛)

https://www.kaggle.com/ 文章目录 Kaggle 入门指南1. Kaggle 的功能概述1.1 竞赛1.2 数据集1.3 学习与教程1.4 社区 2. 注册与设置2.1 创建账户2.2 完善个人资料 3. 探索数据集3.1 查找数据集3.2 下载数据集示例代码&#xff1a;加载数据集 3.3 数据预处理示例代码&#xff1a…

桌面终端安全管理软件有哪些?5大主流的终端安全防护系统盘点,2024人气爆款推荐!

“守一而制万机&#xff0c;安内方可攘外”。在纷繁复杂的数字化世界中&#xff0c;只有确保内部系统的安全稳定&#xff0c;才能有效地抵御外部威胁。 其中&#xff0c;桌面终端作为信息交换和存储的重要节点&#xff0c;在安全管理方面显得尤为重要。 本文将为您盘点2024年五…