Monorepo + lerna rush.js
Monorepo
monolithic repository 单体式仓库,与之对应的是Multirepo(Multiple repository)
Multirepo是比较传统的做法,即每个package都单独使用一个仓库来进行管理
Monorepo是吧所有相关的package都放到同一个仓库进行管理,每个package独立发布。如React、Babel、Vue
MultiRepo方式允许多元化发展(各项目可以有自己的构建工具、依赖管理策略、单元测试方法)。虽然拆分子仓库、拆分子npm包是进行项目隔离的天然方案,但当仓库内容出现关联时,调试需要npm link。调试方式比较低效。
MonoRepo方式则希望集中管理,减少项目间的差异带来的沟通成本。将业务代码聚合,开发者只需要关心业务代码,可以直接跨业务复用而不用关心复用方式,调试时所有的代码都在源码中,非常高效。
Lerna
A tool for managing javascript projects with multiple packages.
Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.
Lerna是一个管理多个npm模块的工具,优化维护多包的工作流,解决多个包相互依赖,且发布需要手动维护多个包的问题。
Lerna实践
1. 安装
npm i -g lerna // 推荐全局安装
2.初始化
lerna init
初始化的目录结构如下图所示:
其中package.json 和lerna.json内容如下所示:
### package.json
{"name": "root","private": true,"devDependencies": {"lerna": "^4.0.0"}
}### lerna.json
{"packages": ["packages/*"],"version": "0.0.0"
}
3. 在monorepo项目下新增一个package
lerna create @demo/cli
分别给相应的package增加依赖模块
lerna add chalk // 为所有的package增加chalk模块
lerna add semver --scope @demo/cli // 仅为@demo/cli 增加semver模块
4. 发布
lerna publish
5.安装依赖包,并清理依赖包,扁平化依赖包
在维护整个项目时,需要为每个package安装依赖包,但如果项目下多个package引用了相同的依赖包,在每个package的node_modules下都安装一遍该依赖包,会导致同一个依赖包安装多次,显得冗余,且每个package都要维护node_modules, 结构很不清爽。故可以使用lerna bootstrap --hoist
命令将每个package下的依赖包提升到工程根目录,来降低安装及管理成本。
lerna bootstrap --hoist
或lerna.json中配置{"packages": ["packages/*"],"version": "0.0.0","command": {"bootstrap": {"hoist": true}},
}
配置好后,对于之前依赖包已经被安装到各个package的node_modules下的情况,我们只需清理一下安装的依赖即可:
lerna clean
Rush.js
rush.js微软出品,专门为monorepo打造的项目管理工具 rushjs.io
rush.js主要解决了两个重要问题: phantom dependencies和doppelgangers(幽灵依赖)
phantom dependencies
没有在package.json中指定安装,却可以在项目中被引用的依赖
如: 项目project-A中引用了component-b, 组件component-b内引用了库lib-a,项目project-A内引用lib-a能生效么?
在npm3.0后是可以的。因为npm原有的树形结构,造成了依赖冗余和路径过深。npm3后开始扁平化,把原来不统计的依赖变成了同级依赖。这样我们就可以在项目中直接引用到了。
phantom dependencies的问题
- 版本依赖混乱
- 依赖丢失
常规解决思路:制定代码规范;使用代码检查工具来避免这种情况发生。
Doppelgangers
幽灵依赖:同一个依赖被安装多次,导致项目臃肿,打包变慢。
Rush.js的Symlink机制
Rush会将项目依赖全部都安装在repo更目录的common/temp下,然后提供symlink到各个项目中去引用。原本的项目中,依然会保持原有的node_modules结构
看一个例子:
Rush保证只会在项目的node_modules中保留package.json中声明过的依赖的symlink,这样就解决了phantom dependencies
rush会将所有的依赖都安装在一个地方,对于不同版本的同一个依赖,rush会同时安装所有的依赖版本,并提供symlink供项目使用,这样就解决了doppelgangers.
另外,rush会对依赖的版本(semver)进行智能判断,防止重复安装依赖包。例如,两个项目同时依赖了一个第三方库,第一个项目依赖的是^1.2.0。另一个依赖的版本号是1.5.0。rush安装依赖时,只会安装1.5.0.
Rush.js的简单使用
Rush.json
Rush build
Rush update
Rush change
Rush publish
Rush vs Lerna
Rush:
- 规范性强,配置细分,各司其职
- 消除phantom,可控性更强
- 消除doppelgangers,减少依赖冗余更彻底
- 可以实现更智能的版本选择
- 支持npm/yarn/pnpm,其中pnpm是lerna不支持的
- 对change log的更新支持更好,lerna则需要扩展
Lerna:
- 当前使用最广,经过各大型项目检验
- 配置简单,可扩展性好
- 版本号管理有成熟的fixed/independent两种模式,Rush的version Policy目前还是实验性功能
Monorepo + lerna rush.js相关推荐
- 你所需要了解的关于 Monorepo 的一切
你所需要了解的关于 Monorepo 的一切 Monorepo 1. 前言 2. Monorepo 2.1 它是什么? 2.2 为什么要使用 Monorepo 2.2.1 Polyrepo 2.2.2 ...
- Lerna 运行流程剖析
大家好,我是若川.持续组织了6个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列& ...
- monorepo工作流基础之changesets打开与进阶(Speeches)
文章目录 背景 先置理论 聊聊工作流 workflow 一致性问题 开源项目的工作流解法 github bot github actions 实践赋能 安装 changesets 配置 changes ...
- 8102年底如何开发和维护一个npm项目
开发流程 初始化 首先在npm官网进行注册登录 运行npm init,可以通过命令行进行一些初始化的设置,如果想快速进行设置,可以运行npm init -y,会在项目的根目录生成一个package.j ...
- 哔哩哔哩 Web 首页重构——回首2021
本期作者 刘磊 高能链开放平台资深前端开发工程师 01 前言 在 2021 年时我们通过数据分析发现:在电脑端有越来越多用户的电脑屏幕切换成了大屏,现有 B 站的网页设计风格已经难以在宽屏设备上高效率 ...
- 如何构建一个在线绘图工具:Feakin 是如何设计与构建的?
高中,读过几本 3D 图形编程相关的书.怎么说呢,自那以后,图形学相关的东西,都不在我的兴趣范围里了.直到最近,我重新燃起了一点兴趣: 架构治理工具 ArchGuard 依赖于「图即代码」,用于生成架 ...
- 第 5 届 FEDAY 前端大会的完整 PPT 内容已出炉-站在大牛的肩膀上学习
前言 有一种快速学习的方法是:站在大牛的肩膀上学习. 即使快能为祖国母亲庆生了,但也阻挡不住大家博已广学的心. 一年一度的第 5 届 FEDAY (前端大会) 圆满结束,来自全球.有极丰富经验和技能的 ...
- 基于 Lerna 管理 packages 的 Monorepo 项目最佳实践
对于维护过多个package的同学来说,都会遇到一个选择题,这些package是放在一个仓库里维护还是放在多个仓库里单独维护,本文通过一个示例讲述了如何基于Lerna管理多个package,并和其它工 ...
- 现代前端工程化-基于 Monorepo 的 lerna 模块(从原理到实战)
本文你能学到什么? 看完本文后希望可以检查一下图中的内容是否都掌握了,文中的例子最好实际操作一下,下面开始正文. 本文是前端工程化系列中的一篇,回不断更新,下篇更新内容可看文末的下期预告!宗旨:工程化 ...
- 使用lerna构建monorepo
使用lerna构建monorepo monorepo是什么? monorepo就是在一个git repository里面管理多个packages或者项目 在实际开发使用中,在哪些场景下可能你会想要使用 ...
最新文章
- 今天来说一下我的SAMC
- IOS使用通知回调方法
- python自动化功能测试_python、selenium自动化功能测试
- 牛客练习赛89E-牛牛小数点【数论】
- Oracle 20c 新特性:表空间缺省加密算法 TABLESPACE_ENCRYPTION_DEFAULT_ALGORITHM
- QT5::总结篇 QWidget
- 旅游网站进行邮件订阅的七大步骤讲解
- 博弈指什么棋_格局:什么是格局?(胜读十年书)
- Extjs ComboBox常用的配置
- html超链接下划线改虚线_怎么把下划线变成虚线
- 苹果和华为如何隔空传照片
- html的图片动态效果,用CSS3实现图片动态效果
- 多目标优化系列(六)SPEA
- 手机网站(wap)广告展示一般都有哪些表现形式?
- NIO核心设计与原理
- c语言编程序按下列公式计算e的值,编写程序,利用公式 ,求出e的近似值
- 清理docker的overlay2日志释放磁盘空间
- random.RandomState()用处
- G - Ugly Numbers
- [Outlook] outlook如何实现自动CC和BCC邮件发送