kuikly-multi-module-config

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Kuikly 多模块工程管理

Kuikly Multi-module Project Management

Contents

Contents

  • When to use multi-module
  • Interactive workflow
  • Configuration overview
  • Critical rules
  • Detailed config references
  • When to use multi-module
  • Interactive workflow
  • Configuration overview
  • Critical rules
  • Detailed config references

何时需要多模块

When to Use Multi-modules

子模块中有 Kuikly 页面(使用了
@Page
注解)才需要多模块设置。若子模块无页面则为普通 KMP 模块,无需特殊配置。
多模块解决的核心问题:多个独立 Kuikly 模块会导致
KuiklyCoreEntry
入口类冲突。
Multi-module setup is only required if the submodule contains Kuikly pages (using the
@Page
annotation). If the submodule has no pages, it is a regular KMP module and no special configuration is needed.
The core problem solved by multi-modules: Multiple independent Kuikly modules will cause conflicts in the
KuiklyCoreEntry
entry class.

交互式工作流

Interactive Workflow

当用户要求创建 Kuikly 子模块时,按以下步骤执行:
When users request to create a Kuikly submodule, follow these steps:

Step 1: 收集信息(⚠️ 必须先完成,不可跳过)

Step 1: Collect Information (⚠️ Must be completed first, cannot be skipped)

🚨 强制规则:在执行任何配置操作之前,必须先向用户询问子模块名称。 即使用户只说了"帮我建一个子模块",也必须先停下来询问子模块要叫什么名字,拿到名称后才能继续。 绝对不要自行假设或编造子模块名称。
向用户询问以下信息(如未提供):
🔴 必须询问(缺一不可,未获得答案前不得执行后续步骤)
  1. 子模块名称 — 问用户:"你的子模块要叫什么名字?"(英文,如
    kuikly_business
  2. 主模块名称 — 可从
    settings.gradle.kts
    中确认,如果无法确定则询问用户(通常是
    demo
    shared
确认名称后,展示以下 checklist:
Task Progress:
- [x] Step 1: 确认子模块名称 → ${用户提供的名称}
- [x] Step 2: 确认主模块名称 → ${确认的主模块名}
- [ ] Step 3: 创建子模块目录和 build.gradle.kts
- [ ] Step 4: 修改 settings.gradle.kts
- [ ] Step 5: 修改主模块 build.gradle.kts(依赖 + KSP 多模块参数)
- [ ] Step 6: 创建子模块 src 目录结构
- [ ] Step 7: 生成示例页面(@Page)
- [ ] Step 8: 检查是否有多套 Gradle 配置(如有则每套都需配置)
🚨 Mandatory Rule: Before performing any configuration operations, you must first ask the user for the submodule name. Even if the user only says "Help me create a submodule", you must stop and ask what name the submodule should have and proceed only after obtaining the name. Never assume or fabricate the submodule name on your own.
Ask the user for the following information if not provided:
🔴 Must Ask (Indispensable, cannot proceed to subsequent steps without answers):
  1. Submodule Name — Ask the user: "What should your submodule be named?" (In English, e.g.,
    kuikly_business
    )
  2. Main Module Name — Can be confirmed from
    settings.gradle.kts
    , if unable to determine, ask the user (usually
    demo
    or
    shared
    )
After confirming the names, display the following checklist:
Task Progress:
- [x] Step 1: Confirm submodule name → ${User-provided name}
- [x] Step 2: Confirm main module name → ${Confirmed main module name}
- [ ] Step 3: Create submodule directory and build.gradle.kts
- [ ] Step 4: Modify settings.gradle.kts
- [ ] Step 5: Modify main module build.gradle.kts (dependencies + KSP multi-module parameters)
- [ ] Step 6: Create submodule src directory structure
- [ ] Step 7: Generate sample page (@Page)
- [ ] Step 8: Check for multiple Gradle configurations (configure each set if present)

Step 2: 执行配置

Step 2: Execute Configuration

按顺序执行以下配置,每步完成后勾选 checklist:
Perform the following configurations in order, and check off the checklist after completing each step:

2.1 settings.gradle.kts

2.1 settings.gradle.kts

在根目录
settings.gradle.kts
中添加子模块 include:
kotlin
include(":${子模块名}")
// 如果主模块有 buildFileName 配置,子模块也需要:
project(":${子模块名}").buildFileName = buildFileName
Add the submodule include in the root directory
settings.gradle.kts
:
kotlin
include(":${submodule name}")
// If the main module has buildFileName configuration, the submodule also needs it:
project(":${submodule name}").buildFileName = buildFileName

2.2 主模块 build.gradle.kts

2.2 Main Module build.gradle.kts

修改主模块,添加两处配置:
kotlin
// 1. commonMain 依赖中添加子模块
kotlin {
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation(project(":${子模块名}"))
            }
        }
    }
}

// 2. ksp 块中配置多模块参数
ksp {
    arg("moduleId", "${主模块名}")
    arg("isMainModule", "true")
    arg("subModules", "${子模块名}")      // 多个子模块用 & 分隔
    arg("enableMultiModule", "true")
}
已有 subModules 时:在现有值后追加
&${子模块名}
,如
"sub1&sub2&${新子模块}"
Modify the main module and add two configurations:
kotlin
// 1. Add submodule to commonMain dependencies
kotlin {
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation(project(":${submodule name}"))
            }
        }
    }
}

// 2. Configure multi-module parameters in the ksp block
ksp {
    arg("moduleId", "${main module name}")
    arg("isMainModule", "true")
    arg("subModules", "${submodule name}")      // Separate multiple submodules with &
    arg("enableMultiModule", "true")
}
When subModules already exists: Append
&${submodule name}
to the existing value, e.g.,
"sub1&sub2&${new submodule}"

2.3 子模块 build.gradle.kts

2.3 Submodule build.gradle.kts

直接复制主模块的
build.gradle.kts
到子模块目录
,然后仅修改以下差异点,其余配置(plugins、targets、cocoapods 等)保持与主模块完全一致。
需要修改的差异点:
kotlin
// 差异 1:ksp 块 — 修改多模块参数
ksp {
    // 其余参数保持不变...
    arg("moduleId", "${子模块名}")       // ← 改为子模块自己的名称
    arg("isMainModule", "false")         // ← 关键:改为 false
    arg("enableMultiModule", "true")
    // ★ 删除 subModules 参数(子模块不需要)
}

// 差异 2:android.namespace — 改为子模块包名
android {
    namespace = "com.tencent.kuikly.${子模块名}"
}

// 差异 3:commonMain dependencies — 移除对其他子模块的依赖(保留 core、compose 等基础依赖)
完整差异清单详见 SUBMODULE_CONFIG.md
Directly copy the main module's
build.gradle.kts
to the submodule directory
, then only modify the following differences, keep other configurations (plugins, targets, cocoapods, etc.) exactly the same as the main module.
Differences to modify:
kotlin
// Difference 1: ksp block — Modify multi-module parameters
ksp {
    // Keep other parameters unchanged...
    arg("moduleId", "${submodule name}")       // ← Change to the submodule's own name
    arg("isMainModule", "false")         // ← Key: Change to false
    arg("enableMultiModule", "true")
    // ★ Remove the subModules parameter (not needed for submodules)
}

// Difference 2: android.namespace — Change to the submodule's package name
android {
    namespace = "com.tencent.kuikly.${submodule name}"
}

// Difference 3: commonMain dependencies — Remove dependencies on other submodules (keep basic dependencies like core, compose, etc.)
See SUBMODULE_CONFIG.md for the complete difference list.

2.4 子模块目录结构

2.4 Submodule Directory Structure

${子模块名}/
├── build.gradle.kts
├── src/
│   ├── commonMain/
│   │   ├── kotlin/com/tencent/kuikly/${子模块名}/
│   │   │   └── pages/          # 放 @Page 页面
│   │   └── assets/             # 资源文件(可选)
│   ├── androidMain/            # 以下 *Main 目录根据主模块架构按需创建
│   │   ├── AndroidManifest.xml
│   │   └── kotlin/
│   ├── iosMain/
│   │   └── kotlin/
│   └── jsMain/
│       └── kotlin/
${submodule name}/
├── build.gradle.kts
├── src/
│   ├── commonMain/
│   │   ├── kotlin/com/tencent/kuikly/${submodule name}/
│   │   │   └── pages/          # Place @Page pages
│   │   └── assets/             # Resource files (optional)
│   ├── androidMain/            # Create the following *Main directories as needed based on the main module architecture
│   │   ├── AndroidManifest.xml
│   │   └── kotlin/
│   ├── iosMain/
│   │   └── kotlin/
│   └── jsMain/
│       └── kotlin/

2.5 AndroidManifest.xml

2.5 AndroidManifest.xml

xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.tencent.kuikly.${子模块名}"/>
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.tencent.kuikly.${submodule name}"/>

2.6 生成示例页面

2.6 Generate Sample Page

在子模块的
pages
目录下创建一个示例页面文件,确保子模块至少有一个
@Page
页面可以验证配置是否正确。
示例页面模板详见 SUBMODULE_CONFIG.md 中的「示例页面模板」章节。
页面文件路径:
${子模块名}/src/commonMain/kotlin/com/tencent/kuikly/${子模块名}/pages/SamplePage.kt
Create a sample page file in the submodule's
pages
directory to ensure the submodule has at least one
@Page
page to verify if the configuration is correct.
See the "Sample Page Template" section in SUBMODULE_CONFIG.md for the sample page template.
Page file path:
${submodule name}/src/commonMain/kotlin/com/tencent/kuikly/${submodule name}/pages/SamplePage.kt

2.7 检查多套 Gradle 配置(如有则每套都需配置)

2.7 Check for Multiple Gradle Configurations (Configure Each Set if Present)

有些项目会为不同平台维护多套 Gradle 配置文件(例如鸿蒙单独使用
build.ohos.gradle.kts
settings.ohos.gradle.kts
),此时需要:
  1. 检查项目根目录和主模块目录,确认是否存在多个
    build.*.gradle.kts
    settings.*.gradle.kts
    文件
  2. 如果存在多套配置,则上述 Step 3~5 的所有修改(子模块
    build.gradle.kts
    settings.gradle.kts
    、主模块 KSP 参数等)都需要在每套配置中重复执行一遍
  3. 子模块也需要对应创建多份
    build.gradle.kts
    (如
    build.ohos.gradle.kts
    ),内容同样基于对应的主模块配置文件复制后修改差异点
💡 判断方法:查看
settings.gradle.kts
中是否有
buildFileName
相关配置,或者主模块目录下是否有多个
build.*.gradle.kts
文件。
鸿蒙平台的具体适配细节详见 MAIN_MODULE_CONFIG.md
Some projects maintain multiple sets of Gradle configuration files for different platforms (e.g., HarmonyOS uses
build.ohos.gradle.kts
and
settings.ohos.gradle.kts
separately). In this case:
  1. Check the project root directory and main module directory to confirm if there are multiple
    build.*.gradle.kts
    or
    settings.*.gradle.kts
    files
  2. If multiple configurations exist, repeat all modifications from Step 3~5 above (submodule
    build.gradle.kts
    ,
    settings.gradle.kts
    , main module KSP parameters, etc.) in each set of configurations
  3. The submodule also needs to create multiple
    build.gradle.kts
    files (e.g.,
    build.ohos.gradle.kts
    ), whose content is also copied from the corresponding main module configuration file and modified for differences
💡 Judgment Method: Check if there is
buildFileName
related configuration in
settings.gradle.kts
, or if there are multiple
build.*.gradle.kts
files in the main module directory.
See MAIN_MODULE_CONFIG.md for specific adaptation details for HarmonyOS.

配置速查表

Configuration Cheat Sheet

配置项主模块子模块
moduleId
主模块名(如
"shared"
子模块名(如
"feature_chat"
isMainModule
"true"
"false"
subModules
所有子模块名,
&
分隔
不需要
enableMultiModule
"true"
"true"
commonMain 依赖
implementation(project(":子模块"))
不依赖主模块
Configuration ItemMain ModuleSubmodule
moduleId
Main module name (e.g.,
"shared"
)
Submodule name (e.g.,
"feature_chat"
)
isMainModule
"true"
"false"
subModules
All submodule names, separated by
&
Not needed
enableMultiModule
"true"
"true"
commonMain dependencies
implementation(project(":submodule"))
No dependency on main module

Critical rules

Critical Rules

❌ 子模块不能单独编译

❌ Submodules Cannot Be Compiled Independently

子模块依赖主模块的
KuiklyCoreEntry
生成,不能独立存在。必须通过主模块编译。
Submodules depend on the
KuiklyCoreEntry
generated by the main module and cannot exist independently. They must be compiled through the main module.

❌ moduleId 必须唯一

❌ moduleId Must Be Unique

每个模块的
moduleId
必须不同,否则 KSP 生成的入口类会冲突。
Each module's
moduleId
must be different, otherwise the entry class generated by KSP will conflict.

❌ subModules 只在主模块配置

❌ subModules Only Configured in Main Module

子模块的 ksp 块中不要配置
subModules
参数。
Do not configure the
subModules
parameter in the ksp block of submodules.

✅ iOS 端无需额外配置

✅ No Additional Configuration Required for iOS

子模块配置了
cocoapods
插件后,Gradle 会自动生成 podspec 文件,无需手动创建。同时,iOS Podfile 中不需要单独 pod 引入子模块,因为子模块会和主模块统一编译生成一个 framework(
shared.framework
)。
After the submodule configures the
cocoapods
plugin, Gradle will automatically generate the podspec file, no manual creation needed. Meanwhile, there is no need to separately import the submodule via pod in the iOS Podfile, because the submodule will be compiled together with the main module into a single framework (
shared.framework
).

✅ 其余配置建议与主模块保持一致

✅ Other Configurations Are Recommended to Be Consistent with Main Module

子模块的 plugins、kotlin targets、cocoapods、android 块等其余配置建议和主模块保持一致,避免因配置差异导致编译或运行时问题。操作方式:直接复制主模块的
build.gradle.kts
,然后仅修改差异清单中列出的项即可。
It is recommended that other configurations of the submodule, such as plugins, kotlin targets, cocoapods, android block, etc., be consistent with the main module to avoid compilation or runtime issues caused by configuration differences. Operation method: Directly copy the main module's
build.gradle.kts
, then only modify the items listed in the difference list.

Detailed guides

Detailed Guides

  • 子模块完整配置模板(build.gradle.kts + 目录结构):SUBMODULE_CONFIG.md
  • 主模块修改指南(依赖、KSP适配):MAIN_MODULE_CONFIG.md
  • Complete submodule configuration template (build.gradle.kts + directory structure): SUBMODULE_CONFIG.md
  • Main module modification guide (dependencies, KSP adaptation): MAIN_MODULE_CONFIG.md