鸿蒙 uts 插件加密盲区:一个后缀,让 .ets 混编源码不再裸奔
鸿蒙 uts 插件加密盲区:一个后缀,让 .ets 混编源码不再裸奔
适用场景:uni-app x + HarmonyOS NEXT + uts 插件 + ArkTS 声明式 UI 混编(native-view / @Builder)
关键词:uts 插件、付费插件加密、鸿蒙混编、ets、native-view
一、背景:鸿蒙原生 UI 必须写进 uts 插件的"混编文件"
uni-app x 编译到鸿蒙(4.31+ JSVM 架构)后,uvue 页面跑在 JSVM 里,不能直接调用鸿蒙原生 API。想用系统级能力(比如原生材质、原生组件、沉浸光感),标准路径只有一个:
- uvue 里放
native-view组件; - uts 插件里通过
bindHarmonyWrappedBuilder挂载 ArkTS 的@Builder声明式 UI; - 原生事件通过
dispatchEvent回传给 uvue。
而 ArkUI 声明式界面(@Builder、Column(){} 这类 DSL)不能写在 .uts 里,官方文档《uts for HarmonyOS》写得很明确:
“uts 插件内的 ets 文件会原样拷贝到产物内,如果需要开发 ArkUI 声明式界面可以在 ets 文件内编写,uts 文件内引用。”
于是插件目录会长这样:
utssdk/app-harmony/
├── index.uts // 逻辑入口,import "./builder.ets"
└── builder.ets // @Builder 声明式 UI(原样拷贝进鸿蒙工程)
问题,就出在这个"原样拷贝"上。
二、发现:付费插件的加密规则,漏掉了鸿蒙 ets 文件
如果你把插件发布为付费插件,DCloud 插件市场会提供自动加密保护。《制作和发布插件指南》里写的加密规则是:
- 加密除
interface.uts之外的所有 uts 文件- 加密
utssdk/app-android及utssdk/app-ios目录下的 java、kt、swift 等混编文件
对照一下就很清楚了:
| 文件 | 是否被加密 |
|---|---|
xxx.uts | ✅ 所有 uts 文件都在范围内 |
app-android/*.kt、app-ios/*.swift | ✅ 规则第二条覆盖 |
app-harmony/builder.ets | ❌ 两条规则都不沾 |
它既不是 .uts 文件,又不在 app-android / app-ios 目录里。结果是:付费插件加密之后,builder.ets 依然是明文——变量名、业务逻辑、甚至中文注释全都原样暴露,付费插件的知识产权保护形同虚设。
这显然是个规则盲区:混淆点在于,鸿蒙混编文件的官方定位叫"ets 文件",而加密工具的匹配口径是"uts 文件"。
三、解法:给文件加一个 .uts 后缀
改一个文件名就够了:
utssdk/app-harmony/
├── index.uts
└── builder.ets.uts // ← 原来叫 builder.ets
index.uts 里的 import 写法保持原样,不需要改:
import { buildNativeTabBar, changeTabIndex } from "./builder.ets"
实测结果:
- 加密命中:文件以
.uts结尾,落入"除 interface.uts 外的所有 uts 文件"规则,付费插件加密后源码不可读; - 编译正常:HBuilderX 编译通过,无报错;
- 运行正常:真机上原生 UI 渲染、交互与改名前完全一致。
也验证过另一种目录写法,同样可行(适合一个模块拆多文件的场景):
utssdk/app-harmony/
├── index.uts // import "./builder/index.ets"
└── builder/
└── index.ets.uts
import 写成 "./builder/index.ets" 即可。
四、为什么两头都能跑通?
加密侧很好理解:规则按文件后缀匹配,xxx.ets.uts 以 .uts 结尾,自然被"所有 uts 文件"这条规则兜住。
编译侧则是因为 builder.ets.uts 已经不是"原样拷贝"的混编文件,而是进入了 UTS 编译链。这一点在编译产物里可以直接验证——产物目录里的这个文件仍然叫 builder.ets,但内容已带上了编译器注入的 sourceMap 注释:
// 源文件 builder.ets.uts
console.log(`[NATIVE-TABBAR] changeIndex -> ${index}`)
// 产物 builder.ets(编译后)
console.log(`[NATIVE-TABBAR] changeIndex -> ${index}`, " at .../builder.ets:52")
同时 index.ets 产物中的 import 会被规范化为模块名引用:
// 源 index.uts
import { buildNativeTabBar, changeTabIndex } from "./builder.ets"
// 产物 index.ets
import { buildNativeTabBar, changeTabIndex } from "./builder"
也就是说:文件后缀负责"被加密",编译器负责"把 ets 语义原样带进产物",两者互不冲突。对插件使用者而言,加密版插件照常走云端解密编译流程,功能不受影响。
五、注意事项
- 本质是规则边界的务实用法,不是官方文档写法。官方后续若补全鸿蒙 ets 的加密规则,可以改回
builder.ets;目前保持双后缀也无副作用(已实测)。 - 文件进入 UTS 编译链后,需要同时满足 uts 与 ArkTS 两套语法约束。纯声明式 UI 实测没有问题,但如果你后续在文件里使用了较新的 ArkTS 语法,务必重新编译验证。
interface.uts按官方设计不加密,敏感信息不要写在那里。- 鸿蒙 uts 付费插件要求 HBuilderX 4.81+,且加密插件只能走云端传统打包(不支持离线打包、安心打包);鸿蒙平台需要云端编译。
- 发布前记得自查:以加密版(或试用版)跑一次编译,确认目标文件确实不可读。
六、小结
一句话总结:把鸿蒙混编的 builder.ets 改名为 builder.ets.uts,import 不变,加密生效,功能照常。
这个坑不算深,但确实会让付费插件作者白掉一层"保护壳"——希望这篇记录能帮到同样在鸿蒙上做原生 UI 混编的开发者。如果官方后续修正了加密规则,欢迎回来改回单后缀。
更多推荐




所有评论(0)