HarmonyOS鸿蒙Next中web迁移方案

HarmonyOS鸿蒙Next中web迁移方案 【问题描述】:应用是使用web技术栈开发,是否有一些比较好的迁移方案?目前应用的核心功能已经完成大部分了。

【问题现象】:不涉及。

【版本信息】:不涉及。

【复现代码】:不涉及。

【尝试解决方案】:无。

4 回复

小伙伴你好,可以使用 ArkWeb组件 来实现 Web 应用的快速迁移和混合开发,可以最大程度复用现有 Web 资产代码。

解决方案

方案一:ArkWeb组件嵌入方案

说明:这是迁移成本最低的方案。通过 Web组件 来加载现有的Web页面,配合JSBridge实现原生与Web的双向通信。您现有的Web核心功能可以直接复用,只需开发原生壳和必要的桥接逻辑即可。

实现流程

cke_7124.png

实现步骤

1. 创建Web组件加载页面

代码示例

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'https://your-web-app.com', controller: this.controller })
        .width('100%')
        .height('100%')
    }
  }
}

2. 配置应用侧调用前端页面函数

当需要从原生侧调用Web页面的JavaScript函数时,使用 runJavaScript() 方法。

代码示例

import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Button('调用JS函数')
        .onClick(() => {
          // 调用前端页面的JavaScript函数
          this.controller.runJavaScript('yourJsFunction()')
            .then((result) => {
              console.log('runJavaScript result: ' + result);
            })
            .catch((error: BusinessError) => {
              console.error(`runJavaScript error: ${error.code}, ${error.message}`);
            });
        })
      
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .width('100%')
        .height('100%')
    }
  }
}

3. 配置前端页面调用应用侧函数

当Web页面需要调用原生能力时,通过 javaScriptProxy 注册原生对象供前端调用。

代码示例

import { webview } from '@kit.ArkWeb';

/**
 * 定义供前端调用的原生对象类
 */
class NativeBridge {
  /**
   * 获取设备信息
   * @returns 设备信息字符串
   */
  getDeviceInfo(): string {
    return 'HarmonyOS Device';
  }

  /**
   * 显示原生Toast
   * @param message 消息内容
   */
  showToast(message: string): void {
    console.info('Toast: ' + message);
    // 调用原生Toast API
  }

  /**
   * 打开原生页面
   * @param pageName 页面名称
   */
  openNativePage(pageName: string): void {
    console.info('Open page: ' + pageName);
    // 实现原生页面跳转
  }
}

@Entry
@Component
struct WebComponent {
  controller: webview.WebviewController = new webview.WebviewController();
  // 创建原生桥接对象
  nativeBridge: NativeBridge = new NativeBridge();

  build() {
    Column() {
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .javaScriptProxy({
          object: this.nativeBridge,
          name: 'nativeBridge',  // 前端通过此名称调用
          methodList: ['getDeviceInfo', 'showToast', 'openNativePage'],
          controller: this.controller
        })
        .width('100%')
        .height('100%')
    }
  }
}

4. 前端页面调用原生方法

在您的Web页面中,可以直接通过注册的对象名调用原生方法:

// 前端JavaScript代码
// 获取设备信息
const deviceInfo = nativeBridge.getDeviceInfo();
console.log(deviceInfo);

// 显示原生Toast
nativeBridge.showToast('操作成功');

// 打开原生页面
nativeBridge.openNativePage('settingsPage');

关键API说明


方案二:混合开发方案(ArkUI + ArkWeb)

说明:将关键页面(如首页、登录页)使用ArkUI原生开发以获得更好的性能和用户体验,复杂业务页面继续使用Web组件加载。这种方案兼顾了开发效率和用户体验。

实现步骤

1. 识别关键页面:分析应用的页面结构,将高频访问、性能敏感的页面标记为需要原生化的页面

2. 原生页面与Web页面混合架构

// MainPage.ets - 原生首页
import { router } from '@kit.ArkUI';

@Entry
@Component
struct MainPage {
  build() {
    Column() {
      // 原生首页内容,获得最佳性能
      Text('首页')
        .fontSize(24)
      
      Button('进入业务页面')
        .onClick(() => {
          // 跳转到Web页面
          router.pushUrl({ url: 'pages/WebBusinessPage' });
        })
    }
  }
}
// WebBusinessPage.ets - Web业务页面
import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebBusinessPage {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      Web({ src: 'https://your-web-app.com/business', controller: this.controller })
        .width('100%')
        .height('100%')
    }
  }
}

建议方案

  • 首页、登录页等高频页面建议原生化
  • 复杂业务逻辑页面可继续使用Web
  • 通过统一的导航框架管理原生页面和Web页面
  • 保持一致的UI风格和交互体验

方案三:加载本地Web资源方案

说明:将Web应用打包到应用的 rawfile 目录中,通过加载本地资源实现离线访问,提升加载速度和用户体验。适合对网络依赖较小的应用场景。

实现步骤

1. 将Web资源放入rawfile目录

将打包后的Web资源(HTML、CSS、JS、图片等)放入 src/main/resources/rawfile/ 目录:

src/main/resources/rawfile/
├── index.html
├── css/
│   └── style.css
├── js/
│   └── app.js
└── images/
    └── logo.png

2. 加载本地Web资源

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct LocalWebPage {
  controller: webview.WebviewController = new webview.WebviewController();

  build() {
    Column() {
      // 加载本地HTML文件
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .width('100%')
        .height('100%')
        .domStorageAccess(true)  // 启用DOM存储
        .fileAccess(true)        // 启用文件访问
    }
  }
}

建议方案

  • 适合离线场景或网络环境较差的情况
  • 加载速度更快,用户体验更好
  • 需要在应用更新时同步更新Web资源
  • 注意资源文件大小对应用包体积的影响

迁移建议

推荐迁移路径

根据您的情况(核心功能已完成大部分),建议采用以下渐进式迁移路径:

阶段 目标 工作内容
第一阶段 快速上架 使用方案一,通过Web组件直接加载现有Web应用
第二阶段 体验优化 使用方案二,将首页等关键页面原生化
第三阶段 深度优化 根据用户反馈,逐步将更多页面原生化

Web组件生命周期管理

在迁移过程中,了解 Web组件的生命周期 对于正确管理页面状态非常重要:

  • onPageBegin:页面开始加载时触发
  • onPageEnd:页面加载完成时触发
  • onProgressChange:页面加载进度变化时触发
  • onErrorReceive:页面加载错误时触发
Web({ src: 'https://your-web-app.com', controller: this.controller })
  .onPageBegin((event) => {
    console.info('页面开始加载: ' + event?.url);
  })
  .onPageEnd((event) => {
    console.info('页面加载完成: ' + event?.url);
  })
  .onProgressChange((event) => {
    console.info('加载进度: ' + event?.newProgress);
  })
  .onErrorReceive((event) => {
    console.error('加载错误: ' + event?.error?.getErrorInfo());
  })

参考文档

更多关于HarmonyOS鸿蒙Next中web迁移方案的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


ArkWeb,新建一个项目,然后直接把web应用放在里面

HarmonyOS Next中Web迁移方案采用ArkWeb组件替代传统WebView,支持前端页面无缝迁移。该方案基于ArkTS/ArkUI开发框架,通过适配鸿蒙渲染引擎与JS引擎实现Web标准兼容。迁移时需将原有Web业务逻辑封装为HAP包,调用鸿蒙API处理系统权限与生命周期。ArkWeb提供Cookie管理、缓存控制等扩展能力,支持主流前端框架(Vue/React)代码直接运行。

针对Web技术栈应用迁移到HarmonyOS Next,推荐以下方案:

  1. 使用ArkTS Web组件
    通过Web组件直接嵌入现有网页,可复用大部分前端代码。需注意:

    • 适配HarmonyOS权限机制(如网络访问权限)
    • 通过WebController实现原生与JS的交互
  2. 渐进式迁移
    将核心业务模块逐步重构为ArkTS组件,非核心功能暂保留在Web容器中。优势:

    • 保持现有业务连续性
    • 分阶段享受原生性能提升
  3. 桥接能力优化
    利用WebViewJavaScriptProxy实现:

    • 前端调用HarmonyOS硬件能力(相机、地理位置等)
    • 双向数据通信(原生→JS / JS→原生)
  4. 容器化部署
    若应用含服务端渲染(SSR)需求,可搭配轻量级容器统一管理Web资源,通过本地加载提升性能。

建议优先评估业务模块的交互复杂度,对强依赖原生能力的模块(如支付、音视频)优先迁移,纯展示类页面可暂留Web方案。

回到顶部