rush.js微软出品,专门为monorepo打造的项目管理工具。
rush是为大型团队准备的,它可以给你提供一个仓库下维护多个项目的构建和发布方案。
一、先了解下Monorepo
Monorepo概念
一种项目管理方式:一个git仓库下管理多个项目,适用于大型团队,框架开发,库开发等。
优点
- 统一技术栈
- 降低团队成员之间的backup成本
2. 提升效率
- 每一个人都可以改动任意部分的代码,改动效果实时呈现,调试方便
- 可以在业务开发中,灵活地将代码抽出作为公共模块
- 省去了在多个repo情况下,给团队新成员开通repo权限的时间
痛点
- 安装构建时间长
- 扁平化包管理的弊端会被放大(后面会具体说)
- 发布管理和版本控制有难度
- 改动影响面大,对测试覆盖有要求
二、Rushjs
微软出品,官方文档:https://rushjs.io
优点:
- 多项目并存下,Symlink实现依赖只需一套,无重复安装
- 提供项目间的自动link(解决phantom dependencies 和 doppelgangers)
- 多线程构建多项目,加快构建速度
- 自动检测有改动的项目,按配置产出版本号和changelog
Rush vs Lerna
Rush:
- 规范性强,配置细分,各司其职
- 消除phantom,可控性更强
- 消除doppelgangers,减少依赖冗余更彻底
- 可以实现更智能的版本选择
- 支持npm/yarn/pnpm, 其中pnpm是Lerna不支持的
- 对change log的更新支持更好,Lerna则需要扩展
Lerna
- 当前使用最广,经过各大型项目检验
- 配置简单,可扩展性好
- 版本号管理有成熟的fixed/independent两种模式,Rush的Version Policy目前还是实验性功能
bolt与Lerna非常相似,都是在workspace的概念下通过少量的配置抽出公有依赖。
结论
- rush的使用时以monorepo风格为前提的
- 通过symlink实现减少重复依赖和消除phantom、doppelgangers
- 提供了专业的改动和发布管理的方案
- 接入方便简洁
- 对比lerna更专业,但优势不明显,如果没有上面rush优势的需求,更建议使用lerna
Rush解决痛点
Rush解决了两个重要的问题:phantom dependencies 和 doppelgangers。
phantom dependencies问题
没有在package.json里指定安装,却可以在项目中被引用的依赖。(npm3.0版本后),造成依赖版本混乱、 依赖丢失等问题。
常规解决思路:制定代码规范;使用代码检查工具来避免这种情况发生。
先了解下Symlink(符号链接):
Rush一次性安装全部原始依赖在Root下的common/temp目录下,从该目录下提供Symlink给单个项目引用。Symlink只是提供指针,这样保证了对于依赖本身的更新会实时展现在项目中,且依然保有原有各项目的node_modules的结构
Rush保证只会在项目的node_modules中保留package.json中声明过的依赖的Symlink, 从而解决了phantom dependencies问题。
doppelgangers问题
同一个依赖被多次安装,导致项目臃肿,打包变慢。
Rush会将所有的依赖都安装在一个地方,对于不同版本的同一个依赖,rush会同时安装所有的依赖版本,并且提供symlink供项目使用,这样,自然就解决了doppelgangers。
另外,rush会对依赖的版本(SemVer)进行智能判断,防止重复安装依赖包。例如,两个项目同时依赖了一个第三方库,第一个项目依赖的是:^1.2.0,另一个依赖的版本号是:1.5.0。rush安装依赖时,只会安装1.5.0。
管理项目
1、搭建rush项目初始目录
apps文件夹下存放各个子项目
libs文件夹下存放各个公共组件包及第三方库
发布方案
- rush.json中可配置区分需要发布和不必要发布的包
- 根据上面配置,rush publish自动升级版本号并发布有过更新的包,这两个也可分开执行
- rush change帮助产出简介规范的change log,没有change log的改动会导致CI失败
三、尝试Rush项目
拉取代码
mkdir rush-sample
cd rush-sample
git clone https://github.com/WGinit/rushjs-demo.git
目录结构
│ README.md
│ rush.json // 配置文件
| .gitattributes
| .travis.yml
| .gitignore
│
└───apps // 子项目文件夹
│ │ project1 // 项目1文件夹
│ │ project2 // 项目2文件夹
└───common // rush init 生成的rush 配置文件
│ │ temp // 所有的项目包管理
│ │ ...
└───libs // 公共组件或给第三方包文件夹
│ util // 第三方工具文件
启动运行
需提前安装rush 及 pnpm
yarn add @microsoft/rush -g // 全局安装rush
yarn add pnpm -g // 全局安装pnpm
安装依赖
rush update --purge // 更新链接
rush install
项目打包
rush build // 打包所有的项目
rush build -t project1 // 只打包project1项目
项目发布
rush publish // 发布对rush.json 文件中配置了shouldPublish的包