调用完成打印

在这里插入图片描述

概述

本文介绍如何使用 Kotlin Multiplatform (KMP) 项目在 Windows 和 macOS 上编译生成 JavaScript 文件,并将其集成到鸿蒙项目中调用。

KMP 是什么?

Kotlin Multiplatform (KMP) 是 JetBrains 推出的跨平台开发框架,允许开发者用 Kotlin 编写一次代码,编译到多个平台。与 Flutter 不同的是:

  • KMP 关注业务逻辑层:主要用于共享中层业务逻辑、数据处理、网络请求等
  • 不负责 UI 层:UI 部分由各平台独立实现(Android、iOS、Web、HarmonyOS 等)
  • 灵活的编译目标:可编译为 JavaScript、Native、JVM 等多种格式

在本场景中,我们利用 KMP 编译到 JavaScript,使得鸿蒙项目可以调用共享的业务逻辑。


项目结构

kjsdemo-master/
├── src/                          # 共享代码(KMP 源码)
│   └── commonMain/
│       └── kotlin/               # Kotlin 业务逻辑
├── kmp_ceshiapp/                 # 鸿蒙项目
│   └── entry/
│       └── src/
│           ├── main/
│           │   ├── ets/          # HarmonyOS 代码
│           │   └── resources/
│           └── libs/             # 放置生成的 JS 文件
├── build.gradle.kts              # 项目配置
└── gradle.properties             # Gradle 属性

前置要求

Windows 环境

  • Java Development Kit (JDK):版本 11 或更高
  • Gradle:项目已包含 Gradle Wrapper
  • Node.js:版本 14 或更高(用于 JavaScript 编译)

macOS 环境

  • Java Development Kit (JDK):版本 11 或更高
  • Gradle:项目已包含 Gradle Wrapper
  • Node.js:版本 14 或更高
  • Xcode Command Line Tools(可选,某些编译场景需要)

步骤一:获取项目

Windows 上获取项目

# 1. 克隆或下载项目
git clone <repository-url>
cd kjsdemo-master

# 2. 验证 Gradle 环境
gradlew --version

macOS 上获取项目

# 1. 克隆或下载项目
git clone <repository-url>
cd kjsdemo-master

# 2. 验证 Gradle 环境
./gradlew --version

步骤二:编译生成 .d.ts 和 .mjs 文件

Windows 编译步骤

# 1. 进入项目根目录
cd d:\flutter_Obj\kjsdemo-master

# 2. 清理之前的构建
gradlew.bat clean

# 3. 编译 JavaScript 目标
gradlew.bat build -x test

# 4. 查找生成的文件
# 生成的文件通常位于:
# build/js/packages/kjsdemo/kotlin/

macOS 编译步骤

# 1. 进入项目根目录
cd /path/to/kjsdemo-master

# 2. 清理之前的构建
./gradlew clean

# 3. 编译 JavaScript 目标
./gradlew build -x test

# 4. 查找生成的文件
# 生成的文件通常位于:
# build/js/packages/kjsdemo/kotlin/

编译输出说明

编译成功后,你会看到以下文件:

文件类型 说明
.mjs ES6 模块格式的 JavaScript 文件,包含编译后的 Kotlin 代码
.d.ts TypeScript 定义文件,提供类型提示和 IDE 支持

步骤三:处理生成的文件

3.1 定位生成文件

编译完成后,在以下目录查找生成的文件:

build/
└── js/
    └── packages/
        └── kjsdemo/
            └── kotlin/
                ├── kjsdemo.mjs          # 主要的 JavaScript 文件
                ├── kjsdemo.d.ts         # TypeScript 定义文件
                └── ...其他文件

3.2 将 .mjs 转换为 .js

鸿蒙项目通常使用 .js 扩展名。将 .mjs 文件重命名为 .js

Windows 命令行:

ren build\js\packages\kjsdemo\kotlin\kjsdemo.mjs kjsdemo.js

macOS/Linux 命令行:

mv build/js/packages/kjsdemo/kotlin/kjsdemo.mjs build/js/packages/kjsdemo/kotlin/kjsdemo.js

或者直接复制时重命名:

Windows PowerShell:

Copy-Item "build\js\packages\kjsdemo\kotlin\kjsdemo.mjs" -Destination "kmp_ceshiapp\entry\src\main\ets\libs\kjsdemo.js"

macOS/Linux:

cp build/js/packages/kjsdemo/kotlin/kjsdemo.mjs kmp_ceshiapp/entry/src/main/ets/libs/kjsdemo.js

步骤四:集成到鸿蒙项目

4.1 复制文件到鸿蒙项目

将生成的 .js 文件复制到鸿蒙项目的合适位置:

kmp_ceshiapp/
└── entry/
    └── src/
        └── main/
            └── ets/
                └── libs/                 # 创建此目录(如不存在)
                    ├── kjsdemo.js        # 复制的 JS 文件
                    └── kjsdemo.d.ts      # 可选:TypeScript 定义文件

4.2 在鸿蒙代码中调用

.ets 文件中导入并使用 KMP 编译的 JavaScript:

// pages/Index.ets

import { someFunction, SomeClass } from '../libs/kjsdemo';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    Column() {
      Text(this.message)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
      
      Button('调用 KMP 函数')
        .onClick(() => {
          // 调用 KMP 编译的 JavaScript 函数
          const result = someFunction('参数');
          this.message = result;
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

4.3 处理模块导入

如果遇到模块导入问题,可能需要调整 build.gradle.kts 中的 JavaScript 编译配置:

// build.gradle.kts 示例配置
kotlin {
    js(IR) {
        browser {
            // 配置浏览器目标
        }
        binaries.executable()
    }
}

常见问题排查

问题 1:找不到生成的 .mjs 文件

原因:编译未成功或输出目录不同

解决方案

# 查看完整的编译输出
gradlew build --info

# 搜索 .mjs 文件
# Windows
dir /s *.mjs

# macOS/Linux
find . -name "*.mjs"

问题 2:鸿蒙项目无法识别导入的 JS 模块

原因:模块路径错误或 TypeScript 配置问题

解决方案

  • 确认文件路径正确
  • 检查 tsconfig.json 中的 moduleResolution 设置
  • 尝试使用相对路径导入

问题 3:编译时出现 Gradle 错误

原因:JDK 版本不兼容或依赖缺失

解决方案

# 检查 JDK 版本
java -version

# 清理 Gradle 缓存
gradlew clean --refresh-dependencies

# 重新编译
gradlew build

完整工作流总结

Windows 完整流程

# 1. 进入项目目录
cd d:\flutter_Obj\kjsdemo-master

# 2. 清理并编译
gradlew clean build -x test

# 3. 定位生成文件
dir build\js\packages\kjsdemo\kotlin\*.mjs

# 4. 复制并转换
Copy-Item "build\js\packages\kjsdemo\kotlin\kjsdemo.mjs" `
  -Destination "kmp_ceshiapp\entry\src\main\ets\libs\kjsdemo.js"

# 5. 在鸿蒙项目中导入使用

macOS 完整流程

# 1. 进入项目目录
cd /path/to/kjsdemo-master

# 2. 清理并编译
./gradlew clean build -x test

# 3. 定位生成文件
find build/js/packages/kjsdemo/kotlin -name "*.mjs"

# 4. 复制并转换
cp build/js/packages/kjsdemo/kotlin/kjsdemo.mjs \
   kmp_ceshiapp/entry/src/main/ets/libs/kjsdemo.js

# 5. 在鸿蒙项目中导入使用

最佳实践

  1. 版本管理:为生成的 JS 文件添加版本号,便于追踪更新

    kjsdemo-v1.0.0.js
    kjsdemo-v1.0.1.js
    
  2. 自动化脚本:创建编译脚本自动化上述流程

    # build.sh (macOS/Linux)
    #!/bin/bash
    ./gradlew clean build -x test
    cp build/js/packages/kjsdemo/kotlin/kjsdemo.mjs \
       kmp_ceshiapp/entry/src/main/ets/libs/kjsdemo.js
    
  3. 错误处理:在鸿蒙代码中添加错误处理

    try {
      const result = someFunction('参数');
    } catch (error) {
      console.error('调用 KMP 函数失败:', error);
    }
    
  4. 类型安全:使用 TypeScript 定义文件获得更好的类型提示

    import type { SomeClass } from '../libs/kjsdemo.d.ts';
    

总结

通过 KMP 的 JavaScript 编译能力,我们可以:

✅ 在 Windows 和 macOS 上统一编译业务逻辑
✅ 生成标准的 JavaScript 文件供鸿蒙项目使用
✅ 避免代码重复,提高开发效率
✅ 保持业务逻辑的一致性

这种方案特别适合需要在多个平台共享业务逻辑的项目,而无需像 Flutter 那样处理整个 UI 层的复杂性。

项目示例:https://gitcode.com/nutpi/kmp_openharmony

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐