大家好,我是你的 Kotlin 跨平台小助手。 今天来介绍一下 JetBrains 发布的 KMP 的新默认项目结构,相信很多同学打开 IDE 新建项目时都愣了一下:我的 composeApp 呢? 别慌,这篇给你把所有变化讲清楚,5 分钟看完,照着迁移就行。
有没有遇到过这些情况?
❌ 想改个 Android 打包配置,翻了半天 build.gradle.kts 找不到哪段是共用的、哪段是平台的 ❌ 项目要加个 iOS 原生 UI,发现结构全乱了,shared 和 composeApp 要重新拆 ❌ Gradle sync 慢得要死,一个模块里塞了 N 个 source set
如果你中了任何一条,恭喜你——这次的结构变化,就是为你准备的。
今天这篇文章把 KMP 新结构讲透:
看完直接就能用。
先给你看最直观的变化。
myProject/
└── composeApp/ # 啥都管的"万能模块"
├── src/
│ ├── androidMain/
│ ├── commonMain/
│ ├── desktopMain/
│ ├── jsMain/
│ └── iosMain/
└── build.gradle.kts # 几百行配置,看到头大旧结构的问题:
myProject/
├── shared/ # 只做一件事:共享代码
│ └── src/
│ ├── androidMain/
│ ├── commonMain/
│ ├── desktopMain/
│ ├── jsMain/
│ └── iosMain/
├── androidApp/ # Android 专属入口
├── desktopApp/ # Desktop 专属入口
├── webApp/ # Web 专属入口
└── iosApp/ # iOS 本来就在这新结构的好处:
💡 好的架构,应该让你不用思考就知道代码放哪。
每次改结构都会有人喊"又折腾",但这次真不是为了改而改。
想象一下:一个类里同时写 UI、网络请求、数据存储,你肯定会说这是坏味道。
那一个 Gradle 模块同时做:
这不是坏味道吗?
拆分后,shared 只管共享代码,各平台 app 管自己的打包。单一职责原则,放到哪都对。
发现没有?iOS 因为要用 Xcode,一直都是独立的 iosApp 文件夹。
这就造成了不对称:
现在统一了,所有平台应用都在独立模块,舒服了。
这个是重点,敲黑板。
Android Gradle Plugin 9.0 开始,不再支持在 multiplatform 模块里应用 application 插件。
翻译成人话:你的 Android app 代码,必须放在一个纯 Android 的模块里,不能放在 multiplatform 模块里。
这不是 JetBrains 想改,是 Android 强制要求的。
❗️ 划重点:就算你不想用新结构,只要升级 AGP 9.0,这一步也必须做。
JetBrains 新出的 Amper 构建工具,因为每个 module 只能有一个 product,天然就是用的"共享库 + 各平台独立应用"的结构。
现在 Gradle 项目也统一了,两种构建工具的用户体验一致,切换成本更低。
JetBrains 在设计时,心里装着这 3 个目标:
以后新人进项目,你不用解释半小时了:
sharedandroidAppdesktopAppiosApp就这么简单。
之前的结构很分裂:
现在不管你怎么选,结构都一样。
选哪些平台、加不加服务端、用不用原生 UI,项目结构的模式永远不变。
项目小的时候,一个 shared 就够了。
项目大了以后呢?
想拆成 :shared:core、:shared:feature-home、:shared:feature-profile...
新结构下,这些拆分都很自然。旧结构下,你还要纠结 composeApp 拆不拆、怎么拆。
💡 金句:好的架构,在项目增长时不会逼你重构。
新结构不是死的,会根据你的选择自适应。
如果你的 iOS 用 SwiftUI,其他平台用 Compose Multiplatform:
myProject/
├── sharedLogic/ # 所有平台共用,不含 Compose
│ └── 业务逻辑、数据层、网络请求...
├── sharedUI/ # 仅 Compose 平台用,含 Compose
│ └── UI 组件、导航、主题...
├── androidApp/ # 用 sharedUI + sharedLogic
├── desktopApp/ # 用 sharedUI + sharedLogic
└── iosApp/ # 只用 sharedLogic,UI 用 SwiftUI 写判断规则:
所有平台都会用到的代码 → 放
sharedLogic只有 Compose 平台需要的代码 → 放sharedUI
如果你的项目是全栈 Kotlin,还要写服务端:
myProject/
├── core/ # 前后端共享
│ └── 数据模型、验证逻辑、API 接口定义...
├── server/ # 服务端代码
└── app/ # 所有客户端都在这
├── shared/
├── androidApp/
├── desktopApp/
└── iosApp/客户端代码统一放进 app 文件夹,避免和服务端混在一起。
好消息:迁移不是强制的。
✅ 旧项目可以继续用旧结构
❌ 但有个例外
说白了就是:完全不想改也行,但 AGP 9.0 那部分你迟早得动。
想完全迁移到新结构?按这个清单来:
androidApp 模块,把 Android application 配置和入口代码移过去desktopApp、webApp 等模块,把各平台入口移过去composeApp 改名为 shared,只保留 library 配置要获得完整支持,记得升级:
想看看别人怎么写的?这 3 个官方项目可以参考:
项目 | 用途 | 链接 |
|---|---|---|
kotlinconf-app | 官方 KotlinConf 应用,生产级 | GitHub[1] |
KMP-App-Template | 官方应用模板,最佳实践 | GitHub[2] |
RSS Reader | 生产级完整示例 | GitHub[3] |
其他有用链接:
看完这篇,检查一下你掌握了多少:
每次技术变更,都会有人喊"又学新东西"。
但你仔细想想:这次的变化,其实是把我们私下里早就会做的最佳实践,变成了官方默认而已。
有经验的 KMP 开发者,早就开始拆模块了,现在只不过是 JetBrains 帮你把模板做好了而已。
好的工具,会把大家都觉得对的事,变成默认选项。
从这个角度看,KMP 越来越成熟了。
今天的分享就到这里。后续我会持续为大家带来实用的技术干货和前沿的技术资讯。如果你对工具链探索感兴趣,我会在公众号「DevLlama」持续分享前端工程化、构建优化等实战经验,欢迎关注,不要错过任何精彩内容!
支持我们,点赞或分享到朋友圈!
[1] GitHub: https://github.com/JetBrains/kotlinconf-app/
[2] GitHub: https://github.com/Kotlin/KMP-App-Template
[3] GitHub: https://github.com/Kotlin/kmp-production-sample
[4] kmp.new: https://kmp.new
[5] Multiplatform Project Structure: https://kotlinlang.org/docs/multiplatform/multiplatform-project-recommended-structure.html
[6] Update your projects for AGP9: https://blog.jetbrains.com/kotlin/2026/01/update-your-projects-for-agp9/