如何在 Gradle 中将单项目构建转换为多项目构建
当您的 Gradle 项目增长时,您可能希望将其拆分为多个子项目,以提高模块化、可维护性和并行执行。
本指南解释了如何将单项目构建转换为多项目构建。
为什么要使用多项目构建?
单项目构建在单个 build.gradle(.kts)
文件中管理所有源代码和依赖项。
相比之下,多项目构建由以下部分组成:
-
一个根项目,包含共享配置和依赖项,如
settings.gradle(.kts)
中所定义。 -
多个子项目,每个子项目都有自己的
build.gradle(.kts)
、依赖项和任务。
步骤 1:项目结构
让我们从一个典型的单项目设置开始,该设置由 gradle init
创建:
root
├── settings.gradle(.kts) (1)
└── app (2)
├── build.gradle(.kts)
└── src/
1 | 定义根项目设置 |
2 | 单个应用程序模块 |
或者,您的单个项目可能如下所示:
app (root) (1)
├── build.gradle(.kts)
├── settings.gradle(.kts)
└── src/
1 | 项目根目录,也作为应用程序模块 |
如果您的项目是这样,请在开始之前将 app 文件夹嵌套在一个新的 root 文件夹中。 |
转换为多项目构建后,结构将如下所示:
root
├── settings.gradle(.kts) (1)
├── app (2)
│ ├── build.gradle(.kts)
│ └── src/
└── library (3)
├── build.gradle(.kts)
└── src/
1 | 定义子项目 |
2 | 原始应用程序模块,现在是一个子项目 |
3 | 一个新的库模块 |
步骤 2:创建一个或多个新的子项目
现在您可以在 root
中将您的附加项目创建为目录。它们都将成为根项目的子项目。
为了继续我们的示例,我们创建一个名为 library
的新子项目:
cd root
mkdir library
确保原始项目 (app
) 与新的 library
子项目保持在同一级别
root
├── app (1)
│ └── some files
└── library (2)
1 | 原始应用程序模块 |
2 | 新创建的子项目 |
将源文件移动到其相应的文件夹中。
在我们的示例中,可重用代码已移动到 library
子项目
root
├── app (1)
│ └── src/
└── library (2)
└── src/
1 | 应用程序模块,包含其自己的源代码 |
2 | 新的库模块,存储可重用代码 |
步骤 3:更新 settings.gradle(.kts)
确保 settings.gradle(.kts)
位于根目录中
root
├── settings.gradle(.kts) (1)
├── app (2)
│ └── src/
└── library (3)
└── src/
1 | 整个构建的单个设置文件 |
2 | 应用程序模块 |
3 | 新的库模块 |
修改 settings.gradle(.kts)
以包含新的子项目。
在我们的示例中,我们将 library
添加到 include
中
rootProject.name = "root"
include("app", "library")
rootProject.name = "root"
include("app", "library")
不应该有其他设置文件.
步骤 4:为每个子项目创建 build.gradle(.kts)
文件
每个子项目都必须有自己的 build.gradle(.kts)
文件
root
├── settings.gradle(.kts) (1)
├── app (2)
│ ├── build.gradle(.kts) (3)
│ └── src/
└── library (4)
├── build.gradle(.kts) (5)
└── src/
1 | 定义子项目 |
2 | 应用程序子项目 |
3 | 定义 app 构建 |
4 | 库子项目 |
5 | 定义 library 构建 |
app
构建文件应与原始构建文件非常相似。它包含构建 app
子项目所需的所有依赖项和配置。
现在,它还依赖于 library
子项目
plugins {
application
id("org.jetbrains.kotlin.plugin.serialization") // Now the plugin is applied
}
repositories {
mavenCentral()
}
dependencies {
implementation("com.google.guava:guava:33.3.1-jre")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
implementation(project(":library")) // Uses the library module
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
application {
mainClass = "org.example.App"
}
plugins {
id('application')
id("org.jetbrains.kotlin.plugin.serialization") // Now the plugin is applied
}
repositories {
mavenCentral()
}
dependencies {
implementation("com.google.guava:guava:33.3.1-jre")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
implementation(project(":library")) // Uses the library module
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
application {
mainClass = "org.example.App"
}
library
构建文件应该是新的。它包含构建 library
子项目所需的所有依赖项和配置
plugins {
id("java-library")
id("org.jetbrains.kotlin.plugin.serialization") // Now the plugin is applied
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.apache.commons:commons-lang3:3.17.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
}
plugins {
id("java-library")
id("org.jetbrains.kotlin.plugin.serialization") // Now the plugin is applied
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.apache.commons:commons-lang3:3.17.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
}
步骤 5:修改或删除根 build.gradle(.kts)
根项目中的构建文件是可选的
root
├── settings.gradle(.kts) (1)
├── build.gradle(.kts) (2)
├── app (3)
│ ├── build.gradle(.kts)
│ └── src/
└── library (4)
├── build.gradle(.kts)
└── src/
1 | 定义子项目 |
2 | 可选(用于共享配置) |
3 | 应用程序模块 |
4 | 新的库模块 |
如果您需要配置共享仓库和设置,可以使用根 build.gradle(.kts)
plugins {
id("org.jetbrains.kotlin.plugin.serialization") version "1.9.21" apply false
}
subprojects {
repositories {
mavenCentral()
}
}
plugins {
id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.21' apply false
}
subprojects {
repositories {
mavenCentral()
}
}
您可以回顾一下如何在每个构建文件中应用名为 org.jetbrains.kotlin.plugin.serialization
的常见第三方插件。
然而,共享逻辑应该使用约定插件来处理,而不是根构建文件。
总结
此过程可以无限重复以添加更多子项目
root
├── settings.gradle(.kts) (1)
├── app (2)
│ ├── build.gradle(.kts)
│ └── src/
├── library-a (3)
│ ├── build.gradle(.kts)
│ └── src/
├── library-b (4)
│ ├── build.gradle(.kts)
│ └── src/
└── library-c (5)
├── build.gradle(.kts)
└── src/
1 | 定义子项目 |
2 | 应用程序模块 |
3 | 一个共享库模块 |
4 | 另一个库模块 |
5 | 又一个库模块 |
通过遵循这些步骤,您可以模块化您的项目,提高可维护性,并实现并行执行。
如果您希望您的某个库成为其自己的构建,则应考虑使用复合构建(即,包含的构建)而不是。