全部学科
Python全栈
python
NodeJS全栈
nodejs

uni-app 项目运行到鸿蒙真机:完整操作指南

📅 2026-07-20 uni-app HarmonyOS 鸿蒙 DevEco Studio HBuilderX

uni-app 项目运行到鸿蒙真机:完整操作指南

项目:Vue 3 + uni-app 3.0 App,编译目标 HarmonyOS App
环境:HBuilderX 5.x + DevEco Studio 5.0 + 鸿蒙真机
自动化脚本:dev-harmony.bat(Windows)


一、环境准备

最低版本要求

工具版本要求说明
HBuilderX4.24+鸿蒙支持最低版本
DevEco Studio5.0.3.400+鸿蒙原生 IDE
uni-app 依赖@dcloudio/uni-app 3.0+需安装 @dcloudio/uni-app-harmony
Vue3.x鸿蒙仅支持 Vue 3
Node.js16+Vite 构建依赖

关键依赖(package.json)

JSON
{
  "@dcloudio/uni-app-harmony": "3.0.0-5010520260709002",
  "@dcloudio/uni-mp-harmony": "3.0.0-5010520260709002",
  "@dcloudio/uni-uts-v1": "^3.0.0-4080420251103001"
}

所有 dcloudio 包需统一版本号,避免编译冲突。


二、首次初始化:生成原生壳工程

首次运行前,需用 HBuilderX 生成鸿蒙原生壳工程:

  1. 确保已安装 DevEco Studio,并至少打开过一次(首次打开自动生成调试签名证书)
  2. 在 HBuilderX 中打开项目
  3. 点击:运行 → 运行到手机或模拟器 → 运行到鸿蒙
  4. 如果提示"没有签名无法安装"——忽略,壳工程文件已生成完毕
  5. 关闭 HBuilderX,后续使用 dev-harmony.bat 自动化构建

壳工程位于 dist/dev/app-harmony/,包含鸿蒙原生代码(AppScope、entry 模块等)。


三、一键构建流程(dev-harmony.bat)

项目提供了 dev-harmony.bat 脚本,自动完成从源码编译到 DevEco Studio 打开的全流程。

用法

batch
# 开发模式(debug 签名)
dev-harmony.bat

# 发布模式(release 签名,用于 AppGallery 上架)
dev-harmony.bat --release

完整流程(3 大步 + 子步骤)

JSON
Step 1:   uni build -p app-harmony        ← 编译 uni-app 注入壳工程
Step 1.4: 注入鸿蒙权限声明                   ← 震动等权限 uni build 不会自动写入
Step 1.5: 注入 App 图标                     ← 从 app-icons/{repo}/ 复制 foreground/background/startIcon
Step 1.6: 设置 bundleName + 版本号           ← 根据 repo.config.json 重写 AppScope/app.json5
Step 1.7: 重置调试签名配置                   ← 删除旧证书,DevEco 打开后自动弹出签名修复
Step 2:   注入 local.properties / release 签名 ← SDK 路径 + AppGallery 发布签名
Step 3:   启动 DevEco Studio                ← 打开壳工程,点击 Run 即可安装到真机

脚本关键逻辑

自动识别仓库dev-harmony.batsrc/baseUrl.js 读取 REPO_CODEjwdevjwsgt),自动对应不同的:

  • bundleName:cn.juanwang.dev / cn.juanwang.sgt
  • App 图标目录:app-icons/jwdev/ / app-icons/jwsgt/
  • 签名配置目录:harmony-configs/jwdev/signing/ / harmony-configs/jwsgt/signing/

版本号自动计算:从 package.json 读取 version,自动计算 versionCode

JavaScript
versionCode = major × 10000 + minor × 100 + patch

例如:版本 1.2.3 → versionCode 10203


四、关键配置详解

4.1 manifest.json — 鸿蒙平台配置

JSON
"app-harmony": {
    "distribute": {
        "icons": {
            "foreground": "../app-icons/jwdev/foreground.png",
            "background": "../app-icons/jwdev/background.png"
        }
    }
}

注意:app-harmony.distribute 支持的字段非常有限(基本只有 icons),权限声明不能通过 manifest.json 配置,需构建后注入。

4.2 vite.config.js — IIFE 编译适配

鸿蒙不支持代码分割(动态 chunk),需在 vite.config.js 中添加 harmony-fix-iife 插件:

JavaScript
{
  name: 'harmony-fix-iife',
  enforce: 'post',
  configResolved(config) {
    const isHarmony = process.env.UNI_PLATFORM === 'app-harmony'
                   || process.env.UNI_PLATFORM === 'mp-harmony'
    if (isHarmony) {
      config.build.rollupOptions.output.inlineDynamicImports = true
      delete config.build.rollupOptions.output.manualChunks
    }
  }
}

作用:检测到鸿蒙平台时,强制将所有动态 import 内联为单一 IIFE 文件。

4.3 repo.config.json — 多仓库配置

JavaScript
{
  "jwdev": {
    "harmonyBundleName": "cn.juanwang.dev",
    "agcProjectId": "...",
    "agcClientId": "..."
  },
  "jwsgt": {
    "harmonyBundleName": "cn.juanwang.sgt",
    "agcProjectId": "...",
    "agcClientId": "..."
  }
}

同一套源码支持打出两个不同包名的 App。

4.4 权限注入 — 构建后脚本

uni build 生成 module.json5 后,运行 scripts/inject-harmony-permissions.js 注入需要的权限:

JavaScript
// 核心逻辑:读取 module.json5 → push 权限 → 写回
const REQUIRED_PERMISSIONS = [
  { name: 'ohos.permission.VIBRATE' }
]
// 去重后 push 到 json.module.requestPermissions

五、Vue 代码适配要点

5.1 getSystemInfoSync — 鸿蒙端需条件编译

鸿蒙运行时的桥接层对 uni.getSystemInfoSync() 存在兼容性问题,需用条件编译替代:

vue
// #ifndef APP-HARMONY
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 0
// #endif

// #ifdef APP-HARMONY
statusBarHeight.value = 44    // 鸿蒙默认状态栏高度
tabBarHeight.value = 65       // 鸿蒙默认 tabBar 高度
// #endif

鸿蒙设备状态栏高度基本统一为 44px,硬编码默认值即可。

5.2 条件编译 — 平台差异隔离

text
// #ifdef APP-HARMONY
// 鸿蒙专属逻辑(如 deviceAutoLogin)
// #endif

// #ifndef APP-HARMONY
// 其他平台逻辑
// #endif

5.3 大体积依赖 — 按平台按需加载

markdown-it、katex、highlight.js 等重型库会导致鸿蒙 bundle 过大(1MB+),用条件编译隔离:

text
<!-- #ifndef APP-HARMONY -->
import MarkdownIt from 'markdown-it'
import katex from 'katex'
<!-- #endif -->

鸿蒙端改为简化纯文本渲染,避免触发桥接层数据量上限。


六、签名与安装

6.1 调试签名(Debug)

脚本会自动重置调试签名配置,DevEco Studio 打开后会弹出 签名修复向导,按提示操作即可:

  1. DevEco 检测到签名缺失 → 弹出修复向导
  2. 自动生成调试证书(.p12)和 Profile
  3. 完成后点击绿色 Run 按钮安装到真机

6.2 发布签名(Release)

用于 AppGallery 上架,需手动准备:

text
harmony-configs/
└── jwdev/
    └── signing/
        ├── xxx.p12          ← 发布证书
        ├── xxx.cer          ← 证书文件
        └── xxx.p7b          ← Profile 文件

并在 harmony-configs/ 下创建 build-profile.release.jwdev.json5,引用签名文件路径。

签名敏感文件(.p12/.cer/.p7b)已在 .gitignore 中排除,不会提交到 Git。


七、完整构建链路总结

text
源码 (src/)
  │
  ├─ prebuild-manifest.js ──→ 模板替换({{repo.xxx}} → 实际值)
  │
  ├─ uni build -p app-harmony
  │    ├─ vite-plugin-manifest.js ──→ manifest.json 注入
  │    ├─ harmony-fix-iife ──→ inlineDynamicImports + 删除 manualChunks
  │    └─ 输出 ──→ dist/dev/app-harmony/ (原生壳工程)
  │
  ├─ inject-harmony-permissions.js ──→ module.json5 权限注入
  ├─ 图标复制 (app-icons/ → AppScope/resources/)
  ├─ app.json5 重写 (bundleName + version)
  ├─ build-profile.json5 重置 (签名清理)
  │
  ├─ local.properties 注入 (SDK 路径)
  │
  └─ DevEco Studio 打开 → Build → Run → 真机

八、常见问题速查

问题原因解决
HBuilderX 报 "vue 2 项目不支持鸿蒙"编译缓存污染清空缓存并重新编译,删除 dist/dev/app-harmony/ 和 node_modules
IIFE 编译错误动态 import 与 IIFE 格式冲突vite.config.js 添加 harmony-fix-iife 插件
启动白屏getSystemInfoSync 桥接序列化失败用条件编译替换为硬编码默认值
震动无反馈权限未写入 module.json5运行 inject-harmony-permissions.js
收藏页白屏markdown-it 等库 bundle 过大条件编译,鸿蒙端用纯文本渲染
签名报错bundleName 变更后证书不匹配运行 Step 1.7,DevEco 重新生成调试证书

九、要点总结

  1. 首次用 HBuilderX 生成壳工程,后续全部用 dev-harmony.bat 自动化构建
  2. 鸿蒙不支持代码分割,vite.config.js 必须设置 inlineDynamicImports: true
  3. manifest.jsonapp-harmony.distribute 有效字段极少,权限需构建后脚本注入
  4. uni.getSystemInfoSync() 在鸿蒙存在桥接兼容问题,用条件编译 + 硬编码默认值替代
  5. 重型第三方库(markdown-it 等)在鸿蒙端按需加载或降级为轻量替代
  6. 多仓库(jwdev/jwsgt)通过 repo.config.json 切换 bundleName、图标、签名配置
  7. 调试签名用 DevEco 自动生成,发布签名需从 AppGallery Connect 手动下载配置

本文为开发实践记录,内容如有错误或不足,欢迎搜索微信公众号「卷王开发者」批评指正。共同进步,感谢阅读。

扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码