Electron鸿蒙桌面应用打包部署完全指南(含自动更新)
从开发到上架全流程,附完整可运行代码与配置
前言
把 Electron 应用成功运行在鸿蒙 PC 上只是第一步,打包、签名、部署、自动更新才是真正让应用走向用户的"最后一公里"。
在 Windows/macOS 上,我们有 electron-builder、electron-packager 这类成熟工具。但鸿蒙 PC 的生态还在快速演进,打包链路有不少"坑"需要踩。
本文将从零开始,带你完成以下实战目标:
- 配置
electron-builder打包鸿蒙 PC 应用 - 生成签名证书并签名应用
- 实现应用自动更新(基于
electron-updater) - 上架鸿蒙应用市场(AppGallery)
- 常见打包错误与解决方案
一、技术架构总览
┌─────────────────────────────────────────────────┐
│ Electron 应用源代码 │
│ main.js + preload.js + renderer/ │
└──────────────────────────┬──────────────────────┘
│ npm run dist
┌──────────────────────────▼──────────────────────┐
│ electron-builder 打包阶段 │
│ 1. 编译原生模块(.node 插件) │
│ 2. 打包 Electron 二进制 │
│ 3. 生成安装包(.exe / .appimage) │
└──────────────────────────┬──────────────────────┘
│ 签名
┌──────────────────────────▼──────────────────────┐
│ 鸿蒙应用签名(.p12 证书) │
│ 使用 hmos-sign 或手动 jarsigner │
└──────────────────────────┬──────────────────────┘
│ 发布
┌──────────────────────────▼──────────────────────┐
│ 鸿蒙应用市场 / 自动更新服务器 │
│ app-update.yml + GitHub Releases │
└─────────────────────────────────────────────────┘
二、环境准备
2.1 工具清单
| 工具 | 版本 | 用途 |
|---|---|---|
| Electron | 34.x | 主框架 |
| electron-builder | 26.x | 打包工具 |
| electron-updater | 6.x | 自动更新 |
| DevEco Studio | 5.0.5+ | 鸿蒙 SDK |
| hmos-sign | 1.0.0+ | 鸿蒙应用签名 |
2.2 安装依赖
bash
# 初始化项目
mkdir electron-hmos-packaging && cd electron-hmos-packaging
npm init -y
# 安装 Electron(鸿蒙定制版)
npm install electron --save-dev
# 安装打包工具
npm install electron-builder --save-dev
# 安装自动更新
npm install electron-updater --save
# 安装鸿蒙签名工具
npm install hmos-sign --save-dev
三、配置 electron-builder
3.1 基础配置(package.json)
json
{
"name": "electron-hmos-demo",
"version": "1.0.0",
"description": "Electron 鸿蒙桌面应用示例",
"main": "main.js",
"scripts": {
"start": "electron .",
"dist": "electron-builder --config electron-builder.yml",
"dist:hmos": "electron-builder --config electron-builder.hmos.yml"
},
"devDependencies": {
"electron": "^34.0.0",
"electron-builder": "^26.0.0"
},
"build": {
"appId": "com.example.electronhmos",
"productName": "Electron鸿蒙示例",
"directories": {
"output": "dist/"
}
}
}
3.2 鸿蒙专用配置(electron-builder.hmos.yml)
yaml
appId: com.example.electronhmos
productName: Electron鸿蒙示例
directories:
output: dist/
# 鸿蒙 PC 平台配置
hmos:
target:
- target: hmos
arch:
- x64
- arm64
icon: resources/icon.png
# 签名配置
sign:
certificate: certificates/hmos.p12
password: "your-cert-password"
provisioningProfile: certificates/hmos.mobileprovision"
# 安装包信息
installer:
name: "Electron鸿蒙示例"
categories:
- Utility
mimeTypes:
- application/x-extension-html
# 文件关联
fileAssociations:
- ext: html
name: HTML 文件
role: Editor
# 自动更新配置
publish:
- provider: generic
url: https://update.example.com/electron-hmos/
channel: latest.yml
四、主进程配置(main.js)
javascript
// main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const { autoUpdater } = require('electron-updater');
const path = require('path');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true
}
});
// 加载应用
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:3000');
mainWindow.webContents.openDevTools();
} else {
mainWindow.loadFile('renderer/index.html');
}
// 自动更新事件
setupAutoUpdater();
}
// 自动更新配置
function setupAutoUpdater() {
// 设置更新服务器地址
autoUpdater.setFeedURL({
provider: 'generic',
url: 'https://update.example.com/electron-hmos/'
});
// 检查更新
autoUpdater.checkForUpdatesAndNotify();
// 更新事件监听
autoUpdater.on('checking-for-update', () => {
console.log('正在检查更新...');
mainWindow.webContents.send('update-status', 'checking');
});
autoUpdater.on('update-available', (info) => {
console.log('发现新版本:', info.version);
mainWindow.webContents.send('update-status', 'available', info);
});
autoUpdater.on('update-not-available', () => {
console.log('当前已是最新版本');
mainWindow.webContents.send('update-status', 'not-available');
});
autoUpdater.on('download-progress', (progressObj) => {
console.log(`下载进度: ${progressObj.percent}%`);
mainWindow.webContents.send('update-progress', progressObj);
});
autoUpdater.on('update-downloaded', (info) => {
console.log('更新包下载完成,将在下次启动时安装');
mainWindow.webContents.send('update-status', 'downloaded', info);
// 提示用户重启应用
setTimeout(() => {
if (confirm('新版本已下载完成,是否现在重启应用?')) {
autoUpdater.quitAndInstall();
}
}, 3000);
});
autoUpdater.on('error', (err) => {
console.error('自动更新错误:', err);
mainWindow.webContents.send('update-status', 'error', err);
});
}
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
五、预加载脚本(preload.js)
javascript
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
// 检查更新
checkForUpdates: () => ipcRenderer.invoke('check-for-updates'),
// 更新状态监听
onUpdateStatus: (callback) => ipcRenderer.on('update-status', callback),
onUpdateProgress: (callback) => ipcRenderer.on('update-progress', callback),
// 安装更新
installUpdate: () => ipcRenderer.invoke('install-update'),
// 获取应用版本
getAppVersion: () => ipcRenderer.invoke('get-app-version')
});
六、渲染进程(index.html)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Electron 鸿蒙应用 - 自动更新示例</title>
<style>
body {
font-family: 'HarmonyOS Sans', sans-serif;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
min-height: 100vh;
}
.container {
max-width: 800px;
margin: 0 auto;
background: rgba(255,255,255,0.1);
padding: 30px;
border-radius: 15px;
backdrop-filter: blur(10px);
}
.update-status {
margin: 20px 0;
padding: 15px;
border-radius: 8px;
background: rgba(0,0,0,0.2);
}
.progress-bar {
width: 100%;
height: 20px;
background: rgba(255,255,255,0.2);
border-radius: 10px;
overflow: hidden;
margin: 10px 0;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #00c9ff 0%, #92fe9d 100%);
transition: width 0.3s ease;
}
button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
margin: 5px;
}
button:hover {
opacity: 0.9;
}
</style>
</head>
<body>
<div class="container">
<h1>🚀 Electron 鸿蒙应用</h1>
<p>版本: <span id="version">加载中...</span></p>
<div class="update-status">
<h3>自动更新状态</h3>
<div id="status">正在检查更新...</div>
<div class="progress-bar" id="progressBar" style="display:none;">
<div class="progress-fill" id="progressFill"></div>
</div>
<div id="progressText"></div>
</div>
<div>
<button onclick="checkForUpdates()">手动检查更新</button>
<button onclick="installUpdate()" id="installBtn" style="display:none;">立即安装更新</button>
</div>
</div>
<script>
// 获取应用版本
window.electronAPI.getAppVersion().then(version => {
document.getElementById('version').textContent = version;
});
// 监听更新状态
window.electronAPI.onUpdateStatus((event, status, data) => {
const statusEl = document.getElementById('status');
const installBtn = document.getElementById('installBtn');
switch(status) {
case 'checking':
statusEl.textContent = '正在检查更新...';
break;
case 'available':
statusEl.textContent = `发现新版本: ${data.version}`;
break;
case 'not-available':
statusEl.textContent = '当前已是最新版本';
break;
case 'downloaded':
statusEl.textContent = '更新包下载完成,请重启应用';
installBtn.style.display = 'inline-block';
break;
case 'error':
statusEl.textContent = `更新错误: ${data}`;
break;
}
});
// 监听下载进度
window.electronAPI.onUpdateProgress((event, progress) => {
const progressBar = document.getElementById('progressBar');
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
progressBar.style.display = 'block';
progressFill.style.width = `${progress.percent}%`;
progressText.textContent = `下载进度: ${Math.round(progress.percent)}%`;
});
// 手动检查更新
function checkForUpdates() {
window.electronAPI.checkForUpdates();
}
// 安装更新
function installUpdate() {
window.electronAPI.installUpdate();
}
</script>
</body>
</html>
七、鸿蒙应用签名
7.1 生成签名证书
bash
# 使用 keytool 生成 .p12 证书
keytool -genkeypair \
-alias electron-hmos \
-keyalg RSA \
-keysize 2048 \
-validity 3650 \
-keystore certificates/hmos.p12 \
-storetype PKCS12 \
-dname "CN=Your Name, OU=Development, O=Your Company, L=City, ST=Province, C=CN" \
-storepass your-cert-password
7.2 配置签名(electron-builder.hmos.yml)
yaml
hmos:
sign:
certificate: certificates/hmos.p12
password: "your-cert-password"
provisioningProfile: certificates/hmos.mobileprovision"
7.3 手动签名(备用方案)
bash
# 如果自动签名失败,可以手动签名
jarsigner -verbose \
-sigalg SHA256withRSA \
-digestalg SHA-256 \
-keystore certificates/hmos.p12 \
-storepass your-cert-password \
dist/Electron鸿蒙示例-1.0.0.hmos \
electron-hmos
八、打包执行
8.1 执行打包命令
bash
# 打包鸿蒙 PC 版本
npm run dist:hmos
输出文件:
dist/
├── Electron鸿蒙示例-1.0.0-hmos-x64.hmos
├── Electron鸿蒙示例-1.0.0-hmos-arm64.hmos
├── latest.yml
└── builder-effective-config.yaml
8.2 常见打包错误与解决
| 错误 | 原因 | 解决方案 |
|---|---|---|
Cannot find module 'electron' |
Electron 未正确安装 | rm -rf node_modules && npm install |
hmos target not supported |
electron-builder 版本过低 | 升级到 26.x+ |
Certificate not found |
证书路径错误 | 检查 electron-builder.hmos.yml 中的证书路径 |
Signing failed |
证书密码错误 | 确认密码正确,或重新生成证书 |
Auto-updater error |
更新服务器配置错误 | 检查 autoUpdater.setFeedURL() 配置 |
九、上架鸿蒙应用市场
9.1 准备材料
- 应用安装包(.hmos 文件)
- 应用图标(512x512 PNG)
- 应用截图(1280x720 或 1920x1080)
- 应用描述(中文,200字以内)
- 隐私政策(必须提供)
9.2 提交流程
- 登录 鸿蒙应用市场开发者后台
- 创建新应用,填写基本信息
- 上传安装包和素材
- 提交审核(通常需要 3-5 个工作日)
- 审核通过后上架
十、自动更新服务器搭建
10.1 使用 GitHub Releases
yaml
# electron-builder.hmos.yml
publish:
- provider: github
owner: your-github-username
repo: electron-hmos-demo
token: ${{ secrets.GITHUB_TOKEN }}
10.2 使用私有服务器
bash
# 1. 在服务器上创建更新目录
mkdir -p /var/www/update/electron-hmos/
# 2. 上传打包文件
scp dist/* user@server:/var/www/update/electron-hmos/
# 3. 确保 latest.yml 可访问
curl https://update.example.com/electron-hmos/latest.yml
十一、总结
本文完整介绍了 Electron 鸿蒙桌面应用的打包、签名、部署和自动更新全流程。核心要点:
- 配置 electron-builder - 使用鸿蒙专用配置
- 签名应用 - 生成 .p12 证书并配置
- 自动更新 - 使用 electron-updater
- 上架市场 - 准备材料并提交审核
- 更新服务器 - GitHub Releases 或私有服务器