Monorepo 項目管理Lerna

1、項目中遇到的問題

      最近在開發小程序的UI庫,組件拆分力度比較細,都是一個個的單獨的package包, 模塊的複用性和靈活性達到最大化,實操的過程當中,會遇到如下問題:node

     一、維護成本較高,任何的基層 repo 版本變動,將會引起一系列上層封裝版本變更git

     二、版本發佈npm包,代碼不夠規範,不少都不是發佈mastergithub

     三、一個包一個repo,每次須要找到對應的倉庫npm

     四、changelog 梳理異常折騰,有些基本上都沒有changelogjson

 

基於上面的問題,有沒有一種能解決咱們問題的技術呢?bootstrap

 

2、Monorepo 項目管理

    Monorepo 的全稱是 monolithic repository,即單體式倉庫,與之對應的是 Multirepo(multiple repository),這裏的「單」和「多」是指每一個倉庫中所管理的模塊數量。小程序

    Multirepo 是比較傳統的作法,即每個 package 都單獨用一個倉庫來進行管理。例如:Rollup, ...,上面遇到問題的也是採用的這種方式。babel

    Monorep 是把全部相關的 package 都放在一個倉庫裏進行管理,每一個 package 獨立發佈。例如:React, Angular, Babel, Jest, Umijs, Vue ...app

    Multirepo和Monorep優劣勢對好比下:工具

    

 

3、Monorepo 管理工具Lerna

Lerna 是一個管理多個 npm 模塊的工具,是 Babel 本身用來維護本身的 Monorepo 並開源出的一個項目。優化維護多包的工做流,解決多個包互相依賴,且發佈須要手動維護多個包的問題。

Lerna 如今已經被不少著名的項目組織使用,如:Babel, React, Vue, Angular, Ember, Meteor, Jest 。

一、lerna模式

在初始化一個項目以前咱們必需要清楚,lerna 對管理 monoRepo 有兩種模式

  • Fixed/Locked mode (default)
  • Independent mode

Fixed/Locked 模式: 官方默認推薦模式,當前 babel 的項目管理模式,在該模式下全部的 packages 都會遵循一個版本號,該版本號維護在 lerna.json 的 version 字段中,當須要版本發佈時 lerna publish 時,若是一個模塊和上一次 release 相比有過變動的話,會自動發佈一個新版本。

這種模式的問題在於:當有一個 major 變動的時候,全部 packages 都會都會有一個新的 major 版本。

維護團隊認爲:版本是一種很是 cheap 的東西,因此沒必要糾結。

Independent 模式: 在該模式下全部 packages 新版本的生成將會由開發者決定,lerna.json 的 version 字段也會隨之失效。這種模式的弊端很是明顯,開發者必需要很是清晰該發什麼版本,事實上在多人協做項目上很難作到這一點。

 二、如何使用lerna

    a、全局安裝lerna

npm i -g lerna

 

    b、初始化項目

mkdir lerna-repo && cd $_ npx lerna init

   初始目錄以下,接着進行開發

 

     c、創建 packages 的依賴關係

lerna bootstrap

     

    這個命令會安裝好全部 packages 的依賴,以及創建好 packages 相互依賴的軟鏈接

    正式流程爲:

  1. 安裝全部 package 的外部依賴.
  2. 對存在相互依賴的 package 建立軟鏈接.
  3. 在全部已經 bootstrapped 的 package 中執行 npm run prepublish.
  4. 在全部已經 bootstrapped 的 package 中執行 npm run prepare.

       固然咱們使用 --hoist 來把每一個 package 下的依賴包都提高到工程根目錄,來下降安裝以及管理的成本。

lerna bootstrap --hoist

 

   

   若是之前安裝了依賴,發生改動,能夠先清理一下安裝的依賴便可:

lerna clean

 

    d、發佈版本

lerna publish

   正式流程爲:

  1. 執行 lerna updated 來肯定哪些包須要被髮布.
  2. 若有必要會升級 lerna.json 的 version 字段。
  3. 對全部須要 update 的 package 進行版本的更新,並寫入他們的 package.json.
  4. 對全部須要 update 的 package 進行依賴申明 specified with a caret (^).
  5. 建立一個 git commit 和 tag
  6. 把包發佈至 npm

 

4、生成changelog

     因爲本項目後期須要對外,使用基於PR來生成changelog的lerna-changelog,項目建議使用cz-lerna-changelog 。

     一、安裝lerna-changelog

npm install lerna-changelog --save-dev

     

     二、修改 lerna.josn 須要新增相關 lerna-changelog 所須要的配置,此處參考babel配置

"changelog": { "repo": "binglingwy/lerna-test-new", "cacheDir": ".changelog", "labels": { "PR: Breaking Change :boom:": ":boom: Breaking Change", "PR: New Feature :rocket:": ":rocket: New Feature", "PR: Bug Fix :bug:": ":bug: Bug Fix", "PR: Docs :memo:": ":memo: Documentation", "PR: Internal :house:": ":house: Internal", "PR: Performance :running_woman:": ":running_woman: Performance" } },

     注意:labels 的 key 必須在 github 的倉庫內定義好

     三、設置令牌

export GITHUB_AUTH="..."

GITHUB_AUTH 的 token 字段能夠在github 申請 token 得到。

   四、建立個PR

        a、拉一個新的分支

        b、修改代碼並提交,提交記錄記得關聯issues,例如:

git commit -a -m "module-base: bug fixed, Close #1"

        c、推送代碼,並在github上建立PR

       注意:在建立 pr 時必定要選擇對應的 label ,label需提早在github建好,跟lerna.josn一致

        d、合併pr到主幹,切換到本地master,生成changelog

node_modules/.bin/lerna-changelog

      e、一旦 publish 後咱們即可以建立 release note,效果以下

     

 固然也能夠在生成文件CHANGELOG.md,在lerna.json中添加conventionalCommits配置:

"command": { "publish": { "allowBranch": "master", "conventionalCommits": true } }

配置後,當咱們執行lerna publish後會在項目根目錄以及每一個packages包下,生成CHANGELOG.md

注意: 只有符合約定commit提交才能正確生成CHANGELOG.md文件。

 

參考文章

Lerna 官網:https://github.com/lerna/lerna/blob/master/README.md

lerna-changelog:https://github.com/lerna/lerna-changelog

手摸手教你玩轉 Lerna: http://www.uedlinker.com/2018/08/17/lerna-trainning/

相關文章
相關標籤/搜索