您好,登錄后才能下訂單哦!
本文首發于 vivo互聯網技術
作者:孔垂亮
對于維護過多個package的同學來說,都會遇到一個選擇題,這些package是放在一個倉庫里維護還是放在多個倉庫里單獨維護,本文通過一個示例講述了如何基于Lerna管理多個package,并和其它工具整合,打造高效、完美的工作流,最終形成一個最佳實踐
最近在工作中接觸到一個項目,這個項目是維護一套 CLI,發到 npm 上供開發者使用。先看一張圖:
項目倉庫中的根目錄上就三個子模塊的文件夾,分別對應三個 package,在熟悉了構建和發布流程后,有點傻了。工作流程如圖中所示:
使用webpack、babel和uglifyjs把 pkg-a 的 src 編譯到 dist
使用webpack、babel和uglifyjs把 pkg-b 的 src 編譯到 dist
使用webpack、babel和uglifyjs把 pkg-main 的 src 編譯到 dist
痛點
不好調試。因為最終的包是通過文件拷貝的方式組裝到一起的,并且都是壓縮過的,無法組建一個自上到下的調試流程(實際工作中只能加log,然后重新把包編譯組裝一遍看效果)
包的依賴關系不清晰。pkg-a、pkg-b索性沒有版本管理,更像是源碼級別的,但邏輯又比較獨立。pkg-main中的package.json最終會拷貝到 pkg-npm 中,但又依賴pkg-a、pkg-b中的某些包,所以要把pkg-a、pkg-b中的依賴合并到pkg-main中。pkg-main和pkg-npm的package.json耦合在一起,導致一些本來是工程的開發依賴也會發布到 npm 上去,變成pkg-npm 的依賴包。
依賴的包冗余。可以看到,pkg-a、pkg-b、pkg-main要分別編譯,都依賴了babel、webpack等,要分別 cd 到各個目錄安裝依賴。
發布需要手動修改版本號。?因為最終只發布了一個包,但實際邏輯要求這個包即要全局安裝又要本地安裝,業務沒有拆開,導致要安裝兩遍。耦合一起,即便使用 npm link 也會導致調試困難,
整個項目像是一個沒有被管理起來的 Monorepo。那什么又是 Monorepo 呢?
Monorepo 的全稱是 monolithic repository,即單體式倉庫,與之對應的是 Multirepo(multiple repository),這里的“單”和“多”是指每個倉庫中所管理的模塊數量。
Multirepo 是比較傳統的做法,即每一個 package 都單獨用一個倉庫來進行管理。例如:Rollup, ...
Monorep 是把所有相關的 package 都放在一個倉庫里進行管理,每個 package 獨立發布。例如:React, Angular, Babel, Jest, Umijs, Vue ...
一圖勝千言:
當然到底哪一種管理方式更好,仁者見仁,智者見智。前者允許多元化發展(各項目可以有自己的構建工具、依賴管理策略、單元測試方法),后者希望集中管理,減少項目間的差異帶來的溝通成本。
雖然拆分子倉庫、拆分子 npm 包是進行項目隔離的天然方案,但當倉庫內容出現關聯時,沒有任何一種調試方式比源碼放在一起更高效。
結合我們項目的實際場景和業務需要,天然的 MonoRepo ! 因為工程化的最終目的是讓業務開發可以 100% 聚焦在業務邏輯上,那么這不僅僅是腳手架、框架需要從自動化、設計上解決的問題,這涉及到倉庫管理的設計。
一個理想的開發環境可以抽象成這樣:
“只關心業務代碼,可以直接跨業務復用而不關心復用方式,調試時所有代碼都在源碼中。”
在前端開發環境中,多 Git Repo,多 npm 則是這個理想的阻力,它們導致復用要關心版本號,調試需要 npm link。而這些是 MonoRepo 最大的優勢。
上圖中提到的利用相關工具就是今天的主角 Lerna ! Lerna是業界知名度最高的 Monorepo 管理工具,功能完整。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。