Files
2026-09-03 19:03:34 +08:00

3.0 KiB
Raw Permalink Blame History

DESIGN_NOTES — 约定插件

为什么存在

多模块项目里,compileSdk/minSdk/Java target、Compose、Hilt、Room、Lint、Spotless 等配置若在每个模块重复手写,必然漂移。约定插件把这些配置集中编码,模块只声明"我是什么类型"(mcl.* 插件),不关心"怎么配"。

这也是 harness-engineering 的"严谨性转移":把约束写进确定性规则,而不是依赖记忆。

插件映射

插件 id 实现类 作用
mcl.kotlin.library JvmLibraryConventionPlugin 纯 JVM(kotlin-jvm + jvmTarget 11 + spotless + junit)
mcl.android.library AndroidLibraryConventionPlugin Android 库(application/library 插件的库版 + lint + spotless + compileSdk/minSdk)
mcl.android.library.compose AndroidLibraryComposeConventionPlugin = library + Compose
mcl.android.application.compose AndroidApplicationComposeConventionPlugin = application + Compose
mcl.android.feature AndroidFeatureConventionPlugin = library.compose + hilt + 导航/lifecycle/共享模块依赖
mcl.android.hilt AndroidHiltConventionPlugin KSP + Hilt(hilt-android + hilt-compiler)
mcl.android.room AndroidRoomConventionPlugin KSP + Room(runtime/ktx/compiler + schema 目录)
mcl.android.lint AndroidLintConventionPlugin lint 配置(checkDependencies、disable GradleDependency)
mcl.root RootPlugin 注册 verifyArchitecture

关键实现要点

  • 内置 Kotlin:AGP 9 内置 Kotlin,因此不显式应用 org.jetbrains.kotlin.android;Kotlin 编译选项通过 KotlinAndroidProjectExtension 的 compilerOptions 配置(见 KotlinAndroid.kt)。
  • compose 插件自包含:*.compose 插件先 apply(mcl.android.library/application) 再叠加 Compose,所以模块只需声明 compose 插件一个。
  • helper 函数:KotlinAndroid.kt(SDK/Java/Kotlin)、AndroidCompose.kt(compose feature + BOM + tooling + material3)、Spotless.kt(ktlint,无 license header)拆成独立函数,插件只做编排。
  • libs 访问器:ProjectExtensions.kt 里的 val Project.libs 让插件能引用版本目录(libs.findLibrary/findVersion)。

如何新增

  1. 新模块:建 build.gradle.kts(选对插件 + namespace)+ 空 AndroidManifest.xml(Android 模块),在 settings.gradle.kts include,在 RootPlugin.kt 的 allow-list 加一行。
  2. 新插件:在 convention/build.gradle.kts 的 gradlePlugin { plugins { register(...) } } 注册,并在 gradle/libs.versions.toml 的 [plugins] 里加一个 mcl-* 条目(无 version)。
  3. 改配置:优先改 helper 函数,让所有适用模块一并生效。

注意:mcl-android-application 与 mcl-android-library 因有 -compose 变体(叶子也是前缀),在 convention/build.gradle.kts 里引用它们的 plugin id 时要用 .asProvider().get().pluginId,其余用 .get().pluginId。