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內容如下所示:
3. 在monorepo項目下新增一個package
lerna create @demo/cli分別給相應的package增加依賴模塊
lerna add chalk // 為所有的package增加chalk模塊 lerna add semver --scope @demo/cli // 僅為@demo/cli 增加semver模塊4. 發布
lerna publish5.安裝依賴包,并清理依賴包,扁平化依賴包
在維護整個項目時,需要為每個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 cleanRush.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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编写Java程序,使用抽象类和抽象方法构
- 下一篇: U盘做系统时如何设置USB为第一启动盘