当您的 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

settings.gradle.kts
rootProject.name = "root"
include("app", "library")
settings.gradle
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 子项目

app/build.gradle.kts
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"
}
app/build.gradle
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 子项目所需的所有依赖项和配置

library/build.gradle.kts
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")
}
library/build.gradle
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)

build.gradle.kts
plugins {
    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.21" apply false
}

subprojects {
    repositories {
        mavenCentral()
    }
}
build.gradle
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 又一个库模块

通过遵循这些步骤,您可以模块化您的项目,提高可维护性,并实现并行执行。

如果您希望您的某个库成为其自己的构建,则应考虑使用复合构建(即,包含的构建)而不是。