新聞中心
為了解決代碼共享、重復(fù)和一致性等問(wèn)題,越來(lái)越多的團(tuán)隊(duì)轉(zhuǎn)向了Monorepo。本文就來(lái)了解一下什么是 Monorepo,它們可以帶來(lái)哪些好處,以及常用的 Monorepo 開發(fā)工具。幫助我們更好地理解和應(yīng)用這一代碼管理策略。讓我們一起進(jìn)入Monorepo的世界,打破傳統(tǒng)的代碼管理方式,迎接更高效的開發(fā)體驗(yàn)!

創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括杭錦網(wǎng)站建設(shè)、杭錦網(wǎng)站制作、杭錦網(wǎng)頁(yè)制作以及杭錦網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,杭錦網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到杭錦省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
什么是 Monorepo ?
Monorepo 是一個(gè)包含多個(gè)獨(dú)立項(xiàng)目,并且具有明確定義的關(guān)系的單個(gè)代碼庫(kù)。
圖片
一個(gè)真正的Monorepo不僅僅是將多個(gè)項(xiàng)目的代碼放在同一個(gè)代碼庫(kù)中。它還需要這些項(xiàng)目之間有明確定義的關(guān)系。如果這些項(xiàng)目之間沒(méi)有良好定義的關(guān)系,那么就不能稱之為Monorepo。
類似地,如果一個(gè)代碼庫(kù)中包含了一個(gè)龐大的應(yīng)用,而沒(méi)有對(duì)其進(jìn)行分割和封裝,那么這只是一個(gè)大型的代碼庫(kù),而不是真正的Monorepo。即使你給它取一個(gè)花里胡哨的名字,也不能改變它的本質(zhì)。
事實(shí)上,一個(gè)優(yōu)秀的Monorepo正好與龐大的代碼庫(kù)相反,它應(yīng)該具有良好的結(jié)構(gòu)和模塊化。
圖片
Monorepo 解決了什么問(wèn)題?
Polyrepo
為了討論的方便,假設(shè)多個(gè)代碼庫(kù)("polyrepo")是與單一代碼庫(kù)("monorepo")相對(duì)應(yīng)的概念。polyrepo 表示多代碼庫(kù),是當(dāng)前開發(fā)應(yīng)用的標(biāo)準(zhǔn)方式:每個(gè)團(tuán)隊(duì)、應(yīng)用或項(xiàng)目都有一個(gè)代碼庫(kù)。通常情況下,每個(gè)代碼庫(kù)只有一個(gè)構(gòu)建產(chǎn)物,并且擁有簡(jiǎn)單的構(gòu)建流程。
圖片
行業(yè)之所以采用多代碼庫(kù)的方式進(jìn)行開發(fā),有一個(gè)重要原因:團(tuán)隊(duì)自治。團(tuán)隊(duì)希望能夠自主決定使用哪些庫(kù),何時(shí)部署應(yīng)用或庫(kù),以及誰(shuí)可以貢獻(xiàn)或使用他們的代碼。
團(tuán)隊(duì)自治是一種組織架構(gòu)和開發(fā)模式的趨勢(shì),它賦予了團(tuán)隊(duì)更大的自主權(quán)和靈活性。每個(gè)團(tuán)隊(duì)擁有自己的代碼庫(kù),可以根據(jù)自己的需求和優(yōu)先級(jí)進(jìn)行獨(dú)立的決策和開發(fā)。這種方式能夠提高團(tuán)隊(duì)的效率和創(chuàng)造力,同時(shí)也減少了團(tuán)隊(duì)之間的依賴和沖突。
圖片
這些都是好的方面,那么為什么需要采取不同的方式呢?因?yàn)檫@種自治是通過(guò)隔離來(lái)實(shí)現(xiàn)的,而隔離卻會(huì)損害協(xié)作。具體來(lái)說(shuō),在多代碼庫(kù)環(huán)境中存在以下常見(jiàn)問(wèn)題:
- 繁瑣的代碼共享:要在多個(gè)代碼庫(kù)之間共享代碼,可能需要為共享代碼創(chuàng)建一個(gè)專門的代碼庫(kù)。這樣就需要設(shè)置工具和持續(xù)集成(CI)環(huán)境,將貢獻(xiàn)者添加到代碼庫(kù)中,并設(shè)置包發(fā)布,以便其他代碼庫(kù)可以依賴它。更不用說(shuō)在多個(gè)代碼庫(kù)之間解決不兼容的第三方庫(kù)版本的問(wèn)題了…
- 大量代碼重復(fù):由于不愿意費(fèi)事設(shè)置共享的代碼庫(kù),團(tuán)隊(duì)通常會(huì)在每個(gè)代碼庫(kù)中編寫自己的常見(jiàn)服務(wù)和組件的實(shí)現(xiàn),這導(dǎo)致了很多代碼重復(fù)。這種做法不僅浪費(fèi)了時(shí)間,而且在組件和服務(wù)發(fā)生變化時(shí)增加了維護(hù)、安全性和質(zhì)量控制的負(fù)擔(dān)。
- 對(duì)共享庫(kù)和消費(fèi)者進(jìn)行成本高昂的跨存儲(chǔ)庫(kù)更改:在多個(gè)代碼庫(kù)中進(jìn)行共享庫(kù)的跨庫(kù)更改是具有挑戰(zhàn)性且成本較高的。當(dāng)一個(gè)共享庫(kù)需要進(jìn)行關(guān)鍵 bug 修復(fù)或重大變更時(shí),開發(fā)人員需要在各個(gè)代碼庫(kù)中逐一應(yīng)用這些修改,而這些代碼庫(kù)之間可能存在孤立的修訂歷史。這也意味著必須在每個(gè)代碼庫(kù)中進(jìn)行相應(yīng)的測(cè)試和驗(yàn)證,確保更改不會(huì)引入新的問(wèn)題。
- 工具不一致:工具鏈的不一致性會(huì)給開發(fā)人員帶來(lái)額外的負(fù)擔(dān)。不同的項(xiàng)目使用不同的命令和工具,可能需要花費(fèi)時(shí)間和精力來(lái)適應(yīng)和記憶這些差異。而且,當(dāng)需要在多個(gè)項(xiàng)目之間進(jìn)行切換時(shí),頻繁地切換命令和工具可能會(huì)導(dǎo)致混淆和錯(cuò)誤。
Monorepo
在多代碼庫(kù)環(huán)境("polyrepo")中工作時(shí),可能會(huì)遇到一些問(wèn)題。那單一代碼庫(kù)("monorepo")是如何解決這些問(wèn)題的呢?
- 創(chuàng)建新項(xiàng)目無(wú)需額外開銷:創(chuàng)建新項(xiàng)目無(wú)需額外的開銷。如果所有消費(fèi)者都在同一個(gè)代碼庫(kù)中,可以直接在現(xiàn)有的開發(fā)環(huán)境中創(chuàng)建和設(shè)置新項(xiàng)目,避免了額外的資源和配置成本。
- 原子提交跨項(xiàng)目:每次提交都能確保所有項(xiàng)目能夠協(xié)同工作。當(dāng)在同一次提交中修復(fù)所有問(wèn)題時(shí),不存在破壞性變更的問(wèn)題,因?yàn)樗行薷亩际且黄鹜瓿傻摹?/li>
- 同一版本的所有內(nèi)容:可以避免因項(xiàng)目依賴沖突而導(dǎo)致的不兼容性問(wèn)題。所有項(xiàng)目都共享同一份代碼庫(kù),使用相同的第三方庫(kù)版本,減少了版本管理和沖突解決的復(fù)雜性。
- 開發(fā)靈活性:可以建立一種統(tǒng)一的構(gòu)建和測(cè)試應(yīng)用程序的方式,即使這些應(yīng)用程序使用不同的工具和技術(shù)。開發(fā)人員可以自信地為其他團(tuán)隊(duì)的應(yīng)用程序做出貢獻(xiàn),并驗(yàn)證其更改是安全的。
Monorepo 工具有哪些?
Monorepo 擁有許多優(yōu)勢(shì),但為了使其發(fā)揮作用,需要使用正確的工具。隨著工作空間的擴(kuò)大,這些工具必須幫助開發(fā)者保持高效、可理解和可管理。
那 Monorepo 工具應(yīng)該提供些什么呢?
- 本地計(jì)算緩存
- 本地任務(wù)編排
- 分布式計(jì)算緩存
- 分布式任務(wù)執(zhí)行
- 透明遠(yuǎn)程執(zhí)行
- 檢測(cè)受影響的項(xiàng)目/包
- 工作區(qū)分析
- 依賴圖可視化
- 代碼共享
- 一致的工具
- 代碼生成
- 項(xiàng)目約束和可見(jiàn)性
注意:除了功能以外,還有其他因素會(huì)影響使用體驗(yàn)。盡管一個(gè)工具可能在某些方面功能不如其他工具強(qiáng)大,但由于用戶體驗(yàn)、成熟度、文檔、編輯器支持等因素的差異,用戶可能會(huì)更喜歡使用它。有些功能可以很容易地通過(guò)自定義實(shí)現(xiàn)來(lái)添加,而有些功能則無(wú)法通過(guò)簡(jiǎn)單的修改來(lái)實(shí)現(xiàn)。因此,除了關(guān)注功能外,還需要綜合考慮其他因素來(lái)選擇適合自己需求的工具。
比較流行的 Monorepo 工具如下:
|
工具 |
開發(fā)團(tuán)隊(duì) |
簡(jiǎn)介 |
|
Bazel |
谷歌 |
快速、可擴(kuò)展、多語(yǔ)言且可擴(kuò)展的構(gòu)建系統(tǒng)。 |
|
Gradle Build Tool |
Gradle |
專為多項(xiàng)目構(gòu)建而設(shè)計(jì)的快速、靈活的多語(yǔ)言構(gòu)建系統(tǒng)。 |
|
Lage |
微軟 |
JS monorepos 中的任務(wù)運(yùn)行器。 |
|
Lerna |
Nrwl |
一個(gè)用于管理具有多個(gè)包的 JavaScript 項(xiàng)目的工具。 |
|
Nx |
Nrwl |
下一代構(gòu)建系統(tǒng)具有一流的 monorepo 支持和強(qiáng)大的集成。 |
|
Pants |
Pants Build |
一個(gè)快速、可擴(kuò)展、用戶友好的構(gòu)建系統(tǒng),適用于各種規(guī)模的代碼庫(kù)。 |
|
Rush |
微軟 |
適合擁有大量團(tuán)隊(duì)和項(xiàng)目的大型單一倉(cāng)庫(kù)。屬于 Rush Stack 項(xiàng)目系列的一部分。 |
|
Turborepo |
Vercel |
JavaScript 和 TypeScript 代碼庫(kù)的高性能構(gòu)建系統(tǒng) |
接下來(lái)將逐個(gè)功能來(lái)比較各個(gè) Monorepo 工具在這些功能上的表現(xiàn)。
本地計(jì)算緩存
本地計(jì)算緩存是指在進(jìn)行任務(wù)執(zhí)行時(shí),將任務(wù)的輸入、輸出和中間結(jié)果存儲(chǔ)在本地機(jī)器上,以便在后續(xù)的構(gòu)建或測(cè)試過(guò)程中可以直接使用這些已經(jīng)計(jì)算過(guò)的結(jié)果,而不需要重新執(zhí)行相同的任務(wù)。
圖片
|
工具 |
是否支持 |
|
Bazel |
|
|
Gradle Build Tool |
Gradle Build Tool 本身提供本地構(gòu)建緩存。Gradle Enterprise 添加了對(duì)復(fù)制和管理的支持。 |
|
Lage |
|
|
Lerna |
Lerna v6 具有由 Nx 提供支持的內(nèi)置本地計(jì)算緩存。 |
|
Nx |
|
|
Pants |
像React一樣,Nx在從其緩存中恢復(fù)結(jié)果時(shí)進(jìn)行了樹差異比較,這使得它在平均情況下比其他工具更快 |
|
Rush |
利用系統(tǒng) tar 命令更快地恢復(fù)文件。 |
|
Turborepo |
本地任務(wù)編排
本地任務(wù)編排是指在執(zhí)行任務(wù)時(shí),按照規(guī)定的順序和并行方式來(lái)管理和執(zhí)行這些任務(wù)。任務(wù)之間可能存在依賴關(guān)系,需要按照正確的順序進(jìn)行執(zhí)行,同時(shí)還可以利用并行計(jì)算的優(yōu)勢(shì),提高任務(wù)的執(zhí)行效率。
圖片
|
工具 |
是否支持 |
|
Bazel |
|
|
Gradle Build Tool |
Gradle Build Tool 通過(guò)配置提供對(duì)并行任務(wù)的支持,并通過(guò)其靈活的 Groovy 或 Kotlin DSL 提供任務(wù)編排支持。 |
|
Lage |
|
|
Lerna |
Lerna v6 充分利用了 Nx 來(lái)高效地協(xié)調(diào)和并行執(zhí)行任務(wù)。 |
|
Nx |
|
|
Pants |
|
|
Rush |
支持此功能。命令可以被建模為簡(jiǎn)單的腳本,也可以作為獨(dú)立的“階段”(例如構(gòu)建、測(cè)試等)。 |
|
Turborepo |
分布式計(jì)算緩存
分布式計(jì)算緩存允許在不同的環(huán)境中共享緩存結(jié)果。通過(guò)共享緩存,整個(gè)組織中的不同部門或團(tuán)隊(duì)可以共享已經(jīng)計(jì)算過(guò)的結(jié)果,避免重復(fù)構(gòu)建或測(cè)試相同的內(nèi)容。
圖片
|
工具 |
是否支持 |
|
Bazel |
|
|
Gradle Build Tool |
Gradle Build Tool 提供遠(yuǎn)程分布式緩存。Gradle Enterprise 添加了對(duì)復(fù)制和管理的支持。 |
|
Lage |
|
|
Lerna |
Lerna v6 可以連接到 Nx Cloud 以啟用分布式緩存。 |
|
Nx |
|
|
Pants |
|
|
Rush |
Rush 內(nèi)置了對(duì) Azure 和 AWS 存儲(chǔ)的支持,并具有允許自定義緩存提供程序的插件 API。 |
|
Turborepo |
分布式任務(wù)執(zhí)行
分布式任務(wù)執(zhí)行是指將一個(gè)命令分布到多臺(tái)機(jī)器上執(zhí)行的能力,同時(shí)在很大程度上保持在單臺(tái)機(jī)器上運(yùn)行時(shí)的開發(fā)人員體驗(yàn)。
圖片
|
工具 |
是否支持 |
|
Bazel |
Bazel 的實(shí)現(xiàn)是最復(fù)雜的一種,可以擴(kuò)展到包含數(shù)十億行代碼的存儲(chǔ)庫(kù),設(shè)置起來(lái)也很困難。 |
|
Gradle Build Tool |
? Gradle Enterprise可以分布式執(zhí)行測(cè)試任務(wù)。 |
|
Lage |
|
|
Lerna |
Lerna v6 可以連接到 Nx Cloud 以實(shí)現(xiàn)分布式任務(wù)執(zhí)行。 |
|
Nx |
Nx 的實(shí)現(xiàn)并不像 Bazel 那樣復(fù)雜,但可以通過(guò)小的配置更改來(lái)打開它。 |
|
Pants |
Pant 的實(shí)現(xiàn)與 Bazel 類似,并使用相同的遠(yuǎn)程執(zhí)行 API。 |
|
Rush |
? Rush 通過(guò)選擇性地與 Microsoft 的 BuildXL 加速器集成來(lái)提供此功能。 |
|
Turborepo |
透明遠(yuǎn)程執(zhí)行
透明的遠(yuǎn)程執(zhí)行功能允許開發(fā)人員在本地開發(fā)環(huán)境中執(zhí)行命令,并將這些命令自動(dòng)透明地分發(fā)到多臺(tái)遠(yuǎn)程機(jī)器上進(jìn)行執(zhí)行。開發(fā)人員可以像在單臺(tái)機(jī)器上運(yùn)行命令一樣,在本地環(huán)境中編寫和執(zhí)行命令,而無(wú)需手動(dòng)切換到遠(yuǎn)程機(jī)器或修改代碼。
|
工具 |
是否支持 |
|
Bazel |
這是 Bazel 和其他工具最大的區(qū)別 |
|
Gradle Build Tool |
|
|
Lage |
|
|
Lerna |
|
|
Nx |
|
|
Pants |
Pant 的實(shí)現(xiàn)與 Bazel 類似,并使用相同的遠(yuǎn)程執(zhí)行 API。 |
|
Rush |
|
|
Turborepo |
檢測(cè)受影響的項(xiàng)目/包
在進(jìn)行構(gòu)建或測(cè)試操作時(shí),通過(guò)檢測(cè)變更的內(nèi)容,確定可能受到變更影響的項(xiàng)目或包,從而只針對(duì)受影響的項(xiàng)目進(jìn)行構(gòu)建或測(cè)試。
圖片
|
工具 |
是否支持 |
|
Bazel |
? Bazel沒(méi)有內(nèi)置支持,但是第三方工具(如target-determinator)使用Bazel的查詢語(yǔ)言提供了這個(gè)功能。 |
|
Gradle Build Tool |
Gradle Build Tool 本身提供增量構(gòu)建和最新檢測(cè)。 |
|
Lage |
|
|
Lerna |
|
|
Nx |
支持,它的實(shí)現(xiàn)不僅查看更改了哪些文件,還查看更改的性質(zhì)。 |
|
Pants |
|
|
Rush |
用于項(xiàng)目選擇的命令行參數(shù)可以檢測(cè)哪些項(xiàng)目受到 Git diff 的影響。Rush 還為自動(dòng)化場(chǎng)景提供了 PackageChangeAnalyzer API。 |
|
Turborepo |
工作區(qū)分析
工作區(qū)是指包含多個(gè)項(xiàng)目或代碼庫(kù)的根目錄。工作區(qū)分析通過(guò)解析工作區(qū)中的項(xiàng)目、文件和依賴關(guān)系,生成一個(gè)項(xiàng)目圖,展示了項(xiàng)目之間的相互關(guān)系和依賴。這個(gè)項(xiàng)目圖可以幫助開發(fā)人員更好地理解整個(gè)工作區(qū)的結(jié)構(gòu)和組織,并能夠快速定位和處理相關(guān)的項(xiàng)目。
圖片
|
工具 |
是否支持 |
|
Bazel |
? Bazel 允許開發(fā)人員編寫 BUILD 文件。一些公司構(gòu)建了分析工作區(qū)源并生成 BUILD 文件的工具。 |
|
Gradle Build Tool |
可以使用build.gradle(Groovy腳本)或build.gradle.kts(Kotlin腳本)來(lái)編寫構(gòu)建任務(wù)。 |
|
Lage |
|
|
Lerna |
|
|
Nx |
默認(rèn)情況下,Nx 分析 package.json、JavaScript 和 TypeScript 文件。它是可插拔的,可以擴(kuò)展以支持其他平臺(tái)(例如 Go、Java、Rust)。 |
|
Pants |
這是Pants的最大差異化點(diǎn)。它使用靜態(tài)分析來(lái)自動(dòng)推斷出支持的所有語(yǔ)言和框架的文件級(jí)依賴關(guān)系。 |
|
Rush |
Rush項(xiàng)目和單倉(cāng)庫(kù)項(xiàng)目具有相同的 |
|
Turborepo |
Turborepo 分析 package.json 文件。 |
依賴圖可視化
依賴關(guān)系圖可視化工具可以將項(xiàng)目和/或任務(wù)之間的依賴關(guān)系以圖形化的方式呈現(xiàn)出來(lái)。這個(gè)可視化過(guò)程是交互式的,也就是說(shuō)可以對(duì)圖中的節(jié)點(diǎn)進(jìn)行搜索、過(guò)濾、隱藏、聚焦或突出顯示,以及進(jìn)行查詢操作。
|
工具 |
是否支持 |
|
Bazel |
Bazel 的實(shí)現(xiàn)支持自定義查詢語(yǔ)言來(lái)過(guò)濾掉不感興趣的節(jié)點(diǎn)。 |
|
Gradle Build Tool |
? Gradle Build Scan 提供豐富的依賴關(guān)系信息,并且第三方工具可用于項(xiàng)目/任務(wù)圖。 |
|
Lage |
? Lage 沒(méi)有附帶可視化工具,可以編寫自己的可視化工具。 |
|
Lerna |
? Lerna 沒(méi)有附帶可視化工具,可以編寫自己的可視化工具。 |
|
Nx |
Nx 配備了交互式可視化工具,可用于過(guò)濾和探索大型工作區(qū)。 |
|
Pants |
? Pants并沒(méi)有自帶可視化工具,但它可以生成一個(gè)包含代碼庫(kù)詳細(xì)圖結(jié)構(gòu)的JSON文件,該文件可以被處理成可用于可視化工具的輸入數(shù)據(jù)。 |
|
Rush |
? Rush 沒(méi)有附帶可視化工具,可以編寫自己的可視化工具。 |
|
Turborepo |
Turborepo 使用 Graphviz 生成執(zhí)行計(jì)劃的靜態(tài)圖像和 HTML 文件。該實(shí)現(xiàn)不是交互式的。 |
代碼共享
代碼共享是指通過(guò)一些方式來(lái)方便地分享代碼庫(kù)中獨(dú)立的代碼片段。
圖片
|
工具 |
是否支持 |
|
Bazel |
可以將任何文件夾標(biāo)記為一個(gè)項(xiàng)目,并通過(guò)Bazel的構(gòu)建規(guī)則來(lái)實(shí)現(xiàn)該項(xiàng)目的共享。 |
|
Gradle Build Tool |
可以發(fā)布可共享的構(gòu)件并從多個(gè)倉(cāng)庫(kù)中引用依賴項(xiàng)。 |
|
Lage |
支持,只有npm包可以共享。 |
|
Lerna |
支持,只有npm包可以共享。 |
|
Nx |
支持,任何文件夾都可以標(biāo)記為一個(gè)項(xiàng)目,并且可以進(jìn)行共享。Nx插件幫助配置WebPack、Rollup、TypeScript和其他工具,以實(shí)現(xiàn)共享而不影響開發(fā)人員的工作環(huán)境。 |
|
Pants |
支持打包、發(fā)布和使用代碼構(gòu)件,使用底層語(yǔ)言和框架的標(biāo)準(zhǔn)慣用法。 |
|
Rush |
支持,不鼓勵(lì)從未聲明為npm依賴的文件夾導(dǎo)入代碼。這確保了項(xiàng)目可以在單體倉(cāng)庫(kù)之間輕松移動(dòng)。對(duì)于創(chuàng)建包是過(guò)于繁瑣的情況,"packlets"提供了一個(gè)輕量級(jí)的替代方案。 |
|
Turborepo |
支持,只有npm包可以共享。 |
一致的工具
這樣的工具可以幫助開發(fā)人員在不同的技術(shù)棧之間切換時(shí)更加輕松和無(wú)縫。不管是使用JavaScript框架,還是使用Go、Rust、Java等其他技術(shù),開發(fā)人員都可以獲得相同的工具支持和開發(fā)體驗(yàn)。這種一致性的工具能夠簡(jiǎn)化開發(fā)流程,減少學(xué)習(xí)成本,并提高團(tuán)隊(duì)的協(xié)作效率。
例如,該工具可以分析package.json和JS/TS文件,以確定JavaScript項(xiàng)目的依賴關(guān)系以及構(gòu)建和測(cè)試方法。但是,對(duì)于Rust,它會(huì)分析Cargo.toml文件,對(duì)于Java,它會(huì)分析Gradle文件。因此,該工具需要具備插件化的能力。
圖片
|
工具 |
是否支持 |
|
Bazel |
Bazel的構(gòu)建規(guī)則就像是不同技術(shù)和框架的插件。 |
|
Gradle Build Tool |
通過(guò)插件生態(tài)系統(tǒng)可以擴(kuò)展其功能,例如使用CMake進(jìn)行本地構(gòu)建或使用Webpack進(jìn)行打包。 |
|
Lage |
只能運(yùn)行 npm 腳本。 |
|
Lerna |
只能運(yùn)行 npm 腳本。 |
|
Nx |
Nx是可插拔的。它默認(rèn)能夠調(diào)用npm腳本,但也可以擴(kuò)展以調(diào)用其他工具(例如Gradle)。 |
|
Pants |
Pants具有強(qiáng)大的插件API,可以提供統(tǒng)一的用戶體驗(yàn)(UX),適用于不同的語(yǔ)言和框架。它內(nèi)置了多個(gè)插件,包括Python、Java、Scala、Go、Shell和Docker等,同時(shí)還有更多的插件正在開發(fā)中。還可以使用相同的API編寫自定義的構(gòu)建規(guī)則。 |
|
Rush |
Rush只針對(duì)TypeScript/JavaScript項(xiàng)目進(jìn)行構(gòu)建,并推薦一種解耦的方法,即使用本地工具鏈或BuildXL單獨(dú)構(gòu)建原生組件。理想情況下,Node.js是單體庫(kù)開發(fā)者所需的唯一先決條件。 |
|
Turborepo |
Turborepo只能運(yùn)行npm腳本,但不必安裝Node.js。 |
代碼生成
原生支持生成代碼。
|
工具 |
是否支持 |
|
Bazel |
? 可以使用外部代碼生成器。 |
|
Gradle Build Tool |
? 可以使用外部代碼生成器。 |
|
Lage |
? 可以使用外部代碼生成器。 |
|
Lerna |
? 可以使用外部代碼生成器。 |
|
Nx |
Nx具有強(qiáng)大的代碼生成能力。它使用虛擬文件系統(tǒng),并提供編輯器集成。Nx插件提供了流行框架的生成器,還可以使用其他生成器。 |
|
Pants |
Pants內(nèi)置了適用于流行的代碼生成框架的插件,包括Protobuf/gRPC、Thrift、Scrooge、Avro和SOAP。它還提供了插件API支持,以便輕松地添加新的代碼生成器。Pants支持從單個(gè)codegen源生成多種語(yǔ)言的代碼。它能夠通過(guò)對(duì)codegen源的靜態(tài)分析來(lái)推斷依賴關(guān)系,并在這些源發(fā)生變化時(shí)正確地使生成的代碼失效。 |
|
Rush |
? Rush的維護(hù)者建議將項(xiàng)目模板作為單體庫(kù)中的普通項(xiàng)目進(jìn)行維護(hù),以確保它們能夠在編譯時(shí)沒(méi)有錯(cuò)誤。通過(guò)一個(gè)社區(qū)插件,可以使用項(xiàng)目腳手架命令來(lái)生成項(xiàng)目模板。 |
|
Turborepo |
? 可以使用外部代碼生成器。 |
項(xiàng)目約束和可見(jiàn)性
Rush支持定義規(guī)則來(lái)約束倉(cāng)庫(kù)內(nèi)的依賴關(guān)系。例如,開發(fā)人員可以將某些項(xiàng)目標(biāo)記為私有項(xiàng)目,只有他們團(tuán)隊(duì)內(nèi)的人才能依賴這些項(xiàng)目。開發(fā)人員還可以根據(jù)使用的技術(shù)(例如React或Nest.js)標(biāo)記項(xiàng)目,并確保后端項(xiàng)目不導(dǎo)入前端項(xiàng)目。
圖片
|
工具 |
是否支持 |
|
Bazel |
Bazel支持可見(jiàn)性規(guī)則,這有助于將私有內(nèi)容與公共內(nèi)容、可共享的內(nèi)容等進(jìn)行分隔。 |
|
Gradle Build Tool |
? 本身不原生支持這樣的規(guī)則,但其豐富的插件功能允許開發(fā)人員開發(fā)類似的規(guī)則。 |
|
Lage |
? 可以使用一組自定義規(guī)則和額外配置的代碼檢查工具(linter)來(lái)確保滿足某些約束條件。 |
|
Lerna |
? 可以使用一組自定義規(guī)則和額外配置的代碼檢查工具(linter)來(lái)確保滿足某些約束條件。 |
|
Nx |
開發(fā)人員可以根據(jù)自己的需求對(duì)項(xiàng)目進(jìn)行任意方式的注釋,并建立不變量,而Nx將確保這些注釋的有效性。它允許開發(fā)人員注釋哪些是私有的、哪些是公開的、哪些是實(shí)驗(yàn)性的、哪些是穩(wěn)定的等等。Nx還允許為每個(gè)包定義公共API,這樣其他開發(fā)人員就無(wú)法深層導(dǎo)入到這些包中。 |
|
Pants |
? 雖然原生支持尚未實(shí)現(xiàn),但可以編寫自定義插件來(lái)強(qiáng)制執(zhí)行此類規(guī)則。 |
|
Rush |
Rush可以根據(jù)項(xiàng)目類型選擇性地要求在引入新的NPM依賴(內(nèi)部或外部)時(shí)進(jìn)行審批。它還支持針對(duì)NPM發(fā)布的版本策略。 |
|
Turborepo |
? 可以使用一組自定義規(guī)則和額外配置的代碼檢查工具(linter)來(lái)確保滿足某些約束條件。 |
小結(jié)
綜上,Monorepo 是一種代碼管理策略,它將一個(gè)項(xiàng)目的所有代碼存儲(chǔ)在一個(gè)單獨(dú)的版本控制庫(kù)中。Monorepo 解決了多個(gè)問(wèn)題:解決了代碼共享與重復(fù)的困擾,提供更好的可追蹤性和一致性。通過(guò)使用Monorepo,開發(fā)團(tuán)隊(duì)可以更好地組織、共享和管理代碼,提高開發(fā)效率和協(xié)作質(zhì)量。選擇合適的Monorepo工具并靈活運(yùn)用,能夠幫助開發(fā)者更好地應(yīng)對(duì)復(fù)雜的軟件開發(fā)需求,推動(dòng)項(xiàng)目的成功完成。
參考:https://monorepo.tools/
當(dāng)前標(biāo)題:聊聊HelloMonorepo
新聞來(lái)源:http://www.dlmjj.cn/article/cdchgoe.html


咨詢
建站咨詢
