依赖管理与版本目录
在 Kotlin Multiplatform 项目中,依赖管理比单平台项目更复杂,因为需要同时处理共享代码依赖和平台特定依赖。版本目录(Version Catalog)是 Gradle 7.0+ 推荐的依赖管理方式,可以有效解决依赖版本一致性问题。
版本目录基础
配置示例
toml
[versions]
kotlin = "2.3.0"
compose = "1.7.6"
kotlinx-coroutines = "1.9.0"
kotlinx-serialization = "1.7.3"
ktor = "3.0.3"
sqldelight = "2.0.2"
[libraries]
# Kotlin 标准库
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
# Kotlinx 库
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
# Ktor 网络库
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
# SQLDelight 数据库
sqldelight-runtime = { module = "app.cash.sqldelight:runtime", version.ref = "sqldelight" }
sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" }
sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
sqldelight-native-driver = { module = "app.cash.sqldelight:native-driver", version.ref = "sqldelight" }
[plugins]
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
android-application = { id = "com.android.application", version = "8.8.0" }
android-library = { id = "com.android.library", version = "8.8.0" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
[bundles]
ktor-common = ["ktor-client-core", "ktor-client-content-negotiation", "ktor-serialization-kotlinx-json"]kotlin
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.sqldelight)
}
kotlin {
sourceSets {
commonMain.dependencies {
// 使用 libs 引用
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
// 使用 bundle 批量引入
implementation(libs.bundles.ktor.common)
implementation(libs.sqldelight.runtime)
implementation(libs.sqldelight.coroutines)
}
androidMain.dependencies {
implementation(libs.kotlinx.coroutines.android)
implementation(libs.ktor.client.android)
implementation(libs.sqldelight.android.driver)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
implementation(libs.sqldelight.native.driver)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
}
}kotlin
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}依赖类型与作用域
API vs Implementation
kotlin
sourceSets {
commonMain.dependencies {
// API:会传递给依赖当前模块的模块
api(libs.kotlinx.coroutines.core)
// Implementation:不会传递
implementation(libs.ktor.client.core)
// CompileOnly:仅编译时可用,不打包
compileOnly(libs.annotations)
}
}选择建议:
- ✅ 使用
api:当依赖是公共 API 的一部分 - ✅ 使用
implementation:内部实现细节 - ✅ 使用
compileOnly:仅用于编译时检查的注解
平台特定依赖
kotlin
sourceSets {
val commonMain by getting {
dependencies {
// 所有平台共享
implementation(libs.ktor.client.core)
}
}
val androidMain by getting {
dependencies {
// 仅 Android
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.kotlinx.coroutines.android)
}
}
val iosMain by getting {
dependencies {
// 仅 iOS (Native 库通常通过 cinterop)
}
}
}版本冲突处理
强制统一版本
kotlin
configurations.all {
resolutionStrategy {
// 强制所有模块使用指定版本
force("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
}
}排除传递依赖
kotlin
commonMain.dependencies {
implementation(libs.some.library) {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk7")
}
}平台特定版本覆盖
toml
[versions]
androidx-lifecycle = "2.8.7"
[libraries]
# Android 需要特定版本
androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }依赖解析策略
依赖解析顺序
Gradle 按以下顺序解析依赖:
- 本地缓存 (
~/.gradle/caches) - 本地仓库 (如
mavenLocal()) - 远程仓库 (
mavenCentral(),google()等)
配置仓库
kotlin
// settings.gradle.kts
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google {
content {
// 仅从 Google 仓库解析 Android 库
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
// 私有仓库
maven {
url = uri("https://your-company.com/maven")
credentials {
username = properties["mavenUser"] as String?
password = properties["mavenPassword"] as String?
}
}
}
}常用依赖配置模式
模式 1:KMP 网络层
toml
[versions]
ktor = "3.0.3"
[libraries]
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" }
ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
[bundles]
ktor-common = [
"ktor-client-core",
"ktor-client-content-negotiation",
"ktor-serialization-kotlinx-json",
"ktor-client-logging",
"ktor-client-auth"
]模式 2:KMP 数据库层
toml
[versions]
sqldelight = "2.0.2"
[libraries]
sqldelight-runtime = { module = "app.cash.sqldelight:runtime", version.ref = "sqldelight" }
sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" }
sqldelight-android-driver = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
sqldelight-native-driver = { module = "app.cash.sqldelight:native-driver", version.ref = "sqldelight" }
sqldelight-primitive-adapters = { module = "app.cash.sqldelight:primitive-adapters", version.ref = "sqldelight" }
[bundles]
sqldelight-common = ["sqldelight-runtime", "sqldelight-coroutines"]模式 3:KMP 依赖注入
toml
[versions]
koin = "4.0.1"
[libraries]
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }
koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" }依赖更新策略
查找可更新的依赖
使用 Gradle Versions Plugin:
kotlin
plugins {
id("com.github.ben-manes.versions") version "0.51.0"
}bash
./gradlew dependencyUpdates版本号管理规范
toml
[versions]
# 主版本.次版本.修订版本
kotlin = "2.3.0" # 使用最新稳定版
kotlinx-coroutines = "1.9.0" # 使用最新稳定版
ktor = "3.0.3" # 建议锁定次版本,仅更新修订版建议:
- 🔒 核心依赖(Kotlin, Coroutines):锁定次版本
- 🔄 工具库(Ktor, SQLDelight):可主动升级次版本
- ⚠️ 实验性依赖:明确标注并慎重使用
最佳实践
✅ 实践 1:集中管理版本
所有版本号统一在 libs.versions.toml 中定义,避免硬编码:
kotlin
// ❌ 不推荐
implementation("io.ktor:ktor-client-core:3.0.3")
// ✅ 推荐
implementation(libs.ktor.client.core)✅ 实践 2:使用 Bundles 批量引入
toml
[bundles]
ktor-common = ["ktor-client-core", "ktor-client-logging", "ktor-serialization-kotlinx-json"]
compose-ui = ["compose-ui", "compose-foundation", "compose-material3"]✅ 实践 3:平台依赖分离
kotlin
// ✅ 清晰的依赖分离
commonMain.dependencies {
implementation(libs.ktor.client.core) // 跨平台核心
}
androidMain.dependencies {
implementation(libs.ktor.client.android) // Android 引擎
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin) // iOS 引擎
}✅ 实践 4:定期更新依赖
建立依赖更新流程:
- 每月运行
dependencyUpdates - 优先更新安全补丁
- 在测试环境验证新版本
- 记录重大版本变更
❌ 避免直接引用传递依赖
kotlin
// ❌ 不要依赖传递依赖
implementation("com.squareup.okhttp3:okhttp:4.12.0") // ktor 内部已包含
// ✅ 明确声明直接依赖
implementation(libs.ktor.client.core)依赖版本查询
Kotlin 生态主要库
Maven Central 搜索
直接访问:https://search.maven.org/
或使用命令行工具:
bash
# 安装 Maven Search CLI
brew install maven-search
# 搜索最新版本
maven-search "io.ktor:ktor-client-core"依赖分析与优化
查看依赖树
bash
# 查看 commonMain 依赖树
./gradlew :shared:dependencies --configuration commonMainImplementationDependenciesMetadata
# 查看 androidMain 依赖树
./gradlew :shared:dependencies --configuration androidMainImplementationDependenciesMetadata识别重复依赖
bash
# 查找重复类
./gradlew :shared:checkDuplicateClasses减少依赖体积
kotlin
// 排除不必要的传递依赖
implementation(libs.some.library) {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect")
}通过规范化的依赖管理,可以确保 KMP 项目在多平台间的依赖一致性,减少版本冲突,提升构建稳定性。