在版本控制系統中,monorepo是一種軟件開發策略,指將多項目的代碼存儲在同一倉庫中。截止2017年,這種軟件工程實踐的各類形式已經存在了二十多年,可是通常概念直到最近才被命名。
Google,Facebook,Microsoft,Uber,Airbnb,以及Twitter均採用了特別龐大的monorepos,經過多樣的策略去擴展用於龐大代碼量和平常變動頻次的構建系統和版本控制軟件
---維基百科 https://en.wikipedia.org/wiki...前端
相對於單個倉庫來講開啓新項目費時費事(建立倉庫、項目架構(雖然有腳手架的話會方便些),多個項目彙總管理麻煩)
組件工具依賴複用及更新麻煩
重複安裝公共依賴react、react-dom這些有多大都清楚
本地項目調試麻煩,這個項目依賴了另外一個項目,那麼你只能用 npm link 的方式將它 link 到須要調試的項目裏面。一旦 link 的項目多了,手動去管理這些 link 操做就容易心累。vue
便於代碼複用
簡化依賴管理
原子性提交(當一項工做分佈在不一樣的倉庫時,發佈須要按必定順序進行,當項目足夠大時管理依賴間多樣的版本會形成依賴地獄)
大型代碼重構,便於確保總體功能重構後的可用性
跨團隊協做靈活的代碼從屬關係,你們均可以參與改進node
缺乏獨立項目的版本信息
缺乏獨立項目的權限控制
須要更多的默認存儲空間react
隨着前端項目的日益複雜,某些業務或者工具庫一般涉及不少個倉庫,時間一長,多個倉庫(MultiRepo)的開發弊端日益顯露,monorepo的管理方式獲得了更多應用。git
目前不少開源項目都用了 monorepo,好比VUE、REACT、Babel。
你們能夠看一下React和Vue3的項目結構:
https://github.com/facebook/r...
https://github.com/vuejs/vue-...github
如何使同一倉庫中的各個項目保持其獨立性?typescript
Lerna 是一個管理多個 npm 模塊的工具,是 Babel 本身用來維護本身的 Monorepo 並開源出的一個項目。優化維護多包的工做流,解決多個包互相依賴,且發佈須要手動維護多個包的問題。
yarn workspaces 是一種管理軟件包的方式,與lerna在包管理上有一部分的功能重合;npm
yarn workspaces的應用: vue、react
來看看lerna的使用。babel/babel, facebook/jest, alibaba/rax 、taro、umi json
在包管理上yarn相對與lerna能夠減小包的重複安裝,lerna則在分包構建發佈上比較有有優點。因此有的項目結合了兩者的優勢進行了多項目管理的方案設計babel
2.Rush Stack(微軟+開源)、Bazel構建系統 (Google)、Buck構建系統 (Facebook)、Nx等,提供從初始化、開發、構建、測試到部署的全流程能力,有一套比較完整的 Monorepo 基礎設施,但定製,適配成本高。
這裏只根據基礎功能列出了包管理生命週期中的關鍵命令,詳細的代碼以及lerna包管理實現的原理你們感興趣的話能夠點贊蒐藏關注後續分析~~
需求:各package獨立打包:有公用打包配置的能力
//包安裝、同時安裝各個子包須要的依賴 yarn install yarn workspace cli add cli-shared-utils //將cli-shared-utils做爲cli的依賴進行安裝 yarn workspaces add lodash //給全部的package安裝依賴: yarn add -W -D typescript //給root 安裝公用的依賴 //清理環境 lerna clean //清理全部的node_modules //按順序構建(各個package之間存在相互依賴,如packageB只有在packageA構建完以後才能進行構建,不然就會出錯,須要按拓撲排序的規則進行構建) lerna run --stream --sort build
兩種模式:
Independent mode:結合Git,檢查文件變更,只發布有改動的packge。(設置方式1:建立項目的時候 能夠經過 lerna init --independent 命令,啓用獨立模式管理軟件包。設置方式2:修改 lerna.json 的 version 字段,修改成 independent, 用來開啓獨立模式)
Fixed/Locked mode(默認):把工程看成一個總體來對待。每次發佈packges,都是全量發佈,不管是否修改
//更新版本 //找出從上一個版本發佈以來有過變動的 package //提示開發者肯定要發佈的版本號 //將全部更新過的的 package 中的package.json的version字段更新 //將依賴更新過的 package 的 包中的依賴版本號更新 //更新 lerna.json 中的 version 字段 //根據commit信息自動生成該版本的CHANGELOG (配置conventionalCommits) //提交上述修改,並打一個 tag //推送到 git 倉庫 lerna version //更新版本 //發佈新包 lerna publish //包含了lerna version