monorepo使用教程


Monorepo 是管理項目代碼的一個方式,指在一個項目倉庫 (repo) 中管理多個模塊/包 (package),不同於常見的每個模塊建一個 repo。

目前有不少大型開源項目采用了這種方式,如 Babel

How is the repo structured?
The Babel repo is managed as a monorepo that is composed of many npm packages.

還有 create-react-appreact-router 等。可以看到這些項目的第一級目錄的內容以腳手架為主,主要內容都在 packages 目錄中、分多個 package 進行管理。

├── packages
|   ├── pkg1
|   |   ├── package.json
|   ├── pkg2
|   |   ├── package.json
├── package.json

monorepo 最主要的好處是統一的工作流和Code Sharing。比如我想看一個 pacakge 的代碼、了解某段邏輯,不需要找它的 repo,直接就在當前 repo;當某個需求要修改多個 pacakge 時,不需要分別到各自的 repo 進行修改、測試、發版或者 npm link,直接在當前 repo 修改,統一測試、統一發版。只要搭建一套腳手架,就能管理(構建、測試、發布)多個 package。

不好的方面則主要是 repo 的體積較大。特別是,因為各個 package 理論上都是獨立的,所以每個 package 都維護着自己的 dependencies,而很大的可能性,package 之間有不少相同的依賴,而這就可能使install時出現重復安裝,使本來就很大的 node_modues 繼續膨脹(我稱這為「依賴爆炸」...)。

基於對以上的理解,我認為當項目到一定的復雜度,需要且可以划分模塊、但模塊間聯系緊密的,比較適合用 monorepo 組織代碼。

目前最常見的 monorepo 解決方案是 Lerna 和 yarn 的 workspaces 特性。其中,lerna 是一個獨立的包,其官網的介紹是:

a tool that optimizes the workflow around managing multi-package repositories with git and npm.

上面提到的 Babel, create-react-app 等都是用 lerna 進行管理的。在項目 repo 中以lerna.json聲明 packages 后,lerna 為項目提供了統一的 repo 依賴安裝 (lerna bootstrap),統一的執行 package scripts (lerna run),統一的 npm 發版 (lerna publish) 等特性。對於「依賴爆炸」的問題,lerna 在安裝依賴時提供了--hoist選項,相同的依賴,會「提升」到 repo 根目錄下安裝,但……太雞肋了,lerna 直接以字符串對比 dependency 的版本號,完全相同才提升,semver 約定在這並不起作用。

具體的使用方法移步 Lerna 官網:https://lerna.js.org

而使用 yarn 作為包管理器的同學,可以在 package.json 中以 workspaces 字段聲明 packages,yarn 就會以 monorepo 的方式管理 packages。相比 lerna,yarn 突出的是對依賴的管理,包括 packages 的相互依賴、packages 對第三方的依賴,yarn 會以 semver 約定來分析 dependencies 的版本,安裝依賴時更快、占用體積更小;但欠缺了「統一工作流」方面的實現。

yarn 官網對 workspace的詳細說明:Workspaces | Yarn

lerna 和 yarn-workspace 並不是只能選其一,大多 monorepo 即會使用 lerna 又會在 package.json 聲明 workspaces。這樣的話,無論你的包管理器是 npm 還是 yarn,都能發揮 monorepo 的優勢;要是包管理是 yarn ,lerna 就會把依賴安裝交給 yarn 處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM