3.0 KiB
3.0 KiB
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)。
如何新增
- 新模块:建
build.gradle.kts(选对插件 + namespace)+ 空AndroidManifest.xml(Android 模块),在settings.gradle.ktsinclude,在RootPlugin.kt的 allow-list 加一行。 - 新插件:在
convention/build.gradle.kts的gradlePlugin { plugins { register(...) } }注册,并在gradle/libs.versions.toml的[plugins]里加一个mcl-*条目(无 version)。 - 改配置:优先改 helper 函数,让所有适用模块一并生效。
注意:
mcl-android-application与mcl-android-library因有-compose变体(叶子也是前缀),在convention/build.gradle.kts里引用它们的 plugin id 时要用.asProvider().get().pluginId,其余用.get().pluginId。