使用Lerna、Yarn管理Monorepo專案

2021-04-08 21:03:16

平常的專案由於依賴包不多基本都是一個依賴使用一個倉庫,但如果開發較為大型的專案,或者專案元件抽出的比較細,這種場景下一個依賴使用一個倉庫就加大了管理難度。Monorepo就是解決這樣場景而產生的,像是BabelVue3React都是使用這樣的管理方式。

Monorepo優劣勢

優勢

1、方便程式碼管理

依賴資料一旦多起來時,眾多的專案倉庫會使得修改關聯功能需要在幾個倉庫間切換。

依賴分散,管理上需要更多的精力,如果缺乏持續性管理,可能導致功能模組定義偏差。或是各個專案內容易存在過多功能相同的程式碼,也不方便提取複用。

如果檔案整理不全,有可能出現交接時導致倉庫遺失的情況。

2、分支構建統一

由於模組數眾多,各個模組的版本管理與模組分支對應也會越來越複雜。

由於模組數眾多,可能因為某個小模組的程式碼修改而未被注意到,導致不容易檢測。

3、方便複用與測試

所有依賴同在一個倉庫,方便複用、修改、測試。

劣勢

1、不利於許可權管理

由於所有程式碼都放在同一個倉庫,不利於做許可權管理,對於專案不熟悉的人容易修改到其他地方程式碼。

2、倉庫體積大

由於所有程式碼同放一個倉庫,可能有時候修改一個小功能需要拉下完整的倉庫。

如果是引入臨時開發者或是新人,不利於快速上手專案。

Lerna、Yarn與Monorepo關係

文章標題提到YarnLerna這是比較主流的Monorepo倉庫管理工具。

YarnFacebook為了解決NPM使用中諸多問題而創立的包管理工具,其中自帶了workspaces功能,可以通過設定根目錄的package.json來實現Monorepo倉庫管理。但是Yarn只解決了包管理的問題,對於包內的依賴、發版依然麻煩,此時就需要另一個工具Lerna

Lerna就是Babel專案在包管理時發現處理依賴等諸多不便,因此產生的管理工具。

Monorepo應用

安裝

安裝lernayarn

npm i -g lerna yarn

初始化專案

進入目錄,執行初始化命令

lerna init

可以使用--independent引數來建立independent模式的專案。

lerna有兩種版本號管理模式:fixedindependentfixed是預設模式,在這模式下所有包都使用lerna.json裡的version欄位值。independent模式是每個包使用獨立的版本號。

執行後在專案下會多出package.jsonlerna.json檔案和packages目錄。

packages目錄就是存放多個專案的目錄,在組態檔中可以修改。

package.json可以新增一些設定,

"private": true, // 私有,主工程不會被髮布
"workspaces": [ // 宣告子package專案路徑,yarn會讀取使用
    "packages/*"
]

lerna.json可以設定一些引數:

  • version: 版本號
  • npmClient: 使用指定的包管理器,值為yarnnpm。預設為npm
  • command.publish.ignoreChanges: 值為陣列,設定忽略變更的檔案或目錄
  • command.publish.message: 自定義釋出新版的提交資訊,參看@lerna/version (翻譯版@lerna/version
  • command.publish.registry: 設定釋出的自定義倉庫地址
  • command.bootstrap.ignore: 值為陣列,lerna bootstrap命令忽略的包
  • command.bootstrap.npmClientArgs: 值為陣列,lerna bootstrap命令時,會將此變數值傳遞給npm install
  • command.bootstrap.scope: 值為陣列,lerna bootstrap命令針對哪些包執行
  • packages: 值為陣列,所有子包的路徑

依賴管理

安裝依賴

只要在專案主目錄下執行

yarn install

yarn會自動讀取workspace設定,就能自動安裝、處理、軟連結各個子包的依賴,統一放在根目錄下。

也可以使用lerna的安裝命令

lerna bootstrap

但可能不如yarn的包管理機制好用,可以看這篇文章《Lerna的依賴管理及hoisting淺析》

增刪依賴

主專案新增依賴

yarn add -W -D [packageName]
-W 是指定在專案根目錄執行命令

刪除公共依賴

yarn remove -W -D [packageName]

給所有子專案增刪依賴

yarn workspaces add [packageName]
yarn workspaces remove [packageName]

給某個專案增刪依賴

yarn workspace [packageNameA] add [packageNameB] // packageNameA是指定安裝依賴的包名,packageNameB是公共的包名或者專案內的包名
yarn workspace [packageName] remove [packageName]

當專案依賴凌亂的時候,可以使用命令清理依賴

lerna clean

其餘還有一些命令

// 如果 package.json 中設定了 "private": true 的不會展示

lerna ls // 列出倉庫中包資訊
lerna changed // 檢視專案變動
lerna exec // 執行命令
yarn workspaces info // 檢視專案內資訊
構建釋出

使用lerna run命令構建專案

lerna run build // 會執行子包中build命令構建
--stream,新增此引數會輸出執行時的資訊
--sort,新增此引數包與包之前有互相依賴的會先進行排序,然後按順序一個個構建
--scop [packageName],新增此引數可以指定某個包執行命令

lerna同時提供了快速版本釋出功能

lerna version

執行後會自動識別修改的包,然後修改版本號。如果當前程式碼有未提交的修改記錄則禁止更新。

使用帶--conventional-commits引數命令,可以支援Git的提交記錄來自動更新版本號

lerna version --conventional-commits

詳細的引數檔案可以看@lerna/version或者@lerna/version翻譯

之後可以用lerna publish釋出新包

lerna publish from-git

詳細的引數檔案可以看@lerna/publish或者@lerna/publish翻譯