📋 项目概述
本文档基于一个完整的 Swifty 密码管理器 适配项目,详细介绍了如何在 HarmonyOS PC 平台上使用 Electron for HarmonyOS 框架,将成熟的 Electron 应用(Swifty)成功运行在鸿蒙 PC 设备上。项目实现了完整的应用集成、资源文件管理、多语言支持等功能,展示了 Electron 应用在 HarmonyOS 平台上的实际适配经验。
项目功能
- ✅ 完整的 Swifty 密码管理器功能(登录/密码存储、信用卡信息、安全笔记)
- ✅ 强密码生成器(一键生成)
- ✅ 基于时间的一次性密码支持(TOTP)
- ✅ Google Drive 同步(可选)
- ✅ 本地加密存储(AES-256-GCM)
- ✅ 多语言支持(i18n)
- ✅ 完整的 Electron 主进程和渲染进程集成
- ✅ 响应式布局,适配鸿蒙 PC 屏幕
原始项目对比
原始项目(Swifty Electron):
- 使用 Electron 27.x + React 18 + Redux Toolkit
- 使用 Webpack 打包构建
- 支持 macOS、Windows、Linux 多平台
- 使用
bozon作为构建工具 - 标准的 Electron 应用结构(main、renderer、preload)
HarmonyOS 适配版本(Electron for HarmonyOS):
- 使用 Electron for HarmonyOS 框架
- 集成到 HarmonyOS HAP 包中
- 适配鸿蒙 PC 平台的文件系统和资源管理
- 修改主进程入口以适配 HarmonyOS 生命周期
- 调整文件路径和资源加载方式
- 配置 Content-Security-Policy 以允许本地资源加载
📸 效果展示
以下是 Swifty 密码管理器在 HarmonyOS PC 平台上的运行效果:
演示示例 1

Swifty 应用主界面在 HarmonyOS PC 上的显示效果
演示示例 2

Swifty 密码管理功能在鸿蒙PC上的实际运行效果
从效果图可以看出,Swifty 应用已成功适配到 HarmonyOS PC 平台,界面显示正常,功能完整可用。
🎯 核心技术要点
1. HarmonyOS Electron 主进程入口:main.js
⚠️ 关键要点 :必须在 app.whenReady() 之前加载 Swifty 主进程代码!
javascript
// ✅ 正确写法
const { app, BrowserWindow } = require('electron');
const path = require('path');
// 设置 swifty 需要的 CONFIG 变量
global.CONFIG = {
appId: 'fcae8dc8cd68b98ad0aa7da1b8479a94edde0eb698acb7e537a94a185b5b1425',
width: 460,
height: 500,
analytics: null,
reload: true,
devTools: true,
apiHost: 'https://getswifty.pro',
autoUpdate: false,
googleOauth: {
scope: 'https://www.googleapis.com/auth/drive.file'
}
};
// ⚠️ 关键:在 app ready 之前加载 swifty 主进程
const swiftyMainPath = path.join(__dirname, 'swifty', 'main', 'index.js');
try {
require(swiftyMainPath);
// swifty 主进程会自己注册 app.on('ready') 事件并创建窗口
} catch (error) {
console.error('Error loading swifty main process:', error);
// 如果加载失败,使用备用窗口创建方式
app.whenReady().then(() => {
createWindow();
});
}
// ❌ 错误写法(会导致 ready 事件丢失)
app.whenReady().then(() => {
require(swiftyMainPath); // Swifty 的 app.on('ready') 可能不会被调用
});
原因说明:
- Swifty 主进程代码内部注册了
app.on('ready')事件处理器 - 如果在
app.whenReady()之后加载,Swifty 的 ready 处理器可能无法正确注册 - 必须在应用启动早期加载,确保事件监听器正确绑定
2. 硬件加速禁用配置
⚠️ 关键要点:HarmonyOS PC 上需要禁用硬件加速以避免渲染问题!
javascript
// Step 1: 在 Electron 层面禁用硬件加速
app.disableHardwareAcceleration();
// Step 2: 在 Chromium 层面追加命令行开关,彻底禁用 GPU
app.commandLine.appendSwitch('disable-gpu');
配置说明:
app.disableHardwareAcceleration():禁用 Electron 的硬件加速disable-gpu开关:在 Chromium 层面禁用 GPU 渲染- 这两个配置必须同时使用,确保在 HarmonyOS PC 上稳定运行
3. 文件路径和资源管理
3.1 资源文件路径配置
javascript
function createWindow() {
// ⚠️ 关键:使用 path.join 构建正确的资源路径
const swiftyRendererPath = path.join(__dirname, 'swifty', 'renderer', 'index.html');
const swiftyPreloadPath = path.join(__dirname, 'swifty', 'preload', 'index.js');
const win = new BrowserWindow({
width: 460,
height: 500,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
preload: swiftyPreloadPath,
webSecurity: false // ⚠️ 允许加载本地资源
}
});
win.loadFile(swiftyRendererPath);
}
路径结构:
web_engine/src/main/resources/resfile/resources/app/
├── main.js # Electron 主进程入口
├── swifty/ # Swifty 应用目录
│ ├── main/ # 主进程代码
│ │ └── locales/ # 多语言文件
│ ├── preload/ # Preload 脚本
│ │ └── index.js
│ └── renderer/ # 渲染进程代码
│ ├── index.html
│ └── index.js
3.2 多语言文件路径
⚠️ 关键要点 :locales 文件必须放在 main/locales/ 目录下!
javascript
// Swifty 的 i18n 模块会查找以下路径:
// app.getAppPath() + 'main/locales/'
// ✅ 正确位置
web_engine/src/main/resources/resfile/resources/app/main/locales/
├── en-US.json
├── zh-CN.json
└── ...
// ❌ 错误位置(会导致 ENOENT 错误)
web_engine/src/main/resources/resfile/resources/app/swifty/main/locales/
解决方法:
bash
# 复制 locales 文件到正确位置
mkdir -p web_engine/src/main/resources/resfile/resources/app/main/locales
cp -r swifty/builds/development/main/locales/* \
web_engine/src/main/resources/resfile/resources/app/main/locales/
4. Content-Security-Policy 配置
⚠️ 关键要点:必须放宽 CSP 策略以允许本地资源加载!
html
<!-- ✅ 正确配置 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Swifty</title>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline' 'unsafe-eval';
img-src 'self' data:;
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';"
/>
<script src="index.js" type="text/javascript"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
配置说明:
'unsafe-inline':允许内联脚本和样式(React 需要)'unsafe-eval':允许eval()函数(Webpack 开发模式需要)data::允许 data URI 图片(Base64 图片)- 这些配置对于 Electron 应用在 HarmonyOS 上运行是必需的
5. 应用图标和名称配置
5.1 应用图标
bash
# 复制 Swifty 图标到鸿蒙项目
cp swifty/build/icon.png \
ElectronForHarmony_swifty/AppScope/resources/base/media/app_icon.png
cp swifty/build/icon.png \
ElectronForHarmony_swifty/AppScope/resources/base/media/product_logo_32.png
cp swifty/build/icon.png \
ElectronForHarmony_swifty/AppScope/resources/base/media/startIcon.png
5.2 应用名称
json
// AppScope/resources/base/element/string.json
{
"string": [
{
"name": "app_name",
"value": "Swifty"
}
]
}
💡 完整代码示例
主进程入口文件 (main.js)
javascript
const { app, BrowserWindow } = require('electron');
const path = require('path');
// 1. 禁用硬件加速(HarmonyOS PC 必需)
app.disableHardwareAcceleration();
app.commandLine.appendSwitch('disable-gpu');
// 2. 设置 Swifty 需要的全局配置
global.CONFIG = {
appId: 'fcae8dc8cd68b98ad0aa7da1b8479a94edde0eb698acb7e537a94a185b5b1425',
width: 460,
height: 500,
analytics: null,
reload: true,
devTools: true,
apiHost: 'https://getswifty.pro',
autoUpdate: false,
googleOauth: {
scope: 'https://www.googleapis.com/auth/drive.file'
}
};
// 3. 备用窗口创建函数
function createWindow() {
const swiftyRendererPath = path.join(__dirname, 'swifty', 'renderer', 'index.html');
const swiftyPreloadPath = path.join(__dirname, 'swifty', 'preload', 'index.js');
console.log('Creating window...');
console.log('Renderer path:', swiftyRendererPath);
console.log('Preload path:', swiftyPreloadPath);
const win = new BrowserWindow({
width: 460,
height: 500,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
preload: swiftyPreloadPath,
webSecurity: false // 允许加载本地资源
}
});
// 打开开发者工具以便调试
win.webContents.openDevTools();
// 加载 Swifty 渲染进程页面
win.loadFile(swiftyRendererPath).then(() => {
console.log('Window loaded successfully');
}).catch((error) => {
console.error('Error loading window:', error);
});
}
// 4. ⚠️ 关键:在 app ready 之前加载 Swifty 主进程
const swiftyMainPath = path.join(__dirname, 'swifty', 'main', 'index.js');
console.log('Attempting to load swifty main process from:', swiftyMainPath);
try {
require(swiftyMainPath);
console.log('Swifty main process loaded successfully - it will manage window creation');
// Swifty 主进程会自己注册 app.on('ready') 事件并创建窗口
} catch (error) {
console.error('Error loading swifty main process:', error.message);
console.error('Error stack:', error.stack);
// 如果加载失败,使用备用窗口创建方式
app.whenReady().then(() => {
console.log('App is ready, falling back to simple window creation');
createWindow();
});
}
// 5. 窗口关闭处理
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
🚀 构建和部署流程
Step 1: 安装 Swifty 依赖
bash
cd swifty
npm install
# ⚠️ 注意:需要 GitHub Personal Access Token
# 配置 .npmrc 文件:
# @swiftyapp:registry=https://npm.pkg.github.com
# always-auth=true
# //npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
Step 2: 构建 Swifty 应用
bash
# 使用 bozon 构建(开发模式)
npm start
# 构建产物位于:swifty/builds/development/
Step 3: 复制文件到鸿蒙项目
bash
cd ../ElectronForHarmony_swifty
# 复制 Swifty 构建文件
cp -r ../swifty/builds/development \
web_engine/src/main/resources/resfile/resources/app/swifty
# 复制多语言文件(⚠️ 关键:必须放在 main/locales/)
mkdir -p web_engine/src/main/resources/resfile/resources/app/main/locales
cp -r ../swifty/builds/development/main/locales/* \
web_engine/src/main/resources/resfile/resources/app/main/locales/
# 复制 preload 脚本
mkdir -p web_engine/src/main/resources/resfile/resources/app/preload
cp ../swifty/builds/development/preload/index.js \
web_engine/src/main/resources/resfile/resources/app/preload/
# 复制 renderer 文件
mkdir -p web_engine/src/main/resources/resfile/resources/app/renderer
cp -r ../swifty/builds/development/renderer/* \
web_engine/src/main/resources/resfile/resources/app/renderer/
Step 4: 配置应用图标和名称
bash
# 复制应用图标
cp ../swifty/build/icon.png \
AppScope/resources/base/media/app_icon.png
# 修改应用名称(编辑 string.json)
# AppScope/resources/base/element/string.json
Step 5: 在 DevEco Studio 中构建
- 打开
ElectronForHarmony_swifty项目 - 点击 Build → Build Hap(s)/APP(s) → Build Hap(s)
- 等待构建完成
Step 6: 安装到鸿蒙 PC
bash
# 使用 hdc 工具安装
hdc install electron/build/default/outputs/default/electron-default-signed.hap
# 或者在 DevEco Studio 中点击 Run 按钮
🐛 常见问题与解决方案
问题 1:白屏(应用无法显示)
错误现象:
- 应用启动后显示空白窗口
- 控制台没有错误信息
可能原因:
- Swifty 主进程加载失败
- Renderer 进程的 JavaScript 未执行
- Preload 脚本未正确加载
- Content-Security-Policy 过于严格
解决方法:
javascript
// 1. 检查主进程加载顺序
// ✅ 确保在 app.whenReady() 之前加载
require(swiftyMainPath);
// 2. 检查文件路径
console.log('Renderer path:', swiftyRendererPath);
console.log('Preload path:', swiftyPreloadPath);
// 3. 放宽 CSP 策略
// 在 index.html 中修改 Content-Security-Policy
// 4. 打开 DevTools 查看错误
win.webContents.openDevTools();
问题 2:找不到 locales 文件
错误信息:
ENOENT: no such file or directory, open '.../main/locales/en-US.json'
原因:
- Swifty 的 i18n 模块查找路径为:
app.getAppPath() + 'main/locales/' - 文件被放在了错误的位置
解决方法:
bash
# ✅ 正确位置
web_engine/src/main/resources/resfile/resources/app/main/locales/
# ❌ 错误位置
web_engine/src/main/resources/resfile/resources/app/swifty/main/locales/
# 复制文件到正确位置
mkdir -p web_engine/src/main/resources/resfile/resources/app/main/locales
cp -r swifty/builds/development/main/locales/* \
web_engine/src/main/resources/resfile/resources/app/main/locales/
问题 3:GitHub Token 认证失败
错误信息:
npm error 401 Unauthorized - GET https://npm.pkg.github.com/download/@swiftyapp/cryptor/...
原因:
- Swifty 依赖私有包
@swiftyapp/cryptor - 需要 GitHub Personal Access Token 才能下载
解决方法:
bash
# 1. 创建 GitHub Personal Access Token
# Settings → Developer settings → Personal access tokens → Tokens (classic)
# 权限:read:packages
# 2. 配置环境变量
export NODE_AUTH_TOKEN=your_token_here
# 3. 配置 .npmrc
cat > swifty/.npmrc << EOF
@swiftyapp:registry=https://npm.pkg.github.com
always-auth=true
//npm.pkg.github.com/:_authToken=\${NODE_AUTH_TOKEN}
EOF
# 4. 永久设置(MacOS)
echo 'export NODE_AUTH_TOKEN=your_token_here' >> ~/.zshrc
source ~/.zshrc
问题 4:应用图标未更新
现象:
- 构建后应用图标仍然是默认图标
- 应用名称未更改
解决方法:
bash
# 1. 确认图标文件已更新
ls -lh AppScope/resources/base/media/app_icon.png
# 2. 确认应用名称配置
cat AppScope/resources/base/element/string.json
# 3. 清理构建缓存
# 在 DevEco Studio 中:Build → Clean Project
# 4. 重新构建
# Build → Build Hap(s)/APP(s) → Build Hap(s)
📁 项目结构说明
ElectronForHarmony_swifty/
├── AppScope/ # 应用配置
│ ├── app.json5 # 应用配置(应用名称:Swifty)
│ └── resources/
│ └── base/
│ ├── media/
│ │ └── app_icon.png # Swifty 应用图标
│ └── element/
│ └── string.json # 应用名称配置
├── electron/ # Electron 模块
│ └── src/main/
│ └── ets/ # 鸿蒙原生代码
├── web_engine/ # Web 引擎模块
│ └── src/main/
│ └── resources/
│ └── resfile/
│ └── resources/
│ └── app/
│ ├── main.js # Electron 主进程入口 ⚠️ 关键文件
│ ├── main/ # Swifty 主进程代码
│ │ └── locales/ # 多语言文件 ⚠️ 关键目录
│ ├── preload/ # Preload 脚本
│ └── renderer/ # Swifty 渲染进程代码
└── build-profile.json5 # 构建配置
⚠️ 重要注意事项
-
主进程加载顺序 :必须在
app.whenReady()之前加载 Swifty 主进程代码,否则 ready 事件监听器无法正确注册。 -
硬件加速:HarmonyOS PC 上必须禁用硬件加速,否则可能导致渲染问题。
-
文件路径:确保所有文件路径正确,特别是:
main/locales/- 多语言文件必须放在这个位置preload/index.js- Preload 脚本路径renderer/index.html- 渲染进程入口
-
Content-Security-Policy:必须放宽 CSP 策略以允许本地资源加载和 React 运行。
-
GitHub Token:Swifty 依赖私有包,需要配置 GitHub Personal Access Token。
-
应用图标和名称:修改后需要清理构建缓存并重新构建。
📦 构建产物
构建完成后,HAP 包位于:
electron/build/default/outputs/default/electron-default-signed.hap
可以使用 hdc 工具安装到鸿蒙 PC:
bash
hdc install electron/build/default/outputs/default/electron-default-signed.hap
🔗 相关资源
- OpenHarmony PC开发者专区
- HarmonyOS PC 开发者社区
- Swifty 官方仓库
- Electron for HarmonyOS 文档
- HarmonyOS 开发文档
- Electron 官方文档
📄 许可证
本项目基于 Swifty 项目(GNU/GPL Version 3)和 Electron for HarmonyOS 框架。