HarmonyKit | 鸿蒙新特性实战:从零构建开发者工具箱

📅 2026/7/6 2:34:24 👁️ 阅读次数 📝 编程学习
HarmonyKit | 鸿蒙新特性实战:从零构建开发者工具箱

HarmonyKit | 鸿蒙新特性实战:从零构建开发者工具箱

引言:一个开发者的移动端困境

去年冬天,我在星巴克紧急排查一个线上问题。生产日志里有一段 Base64 编码的 token,需要解码才能定位。打开手机,搜了三个 “Base64 在线解码” 网站:第一个弹了三个广告,第二个加载了 30 秒还没出结果,第三个解码结果明显错误。最后我不得不打开笔记本,用终端跑echo '...' | base64 -d

那次经历让我开始认真思考一个问题:为什么移动端没有一个像样的开发者工具箱?JSON 格式化、Base64 编解码、时间戳转换——这些在桌面端随手可得的工具,在手机上的体验却如此糟糕。不是没有 App 提供这些功能,是它们几乎全部充斥着广告、内购、隐私收集和拙劣的交互设计。

于是我决定自己做一个。HarmonyKit 的初衷很简单:做一个干净、原生、免费的鸿蒙开发者工具箱。没有广告,没有注册登录,没有网络请求,打开即用。

项目仓库:https://atomgit.com/VON-/harmony-kit

为什么是鸿蒙

选择鸿蒙平台有两个原因,一个理性,一个感性。

理性的原因是:鸿蒙正处于应用生态的快速建设期,开发者工具类应用是稀缺品类。你在 App Store 和 Google Play 上能找到几百个"开发者工具箱",但在鸿蒙应用市场上,这个赛道还几乎空白。与其在红海里卷,不如在蓝海里认真做一个好产品。

感性的原因更私人:我对 HarmonyOS 的技术体系感到好奇。ArkTS 的类型系统、Kit 模块化设计、声明式 UI 框架——这些技术选型背后有一套自洽的设计哲学。与其看文档,不如亲手写一个项目来理解它。

首版目标:5 个工具,一个下午

HarmonyKit 的第一个版本只包含五个工具:JSON 格式化、Base64 编解码、时间戳转换、URL 编解码和哈希计算。选这些工具的标准有三个:

第一,必须是开发者日常使用频率最高的。如果你每周需要至少一次跳转到某个在线工具网站,那它就应该进入候选。

第二,必须是纯算法可以实现的。不需要 Canvas 渲染二维码,不需要 WebSocket 连接服务器,不需要读写本地文件。输入一个字符串,输出一个字符串——这个模型覆盖了 80% 的开发者日常工具需求。

第三,必须能在两小时内完成编码。首版的核心目标是跑通整个项目流程——页面导航、组件复用、工具函数封装——而不是炫技。快速的反馈循环意味着能尽早发现架构问题。

结果五个工具的核心逻辑加起来不到 200 行代码。最复杂的哈希计算用了cryptoFramework.createMd(),Base64 用了util.Base64Helper,JSON 格式化就是JSON.parse+JSON.stringify。鸿蒙的系统 API 足够丰富,第三方库完全没有必要。

第一行 ArkTS 代码

@Entry@Componentstruct Index{build(){Column(){Text('HarmonyKit').fontSize(24).fontWeight(FontWeight.Bold)}.width('100%').height('100%').backgroundColor('#f5f5f5')}}

如果你写过 Flutter、React Native 或者 Compose,这行代码不需要解释。@Entry告诉系统这是一个可路由的页面,@Component声明这是一个 UI 组件,build()返回组件树。声明式 UI 的范式已经跨平台统一了——学习的是一次思维模型,迁移的是具体语法。

但 ArkTS 有一个其他框架没有的特征:严格类型约束build()方法内只能写 UI 组件语法,不能用let声明变量,不能用if (x) {}包裹非 UI 逻辑,不能用匿名对象字面量做类型声明。这个约束一开始让人抓狂,但后来我理解了——它强制你把逻辑从 UI 中剥离。UI 文件只负责"怎么展示",数据转换和业务逻辑必须放在 utils 里或组件方法里。

项目目录结构的设计

HarmonyKit 的源码组织遵循严格的三层分离:

entry/src/main/ets/ ├── model/ # 数据层 ├── utils/ # 逻辑层 ├── components/ # 组件层 └── pages/ # 页面层

这个结构不是一开始就设计好的。最初所有代码挤在两个文件里——Index.ets 和 JsonFormatter.ets——utils 文件夹甚至不存在。随着工具从 5 个增长到 10 个,JsonUtilsBase64UtilsHashUtils这些纯函数自然地从页面文件中抽离出来。

数据层(model)是 HarmonyKit 的"注册中心"。ToolItem接口定义了一个工具的全部元数据——id、名称、描述、图标、颜色、分类、路由路径。添加新工具只需要在TOOL_LIST数组中追加一个对象,然后在pages/tools/下新建一个文件。没有配置中心,没有插件系统,只是一个类型安全的数组。

逻辑层(utils)是最"干净"的代码。所有 util 类都是静态方法,输入字符串输出字符串,不依赖任何 UI 模块。HashUtils.hash()调用的是异步的cryptoFramework,但方法签名也是返回Promise<string>。单元测试只需要实例化类然后传参,完全不需要 mock UI 上下文。

组件层(components)提供了两个可复用组件:ToolCard(工具卡片)和CopyButton(复制按钮)。它们的共同特征是纯@Prop驱动——组件内部没有@State,所有状态由父组件传入。这意味着组件可以在任何上下文中使用,不会因为状态耦合而无法复用。

页面层(pages)是唯一可以同时引用 model、utils 和 components 的地方。页面层承担"组装"职责——从 model 拿工具定义,用 components 搭建 UI,调 utils 处理数据。这种"页面为王"的设计让每个工具页成为一个独立的功能单元。

从编译错误中学习 ArkTS

HarmonyKit 开发中最有价值的经验来自编译错误。我整理了几个最有代表性的:

首先是arkts-no-any-unknown错误。ArkTS 禁止使用anyunknown类型。JSON.parse()的返回值必须显式声明为Object然后转型:

constobj:Object=JSON.parse(input);returnJSON.stringify(objasobject,null,indent);

这个约束看似繁琐,但实际避免了大量运行时类型错误。JSON.parse("42")返回的是 number 不是 object——如果你的代码假设它是 object,没有类型标注的 TypeScript 会静默通过,运行时崩溃。ArkTS 让你在编译期就面对这个问题。

其次是arkts-no-obj-literals-as-types错误。你不能直接在函数返回值、函数参数或ForEach回调中写匿名对象类型:

// 错误functionvalidate():{valid:boolean;error:string}// 正确interfaceValidateResult{valid:boolean;error:string}functionvalidate():ValidateResult

这个约束迫使我为每个数据流转创建了显式接口。意外的好处是:当工具从 5 个增加到 10 个时,所有的接口定义都在 model 和 utils 文件中集中管理,代码可读性远超"随手写一个匿名类型"的方式。

第三个高频错误是arkts-no-untyped-obj-literals。创建对象字面量时,必须明确它对应哪个接口:

// 错误return{valid:true,error:''};// 正确constresult:ValidateResult={valid:true,error:''};returnresult;

构建系统的坑

hvigor 是鸿蒙的构建工具。它有自己的守护进程、增量编译和缓存机制。HarmonyKit 的开发过程中遇到过几个典型问题:

一个诡异的现象是pages/目录下会自动创建.hvigor/outputs/文件夹。这个文件夹是构建缓存,正常情况下应该被.gitignore排除。但如果你的 Git 配置有问题(比如core.worktree指向了错误的路径),这个文件夹会导致构建失败。

另一个常见问题是build-profile.json5中的 SDK 版本声明。targetSdkVersioncompatibleSdkVersion必须与本地安装的 DevEco Studio SDK 版本匹配。HarmonyKit 最初声明的是6.1.1(24),后来发现实际 SDK 版本是6.0.2(22),改回去之后很多"API 不存在"的报错消失了。

还有app_name冲突。AppScope/resources/base/element/string.jsonentry/src/main/resources/base/element/string.json都可能声明app_name。如果两个文件都声明了,编译器会报 warning:'app_name' conflict, first declared。解决方案是只在 AppScope 中保留app_name,entry 的 string.json 不声明。

从 5 个工具到 10 个

首版 5 个工具验证了架构可行性后,第二批 5 个工具(正则测试器、UUID 生成器、颜色转换、进制转换、文本统计)在一个下午完成。

新增一个工具的流程是标准化的:

  1. model/ToolItem.etsTOOL_LIST中追加一个对象
  2. pages/tools/下创建Xxx.ets页面文件
  3. main_pages.json中添加路由
  4. 如果核心逻辑复杂,在utils/下创建对应的工具类

四个步骤,10 分钟。架构对了,加功能就像搭积木。这是 HarmonyKit 整个开发过程中最值得记录的经验——花 70% 的时间做架构设计,后面的功能实现只需要 30% 的时间。

如果反过来——一开始就一把梭写所有工具——结果很可能是 10 个工具页各有各的模式,复制按钮有 3 种写法,错误处理有 5 种风格。重构的代价远大于预先设计的成本。

技术栈全景

HarmonyKit 的技术栈可以用一张表概括:

层面技术用途
UI 框架ArkUI (ArkTS)声明式 UI、组件系统、路由
设计系统HDS (@kit.UIDesignKit)HdsTabs 底部导航、沉浸光感材质
基础能力@kit.ArkUI路由导航、util 工具类
加密@kit.CryptoArchitectureKitMD5/SHA1/SHA256 哈希计算
系统服务@kit.BasicServicesKit剪贴板操作

没有引入任何第三方 npm 包。这不是刻意为之——而是系统 Kit 确实覆盖了 HarmonyKit 需要的所有能力。

写给后来者

如果你也想做一个鸿蒙开发者应用,这里有三个建议:

尽早编译。不要在 IDE 里写完 500 行代码才第一次编译。ArkTS 的编译错误和 TypeScript 差异很大,越早发现越容易定位。

不要和编译器对抗。ArkTS 的严格模式是有意为之的——禁止 any、禁止解构参数、禁止对象字面量类型——与其想办法绕过,不如接受它的设计哲学,你会发现代码质量确实提升了。

多读官方文档。鸿蒙的 API 文档质量正在快速提升。遇到 API 调用问题,先查官方 API Reference 而不是搜索引擎。社区教程可能基于旧版 API,直接复制会踩坑。

HarmonyKit 还在持续演进中。如果你对某个工具的实现有更好的想法,或者想贡献新工具,欢迎提交 PR。

项目仓库:https://atomgit.com/VON-/harmony-kit