使用Gradle构建Monorepo项目
根據(jù)Wikipedia的說(shuō)法 , monorepo是一種軟件開(kāi)發(fā)策略,其中許多項(xiàng)目存儲(chǔ)在同一存儲(chǔ)庫(kù)中。 這種策略可以快速檢測(cè)到因依賴關(guān)系的更改而導(dǎo)致的潛在問(wèn)題和破壞,并且已被許多使用大型代碼庫(kù)的組織采用,例如Google,Facebook和Twitter。
如果碰巧將Gradle用作首選的構(gòu)建工具,那么您也可以應(yīng)用此策略,這要?dú)w功于3.1版中引入的Composite Builds功能(在撰寫本文時(shí),最新版本為5.0)。 讓我們看一下不使用此功能時(shí)的典型monorepo工作流程。
沒(méi)有復(fù)合建筑的生活
假設(shè)您剛剛在一家公司中工作,該公司的項(xiàng)目保存在單個(gè)存儲(chǔ)庫(kù)中。 每個(gè)項(xiàng)目都有一個(gè)單獨(dú)的構(gòu)建,并且它們之間的唯一關(guān)系是通過(guò)相互依賴來(lái)滿足它們的需要。 有些項(xiàng)目比其他項(xiàng)目具有更多的依賴關(guān)系,有些項(xiàng)目甚至可能與其他項(xiàng)目沒(méi)有依賴關(guān)系。
項(xiàng)目數(shù)量很重要; 當(dāng)價(jià)格較低時(shí),您可以說(shuō)所有這些工具都可以放在一個(gè)傘項(xiàng)目下,就像使用Maven及其反應(yīng)堆功能所做的那樣。 Gradle具有類似的功能,除了在不觸發(fā)所有其他項(xiàng)目的情況下更輕松地定位特定的構(gòu)建之外。 可以這樣說(shuō),Gradle的反應(yīng)堆更智能,可以選擇要執(zhí)行的目標(biāo)。
但是,當(dāng)項(xiàng)目數(shù)量超過(guò)一打,比如說(shuō)幾百個(gè)時(shí),會(huì)發(fā)生什么? 即使使用更智能的反應(yīng)堆,Gradle也必須閱讀所有項(xiàng)目的配置,然后解決適當(dāng)?shù)哪繕?biāo)。 這肯定會(huì)花費(fèi)您寶貴的日常工作時(shí)間,這是很大的禁忌。
解決方案是將每個(gè)項(xiàng)目分解為單獨(dú)的版本。 反應(yīng)堆功能已經(jīng)一去不復(fù)返了,因此我們不必付出閱讀和配置所有項(xiàng)目的代價(jià),以后再丟棄其中的大多數(shù)項(xiàng)目。 但是,現(xiàn)在當(dāng)依賴項(xiàng)可能引入了錯(cuò)誤或二進(jìn)制不兼容時(shí),我們失去了做出反應(yīng)的機(jī)會(huì),這是在monorepo中組織代碼的原因之一。
現(xiàn)在,我們必須遵循以前嘗試過(guò)的
- 在依賴項(xiàng)項(xiàng)目上進(jìn)行更改。
- 構(gòu)建工件并將其發(fā)布到存儲(chǔ)庫(kù)。 大多數(shù)人都依賴快照工件。
- 確保從屬項(xiàng)目消耗了新發(fā)布的工件/快照。
- 編譯并運(yùn)行測(cè)試以確定代碼是否可以再次運(yùn)行。
- 沖洗并重復(fù)直到起作用。
這種方法的問(wèn)題在于,我們浪費(fèi)時(shí)間來(lái)發(fā)布中間工件,并且不時(shí)地形成表單,我們會(huì)忘記發(fā)布快照發(fā)行版,而在調(diào)試會(huì)話中花費(fèi)數(shù)小時(shí),直到我們意識(shí)到二進(jìn)制文件不正確,呃。
復(fù)合材料為營(yíng)救
現(xiàn)在讓我們看看Composite Builds如何解決我們所遇到的問(wèn)題。我們首先查看以下項(xiàng)目及其之間的依賴關(guān)系
項(xiàng)目1
Project2 <–取決于— Project1
Project3 <–取決于— Project2
這個(gè)小的依存關(guān)系圖告訴我們,對(duì)Project1所做的任何更改都會(huì)影響Project2,進(jìn)而影響到Project3,因?yàn)閷?duì)Project2所做的更改也會(huì)影響Project3。 此monorepo的目錄結(jié)構(gòu)如下所示
. ├── project1 │ └── build.gradle ├── project2 │ └── build.gradle └── project3└── build.gradle在這里,我們可以看到三個(gè)項(xiàng)目及其各自的構(gòu)建文件。 每個(gè)項(xiàng)目都有其自己的發(fā)布生命周期和版本,我們可以在其構(gòu)建文件中觀察到
project1 / build.gradle
apply plugin: 'java'group = 'com.acme' version = '1.0.0'project2 / build.gradle
apply plugin: 'java'group = 'com.acme' version = '2.3.0'dependencies {compile 'com.acme:project1:1.0.0' }project3 / build.gradle
apply plugin: 'java'group = 'com.acme' version = '1.2.0'dependencies {compile 'com.acme:project2:2.3.0' }激活“復(fù)合構(gòu)建”功能需要在名為settings.gradle的文件中配置項(xiàng)目之間的鏈接。 項(xiàng)目2和3需要此文件,因此我們的存儲(chǔ)庫(kù)如下所示
. ├── project1 │ └── build.gradle ├── project2 │ ├── build.gradle │ └── settings.gradle └── project3├── build.gradle└── settings.gradle接下來(lái),我們像這樣寫下項(xiàng)目之間的鏈接
project2 / settings.gradle
includeBuild '../project1'project3 / settings.gradle
includeBuild '../project2'大。 完成此設(shè)置后,我們現(xiàn)在可以通過(guò)發(fā)出以下命令來(lái)構(gòu)建project3
$ cd project3 $ pwd /tmp/project3 $ gradle classes > Task :processResources > Task :project2:processResources > Task :project1:compileJava > Task :project1:processResources > Task :project1:classes > Task :project1:jar > Task :project2:compileJava > Task :project2:classes > Task :project2:jar > Task :compileJava > Task :classes如您所見(jiàn),project1和project2均已構(gòu)建。 對(duì)project1進(jìn)行更改并再次觸發(fā)對(duì)project3的構(gòu)建,將按預(yù)期構(gòu)建所有三個(gè)項(xiàng)目。 現(xiàn)在,假設(shè)將此Monorepo擴(kuò)展到數(shù)十個(gè)或數(shù)百個(gè)項(xiàng)目,您將很快意識(shí)到幾乎不需要快照版本(如果有)。 Gradle還具有其他功能,例如輸入/輸出的任務(wù)緩存,這也使構(gòu)建更快。 同樣,最近宣布的構(gòu)建緩存功能通過(guò)“捕獲” CI服務(wù)器場(chǎng)中其他節(jié)點(diǎn)計(jì)算的輸出來(lái)加快構(gòu)建速度。
如果您喜歡本文,則可以在我的博客上找到有關(guān)Gradle和構(gòu)建工具的其他有趣文章。
翻譯自: https://www.javacodegeeks.com/2018/12/building-monorepo-projects-gradle.html
總結(jié)
以上是生活随笔為你收集整理的使用Gradle构建Monorepo项目的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: gradle ant_区分基于Ant目标
- 下一篇: ps退出画板模式快捷键(ps退出全屏快捷