# 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`。