Kotlin 单体仓库入门
现代复杂应用程序的开发经常面临代码管理问题。选择单体仓库还是多仓库架构是一个关键的架构决策。在本文中,我们将探讨如何使用最佳实践和现代工具来组织 Kotlin 单体仓库。
单体仓库 (monorepo) 是一种将所有项目、库和服务存储在一个仓库中的方法。对于 Kotlin 开发者来说,这尤其重要,因为 Gradle 构建系统功能强大,并且可以在不同模块之间共享通用代码。
Kotlin 项目单体仓库的优势
在讨论组织方式之前,我们先来看看 Kotlin 单体仓库的主要优势:
- 统一的依赖版本 — 所有模块使用相同版本的 Kotlin、库和插件,从而消除版本冲突。
- 简化的重构 — 对公共库的更改会自动被所有依赖模块验证。
- 集中配置 — 通用 Gradle 设置、linter 和 CI/CD 只需配置一次。
- 原子提交 — 不同模块的相关更改可以在一个提交中完成。
- 代码复用 — 通用工具类、DTO 和业务逻辑可以轻松地被所有项目使用。
使用 Kotlin 和 Gradle 的 Monorepo 结构
让我们看看使用 Gradle Multi-Module 的 Kotlin Monorepo 的最佳目录结构:
my-monorepo/├── build.gradle.kts # 根构建文件├── settings.gradle.kts # 模块配置├── gradle.properties # 通用属性├── gradle/│ └── libs.versions.toml # Version Catalog├── modules/│ ├── common/ # 通用工具和模型│ ├── domain/ # 业务逻辑│ ├── data/ # 数据层 (API, DB)│ ├── service-a/ # 微服务 A│ ├── service-b/ # 微服务 B│ └── shared-test/ # 通用测试工具├── apps/│ ├── backend/ # 主应用程序│ └── cli-tool/ # CLI 工具└── config/ ├── checkstyle/ # Linter 配置 └── docker/ # 服务的 Dockerfile配置 settings.gradle.kts
settings.gradle.kts 文件定义了项目的所有模块:
rootProject.name = "my-monorepo"
// 包含所有模块include( ":modules:common", ":modules:domain", ":modules:data", ":modules:service-a", ":modules:service-b", ":apps:backend", ":apps:cli-tool")
// 版本管理插件pluginManagement { repositories { gradlePluginPortal() mavenCentral() }}使用 Version Catalog (libs.versions.toml)
为了集中管理依赖,我们使用 gradle/libs.versions.toml:
[versions]kotlin = "1.9.22"coroutines = "1.7.3"ktor = "2.3.7"exposed = "0.44.1"
[libraries]kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }
[plugins]kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }common 模块的 build.gradle.kts 示例
plugins { alias(libs.plugins.kotlin.jvm)}
depend