第3章 项目与模块声明

3.1 核心概念

Gradle 多模块项目以 settings.gradle.kts 为入口声明项目结构。该文件定义了:

  • 项目名称:通过 rootProject.name 设置,影响 Gradle 缓存路径和发布坐标。
  • 模块注册:使用 include 将子模块纳入构建,支持路径映射和动态侦测。
  • 模块路径映射:include(":app") 默认映射到 app/ 目录,也可用 include(":lib:core") 映射到 lib/core/。

3.2 实现流程

初始化多模块项目需按以下步骤操作:

  1. 创建根目录,生成 settings.gradle.kts、build.gradle.kts 和 gradle/wrapper/。
  2. 在 settings.gradle.kts 中声明 rootProject.name 和子模块。
  3. 为每个子模块创建独立目录,并在其目录内放置 build.gradle.kts。
  4. 执行 gradle projects 验证模块层级。

3.3 配置详解

以下为典型 settings.gradle.kts 配置:

rootProject.name = "MyApp"

include(":app")
include(":lib:core")
include(":lib:utils")
include(":tests:unit")
include(":tests:integration")

模块路径与目录结构的对应关系:

include 参数实际目录(相对根)
:appapp/
:lib:corelib/core/
:lib:utilslib/utils/
:tests:unittests/unit/
:tests:integrationtests/integration/

若需重定向模块目录,使用 include 的第二个参数:

include(":my-module")
project(":my-module").projectDir = file("custom-dir/my-module")

3.4 多模块项目初始化命令

Gradle 提供 init 任务快速搭建多模块骨架:

mkdir MyMultiModuleProject && cd MyMultiModuleProject
gradle init --type multi-module --dsl kotlin

交互式向导会提示输入根项目名和子模块列表。生成后查看 settings.gradle.kts:

rootProject.name = "MyMultiModuleProject"

include("app", "list", "utilities")

3.5 调试与验证

使用以下任务诊断模块声明:

  • gradle projects:显示完整模块树。
  • gradle :app:dependencies 查看子模块依赖。
  • gradle --build-cache 启用缓存后,检查输出目录是否包含 rootProject.name。

常见错误及解决方法:

错误信息原因修复
Project with path ':app' not found模块未在 settings 中 include添加 include(":app")
Cannot add task ':app:build' as a task with that name already exists同名模块冲突检查是否有重复 include 或命名冲突
Root project 'x' does not match rootProject.name 'y'目录名与 rootProject.name 不一致调整项目目录名或修改 rootProject.name

3.6 性能与稳定性优化

多模块项目声明直接影响构建性能:

  • 减少不必要的模块:只 include 必须的子模块,避免大量模块导致配置阶段变慢。
  • 使用懒加载:通过 includeBuild 引用复合构建时,确保版本对齐。
  • 固定根项目名称:避免在 CI 中因目录名动态变化导致缓存失效。
  • 启用配置缓存:Gradle 7.6+ 支持 --configuration-cache,需确保 settings 无动态缺陷。

3.7 模块路径映射结构图

下图展示了典型多模块项目的声明与目录映射关系:

多模块项目模块映射示意图 rootProject.name = "MyApp" :app :lib:core :lib:utils :tests:unit 对应目录:lib/core/ lib/utils/ 等 📌 每个子模块目录下必须存在 build.gradle.kts 文件,否则 Gradle 会报配置错误

3.8 实战案例:声明一个微服务项目

假设项目包含服务网关、订单服务和用户服务,目录结构如下:

cloud-app/
├── settings.gradle.kts
├── build.gradle.kts          # 根项目构建文件(极少配置)
├── gateway/
│   └── build.gradle.kts
├── order-service/
│   └── build.gradle.kts
└── user-service/
    └── build.gradle.kts

对应的 settings.gradle.kts:

rootProject.name = "cloud-app"

include(":gateway")
include(":order-service")
include(":user-service")

若要使用子模块扁平化命名(如 :order 对应目录 order-service),可添加目录映射:

include(":order")
project(":order").projectDir = file("order-service")

3.9 常见陷阱与避坑

❌ 错误: 使用 include ":app"(带空格)→ Gradle 会忽略空白,但仍建议无空格。
✅ 最佳实践: 所有子模块使用小写及连字符,避免驼峰;每个模块声明一行,便于版本控制。
🔍 调试命令: 执行 gradle projects --info 可查看每个模块的路径和 projectDir 实际值。

3.10 小结

本章详述了通过 settings.gradle.kts 声明项目和模块的核心机制。掌握 rootProject.name、include 及其路径映射,是构建稳定多模块 Gradle 项目的基础。合理规划和声明模块直接影响到构建性能、缓存命中率和团队协作效率。