Expo 官方不支持鸿蒙?我用一个开源 CLI,让 Expo 项目复用一套代码跑上 HarmonyOS
我们团队的项目深度使用 Expo。靠着它,安卓、iOS 两端已经顺利上线——一套代码、配置即能力、Router、OTA……Expo 基本上把跨端的脏活全包了,开发体验确实香。
但今年鸿蒙来了。业务侧的需求很直接:要一个鸿蒙版,而且要快,最好能复用现有代码。
"复用代码"听起来很美。可真上手才发现一个尴尬的现实:
- 鸿蒙社区有一套 RNOH(React Native OpenHarmony),能把 React Native 跑在鸿蒙上。但它对接的是裸 RN。
- 而我们的项目是深度绑定 Expo 的。Expo 在 RN 之上又加了一整套东西:Expo Router、expo-image、expo-clipboard、config plugin、Expo Modules……这整整一层,官方并没有适配鸿蒙。
换句话说,RNOH 帮我们搭好了「RN → 鸿蒙」的桥,但「Expo → 鸿蒙」这截桥,没人修。
我就是卡在这个缺口上折腾了一阵,然后造出了 expo-harmony-cli。这篇文章就聊聊它是什么、填了哪些坑、以及怎么用。
它是什么
一句话:一条命令,一键初始化一个开箱即跑鸿蒙的 Expo(基于 RN)工程——同一套代码覆盖鸿蒙、iOS、安卓三端,全程沿用 Expo 的 CNG(配置驱动、随时重建)工作流。
它不替换你的 Expo 工作流——安卓、iOS、Web 照常用 Expo 的方式构建发布。它做的事,是在旁边"接"出一个鸿蒙端:注入 Metro 配置、生成鸿蒙原生工程、把你的 Expo 依赖适配到鸿蒙、自动注册原生模块。
一条命令创建项目,剩下鸿蒙那层的适配,它接管。
先铺垫一下:把 Expo 应用跑上鸿蒙,到底要干啥
要理解这个 CLI 的价值,得先知道手动上鸿蒙有多麻烦。
本质上,你得在项目里塞进一整个 harmony/ 原生工程——它的地位,就相当于 android/、ios/ 之于安卓和 iOS。除此之外,还要处理一大堆 JS 依赖的适配:每个 expo-_ 插件、每个 react-native-_ 包,在鸿蒙上未必能直接用,得逐个换包、锁版本、打补丁,甚至有些鸿蒙压根不支持得删掉。
这些活,就是 CLI 要自动化的对象。下面挨个说。
1. 一条命令,创建带鸿蒙基线的 Expo 项目
npx expo-harmony-cli my-harmony-app
这条命令背后跑了四步:拉 Expo SDK 52 模板 → 注入鸿蒙基线(Metro 配置、构建脚本、鸿蒙入口)→ 扫描并适配默认模板里的依赖 → 写入开发文档。
跑完,你拿到的就是一个开箱即跑鸿蒙的纯净 Expo 项目,安卓、iOS 工作流完全不受影响。
2. 核心黑科技:兼容表(compat-table)
这是整个工具的灵魂,也是我最想讲的部分。
手动适配时最烦的就是依赖。CLI 维护了一张兼容表,把每个包按适配方式分类,全自动处理:
| 类型 | 含义 |
|---|---|
bump-native | 升级到鸿蒙兼容版本,并安装鸿蒙原生包 |
native | 安装对应的鸿蒙原生包(含原生注册) |
alias-only | 装 JS 层鸿蒙替代包,无需原生注册 |
patch-only | 锁定版本 + 打补丁 |
remove | 鸿蒙不支持,移除 |
unsupported | 暂未自动适配 |
你装、卸依赖时,CLI 自动查这张表,完成换包 + 锁版本 + 打 patch + 配 alias 全套动作。而且每一对版本都是真机验证过的,你不用自己去踩版本兼容的坑。
想知道哪些包已被覆盖?一条命令查看:
pnpm dlx expo-harmony-cli list
3. 一键生成鸿蒙原生工程
pnpm dlx expo-harmony-cli prebuild --platform harmony
生成整个 harmony/ 工程。里面的配置(oh-package.json5、bundleName、应用名、入口页)都是根据你的 app.json 自动渲染的,不用手动去填那些 json5。
这其实就是 Expo 的 CNG(Continuous Native Generation,持续原生代码生成) 工作流在鸿蒙端的延伸——harmony/ 和 android/、ios/ 一样由配置生成、可随时重新 prebuild 重建,原生代码不进版本库,你永远不必手维护那一堆 json5 和原生文件。
值得一提的是它的平台分流:不带 --platform 时三端(Android/iOS/HarmonyOS)原生工程一起生成;只想调试鸿蒙时,显式加上 --platform harmony 就只走鸿蒙生成器。
4. 原生模块注册自动化(autolinking)
这是鸿蒙适配里最容易漏、漏了就白屏的环节。
每一个带原生能力的鸿蒙包,都要注册到四个文件里:C++ 的 PackageProvider、ArkTS 的 RNOHPackagesFactory、CMake 配置、oh-package.json5。手动改,漏一个文件就构建失败或运行报错。
CLI 的 autolinking 会遍历内置的 HarmonyOS 原生包映射表,并检查对应包是否已安装在 node_modules 中,自动生成并同步这四个文件。不会覆盖你手改的签名和资源——这点很关键,毕竟签名配置是开发者私有的。
5. 依赖的全生命周期,统一交给 CLI 管
正因为适配状态分散在「依赖、patch、alias、原生注册」好几处,所以这几个操作都得走 CLI,否则很容易状态不一致:
pnpm dlx expo-harmony-cli install react-native-svg # 装
pnpm dlx expo-harmony-cli uninstall react-native-svg # 卸(remove 是同义别名)
pnpm dlx expo-harmony-cli scan # 重新扫描对账,回收残留
pnpm dlx expo-harmony-cli sync # 只刷新原生注册,不覆盖 harmony/
CLI 会用一个状态文件(.expo-harmony/managed-state.json)记录"我管了哪些东西"。卸载时只清理自己管理的资产,绝不碰你手工改的配置——这是它设计上很克制的一点。
6. 兜底:兼容表没覆盖的包,怎么办?
这也是我最想分享的一块。
现实是,不可能把所有包都预先适配好。遇到兼容表里没有的包,CLI 项目内嵌了一份给 AI 编码助手用的适配 Skill(.agent/skills/expo-harmony-adapter/SKILL.md)。
它把"怎么把一个 Expo 插件适配到鸿蒙"沉淀成了一套标准化工作流:四种适配方式(打补丁 / Metro alias / 本地包装包 / 业务层适配)、发现鸿蒙插件的渠道、原生模块配置清单、甚至避坑要点……你把它喂给 Claude Code / Codex 这类工具,它就能按这套方法论帮你适配新包。
说白了,这部分就是我个人踩坑经验的结晶。
这个工具是怎么"长"出来的
说起来,expo-harmony-cli 不是一开始就规划好的,它有个演进过程。
最早我是一个一个手动适配项目里用到的 Expo 插件,过程繁琐但好歹跑通了。后来我把这些适配经验整理成了一份 Skill 文档,让 AI 帮我加速适配——这已经省了不少事。
但每次起新项目,还是得把 Metro、原生工程、patch、依赖版本这些基建重新搭一遍。我就想:如果能有个 CLI,一条命令起一个纯净的「Expo for Harmony」项目,把鸿蒙这层基建全搭好,开发者只管把重心放在业务上,该多好。
于是就有了现在这个开源的 expo-harmony-cli。
现状:不是玩具,已经在真实业务里跑通
这套思路我们先在内部验证过:已有的、深度绑定 Expo 的项目,已经完整适配了鸿蒙,复用的就是同一套代码。目前【王牌智剪AI】鸿蒙版已经上架华为应用市场,可以搜索体验。
所以它不是一个 demo 级的玩具。
当前的支持基线:
- Expo SDK 52
- React Native 0.77.1
- RNOH(React Native OpenHarmony)0.77.71
- DevEco Studio 5.0+
也诚实说一下限制:并不是所有 Expo / RN 原生模块都已适配,以 list 命令的输出和项目文档为准;Release 包目前采用 JS rawfile 形式,Hermes HBC 还未作为默认发布格式。
上手很简单
完整流程就几步:
# 1. 创建项目
npx expo-harmony-cli my-harmony-app
cd my-harmony-app
pnpm install
# 2. 生成鸿蒙原生工程
pnpm dlx expo-harmony-cli prebuild --platform harmony
cd harmony && ohpm install && cd ..
# 3. 启动鸿蒙 Metro,然后在 DevEco Studio 里打开 harmony/ 跑起来
pnpm start:harmony
至于安卓、iOS,照常用 Expo 的标准命令,CLI 完全不插手:
npx expo run:android # 构建并安装到安卓设备/模拟器
npx expo run:ios # 构建并安装到 iOS 模拟器/真机
之后装新依赖,记得走 pnpm dlx expo-harmony-cli install <包名>,而不是 expo install 或 pnpm add——这是保证鸿蒙适配状态一致的唯一入口。
写在最后
如果你也在用 Expo / React Native,又面临"要上鸿蒙"的诉求,欢迎试试。鸿蒙生态正在起来,Expo 用户不该被挡在门外——这截「Expo → 鸿蒙」的桥,希望能有更多人一起修。
觉得有用的话,来个 ⭐ 是对开源最大的鼓励;遇到没适配的包、或想一起丰富兼容表,Issue 和 PR 都欢迎。
📦 GitHub:https://github.com/stonehill-2345/expo-harmony-cli
📦 Gitee:https://gitee.com/stonehill-2345/expo-harmony-cli
📦 npm: https://www.npmjs.com/package/expo-harmony-cli
更多推荐

所有评论(0)