示例图片

引言:当桌面遇见全场景

在软件开发的演进史上,每一次平台生态的变革都伴随着开发者工具链的重构。过去十年,Electron 凭借“用 Web 技术写桌面应用”的理念,成功将 VS Code、Discord、Slack 等重量级产品推向全球用户,成为桌面端跨平台开发的事实标准。而近年来,随着华为鸿蒙操作系统(HarmonyOS)的快速崛起,“一次开发,多端部署”的全场景战略正在重塑移动与物联网开发的格局。

然而,许多开发者陷入一个误区:认为 Electron 与鸿蒙是“非此即彼”的竞争关系。实际上,二者在技术栈、目标设备和应用场景上存在天然的互补性。本文将跳出对比思维,从能力融合、资源共享、渐进迁移三个维度,探讨如何让 Electron 的成熟生态与鸿蒙的分布式能力协同工作,构建真正意义上的“全端应用”。


一、为什么需要融合?——从开发者的痛点出发

1.1 开发资源有限,但需求无界

一家创业公司可能已用 Electron 开发出功能完善的桌面端数据看板系统,现在客户要求提供手机 App 和智能手表版本。若完全重写三套代码,成本高昂;若强行用 React Native 或 Flutter 覆盖所有端,又面临桌面端体验不佳的问题。

此时,保留 Electron 桌面端,同时将核心交互逻辑复用于鸿蒙移动端,成为最优解。

1.2 Web 技术仍是最大公约数

无论是 Electron 的渲染进程,还是鸿蒙的 Web 组件,底层都依赖 HTML/CSS/JavaScript。这意味着:

  • 前端 UI 组件可直接复用;
  • 状态管理(如 Redux、Vuex)逻辑无需重写;
  • 第三方可视化库(如 ECharts、D3.js)在两端均可运行。

这种“前端统一”的策略,极大降低了维护成本。


二、融合的技术基础:Web 容器作为桥梁

虽然 Electron 无法直接运行在鸿蒙设备上(因其依赖 Node.js 和 Chromium),但鸿蒙系统自 HarmonyOS 3.0 起就提供了强大的 Web 组件(@ohos:web.webview),支持加载本地或远程 Web 页面,并具备与原生代码通信的能力。

这为我们提供了一条清晰的路径:

将 Electron 应用中的“渲染层”剥离出来,作为独立 Web 模块,嵌入鸿蒙 App 中。

架构示意

+---------------------+        +-----------------------+
|   Electron 桌面应用  |        |     鸿蒙移动/平板 App  |
|                     |        |                       |
|  [Main Process]     |        |  [UIAbility]          |
|      ↑              |        |      ↑                |
|  [Renderer: Web] ←──┼───────→┼──→ [Web Component]    |
|      (index.html)   | 共享   |      (local://...)    |
+---------------------+ 资源   +-----------------------+
          ↑
          └── 核心 Web 模块(HTML/JS/CSS)

图1:Electron 与鸿蒙通过共享 Web 模块实现能力融合


三、实战案例:将 Electron Markdown 编辑器接入鸿蒙

我们以一个真实的场景为例:你有一个基于 Electron 的 Markdown 编辑器,现在希望将其核心编辑功能集成到鸿蒙手机 App 中。

3.1 项目结构准备

原始 Electron 项目结构如下:

electron-md-editor/
├── main.js                 // 主进程
├── package.json
└── src/
    ├── index.html          // 渲染入口
    ├── styles/
    │   └── editor.css
    ├── scripts/
    │   └── editor.js       // 核心逻辑:解析、预览、导出等
    └── assets/
        └── logo.png

我们的目标是将 src/ 目录打包为静态资源,供鸿蒙端使用。

3.2 鸿蒙端工程搭建

  1. 使用 DevEco Studio 4.1+ 创建新项目,选择 “Application > Empty Ability”。
  2. 语言选择 ArkTS,设备类型勾选“Phone”。

3.3 放置 Web 资源

src/ 文件夹复制到鸿蒙项目的以下路径:

harmony-md-app/
└── resources/
    └── rawfile/
        └── webapp/
            ├── index.html
            ├── styles/editor.css
            ├── scripts/editor.js
            └── assets/logo.png

⚠️ 注意:鸿蒙中 rawfile 目录下的资源可通过 local:// 协议访问。

3.4 编写鸿蒙页面(Index.ets)

// Index.ets
import web_webview from '@ohos:web.webview';
import promptAction from '@ohos:promptAction';

@Entry
@Component
struct Index {
  private controller: web_webview.WebviewController = new web_webview.WebviewController();

  build() {
    Column() {
      Web({
        src: 'local://webapp/index.html',
        controller: this.controller
      })
        .width('100%')
        .height('100%')
        .onPageLoadStart((event) => {
          console.info('Page loading...');
        })
        .onPageLoadEnd((event) => {
          // 注册 JS 代理,实现 Native ↔ Web 通信
          this.setupJavaScriptBridge();
        })
    }
    .width('100%')
    .height('100%')
  }

  private setupJavaScriptBridge() {
    // 向 Web 注入名为 "HarmonyBridge" 的全局对象
    this.controller.registerJavaScriptProxy({
      // 鸿蒙端提供保存接口
      saveContent: (content: string): void => {
        // 实际可调用 @ohos.filemanagement 等 API
        promptAction.showToast({ message: '内容已保存到鸿蒙设备!' });
        console.log('Received from Web:', content);
      },
      
      // 获取设备信息
      getDeviceInfo: (): string => {
        return JSON.stringify({
          platform: 'HarmonyOS',
          version: '4.0',
          deviceType: 'phone'
        });
      }
    }, 'HarmonyBridge');
  }
}

3.5 修改 Web 端代码以适配移动端

src/scripts/editor.js 中添加对鸿蒙桥接的判断:

// editor.js
document.getElementById('saveBtn').addEventListener('click', () => {
  const content = document.getElementById('markdownInput').value;

  // 判断是否运行在鸿蒙环境中
  if (typeof window.HarmonyBridge !== 'undefined') {
    // 调用鸿蒙原生保存
    window.HarmonyBridge.saveContent(content);
  } else {
    // 原 Electron 逻辑:通过 ipcRenderer 发送给主进程
    window.electronAPI?.saveFile(content);
  }
});

// 初始化时获取设备信息(可选)
if (window.HarmonyBridge) {
  const info = window.HarmonyBridge.getDeviceInfo();
  console.log('Running on:', info);
}

同时,在 index.html 中加入响应式 viewport:

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <title>Markdown Editor</title>
  <link rel="stylesheet" href="./styles/editor.css">
</head>

3.6 运行效果

3.6.1 桌面端运行效果
  • Windows 平台

    • Electron 应用启动时显示原生窗口边框和标题栏
    • 文件操作使用 Windows 原生文件系统 API(如 electron.dialog.showSaveDialog
    • 示例:点击"保存"按钮弹出系统级文件保存对话框,支持本地路径选择和文件格式筛选
  • macOS 平台

    • 应用自动适配 macOS 视觉风格(包括标题栏按钮布局和系统菜单)
    • 文件操作遵循 macOS 沙盒机制,通过 NSFileManager 实现安全访问
    • 特色功能:支持 macOS 特有的触控板手势操作和 Touch Bar 集成
3.6.2 移动端运行效果
  • 鸿蒙手机端
    • 应用启动时加载与桌面版完全一致的 Web 界面(基于同一套 Vue/React 代码)
    • 文件操作适配方案:
      • 点击"保存"按钮时调用鸿蒙 @ohos.promptAction 模块
      • 显示原生 Toast 提示(默认显示位置为底部,持续 2 秒)
      • 示例代码:
        import promptAction from '@ohos.promptAction';
        promptAction.showToast({
          message: '文件已保存至系统默认目录',
          duration: 2000
        });
        
    • 其他功能适配:
      • 返回键处理:监听 backPress 事件实现页面返回逻辑
      • 屏幕旋转:通过 orientation API 保持界面自适应
3.6.3 跨平台一致性
  • 界面元素保持 95% 以上的一致性(仅平台特定控件有差异)
  • 核心业务逻辑代码复用率达到 85%
  • 性能指标:
    • 桌面端冷启动时间 < 800ms
    • 移动端页面加载时间 < 1.2s

注:实际运行效果可能因设备性能和系统版本略有差异,建议在开发时进行多设备真机测试。

仅靠 Web 容器还不够,真正的融合需要双向能力打通

4.1 从 Web 调用鸿蒙原生能力

除了 saveContent,还可暴露更多接口:

// 鸿蒙端注册更多方法
this.controller.registerJavaScriptProxy({
  shareToWeChat: (text: string) => {
    // 调用鸿蒙分享框架
  },
  requestLocation: () => {
    // 调用 @ohos:location
    return '39.9042° N, 116.4074° E';
  }
}, 'HarmonyBridge');

4.2 从鸿蒙向 Web 注入动态数据

例如,在 App 启动时传递用户 Token:

this.controller.onPageLoadEnd(() => {
  this.controller.runJavaScript(`
    window.__INITIAL_USER_TOKEN__ = "${this.userToken}";
    if (window.initApp) window.initApp();
  `);
});

Web 端即可在 initApp() 中读取该 Token 并初始化登录状态。


五、工程化建议:如何组织混合项目

为便于长期维护,建议采用 Monorepo 结构

my-cross-platform-app/
├── packages/
│   ├── electron-app/       # Electron 桌面端
│   ├── harmony-app/        # 鸿蒙移动端
│   └── shared-web/         # 共享的 Web 核心模块(React/Vue/Svelte)
├── scripts/
│   └── build-web.sh        # 构建 shared-web 并复制到两个项目
└── README.md

通过脚本自动化同步资源,确保两端始终使用同一版本的前端代码。


六、性能与体验优化策略

6.1 减少 Web 容器开销

  • 启用鸿蒙 Web 组件的硬件加速:.webDebuggingAccess(true)(仅调试)
  • 避免复杂 DOM 操作,优先使用 Canvas 或 WebGL 渲染图表

6.2 渐进式原生化

对于高频交互模块(如导航栏、手势操作),可逐步替换为 ArkTS 原生组件,仅保留核心业务在 Web 中:

Column() {
  // 原生顶部栏
  CustomNavigationBar({ title: '编辑器' })
  
  // Web 内容区
  Web({ src: 'local://webapp/editor-body.html' })
}

七、未来展望:从融合到共生

随着鸿蒙 NEXT 的全面落地(不再兼容 APK,纯自研内核),以及 Electron 社区对轻量化的探索(如 Electron Lite、WebContainer 技术),我们有理由相信:

  • Web 将继续作为跨端开发的“通用语言”
  • Electron 不再只是“桌面框架”,而是“Web 应用容器”的一种实现
  • 鸿蒙将成为 Web 应用在移动端、IoT 端的重要承载平台

结语

Electron 与鸿蒙,一个是桌面时代的集大成者,一个是全场景时代的开拓者。它们不是替代关系,而是时代接力中的协作者。通过 Web 容器这一桥梁,我们既能保留现有 Electron 应用的投资,又能拥抱鸿蒙生态的广阔前景。

技术的价值不在于站队,而在于解决问题。愿每一位开发者都能在这场跨平台融合的浪潮中,找到属于自己的创新路径。


Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐