Skip to content

依赖管理与版本目录

源:Gradle Version Catalogs

在 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 按以下顺序解析依赖:

  1. 本地缓存 (~/.gradle/caches)
  2. 本地仓库 (如 mavenLocal())
  3. 远程仓库 (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:定期更新依赖

建立依赖更新流程:

  1. 每月运行 dependencyUpdates
  2. 优先更新安全补丁
  3. 在测试环境验证新版本
  4. 记录重大版本变更

❌ 避免直接引用传递依赖

kotlin
// ❌ 不要依赖传递依赖
implementation("com.squareup.okhttp3:okhttp:4.12.0") // ktor 内部已包含

// ✅ 明确声明直接依赖
implementation(libs.ktor.client.core)

依赖版本查询

Kotlin 生态主要库

最新版本查询
Kotlinhttps://github.com/JetBrains/kotlin/releases
Kotlinx Coroutineshttps://github.com/Kotlin/kotlinx.coroutines/releases
Kotlinx Serializationhttps://github.com/Kotlin/kotlinx.serialization/releases
Ktorhttps://github.com/ktorio/ktor/releases
SQLDelighthttps://github.com/cashapp/sqldelight/releases
Koinhttps://github.com/InsertKoinIO/koin/releases

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 项目在多平台间的依赖一致性,减少版本冲突,提升构建稳定性。