商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 鸿蒙开发Hvigor插件动态生成代码的操作方法

鸿蒙开发Hvigor插件动态生成代码的操作方法

  发布于2026-07-21 阅读(0)

扫一扫,手机访问

Hvigor 给了开发者一个相当灵活的扩展空间——你可以自己写插件,把自定义的构建逻辑塞进去,还能跟别人共享。目前 Hvigor 支持两种插件开发方式:一种是直接基于 hvigorfile 脚本,另一种是基于 TypeScript 项目。这里先聊聊第一种,基于 hvigorfile 脚本开发,上手快,改起来也方便。

基于 hvigorfile 脚本开发

直接在工程或模块下的 hvigorfile.ts 里写插件代码,好处是即改即用,不需要额外搭建项目结构。不过缺点也很明显:想在不同项目之间复用就比较麻烦,没法像独立的 npm 包那样分发共享。

先导入必要的接口:

// 导入接口
import { HvigorPlugin, HvigorNode } from '@ohos/hvigor'

然后定义一个插件方法,实现 HvigorPlugin 接口:

// 实现自定义插件
function customPlugin(): HvigorPlugin {
    return {
        pluginId: 'customPlugin',
        apply(node: HvigorNode) {
            // 插件主体
            console.log('hello customPlugin!');
        }
    }
}

最后在导出声明里把插件注册进去:

export default {
    system: appTasks,
    plugins:[
        customPlugin()  // 应用自定义Plugin
    ]
}

流程就这么简单。但真正有意思的是,我们可以用这个机制解决一些日常开发中的痛点。下面两个例子就很能说明问题。

自动生成 na vigation 防混淆文件

使用系统路由表时,每次添加新页面都得在 release 环境下配一下混淆规则,否则页面名被混淆后导航就失败了。要是把页面都放在一个固定目录下,和模块化设计又冲突;用固定前缀或后缀命名,又总觉得怪怪的。手动一个一个加,虽然符合规范,但确实繁琐。

其实可以写一个 Hvigor 插件来自动生成混淆配置文件。思路很简单:自定义一个 HvigorPlugin 任务,通过 OhosHapContext 对象读取 module.json5 中的 routerMap 字段,拿到系统路由表的名称,再去 profile 目录下解析对应的 JSON 文件,提取所有页面路径,然后写入一个混淆文件。每次编译时自动生成,我们只需要在混淆配置里引入这个文件就好。

import { hapTasks, OhosHapContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin'
import { HvigorPlugin, HvigorNode, FileUtil } from '@ohos/hvigor'

function parseRouterMap(): HvigorPlugin {
  return {
    pluginId: 'parseRouterMap',
    apply(node: HvigorNode) {
      const hapCtx = node.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext
      const moduleJson = hapCtx.getModuleJsonOpt()
      const routerMapName = moduleJson['module']['routerMap'].split(':')[1]
      const dir = hapCtx.getModulePath()
      const srcFile = FileUtil.pathResolve(dir, 'src', 'main', 'resources', 'base', 'profile', `${routerMapName}.json`)
      const json = FileUtil.readJson5(srcFile)
      const routerRuleFile = FileUtil.pathResolve(dir, 'obfuscation-router.txt')
      FileUtil.ensureFileSync(routerRuleFile)
      const routerMapArray = json['routerMap']
      let rules = '-keep-file-name\n'
      for (const element of routerMapArray) {
        const pageSourceFile = element['pageSourceFile']
        const path = pageSourceFile.substring(0, pageSourceFile.lastIndexOf('.'))
        rules += `${path}\n`
      }
      FileUtil.writeFileSync(routerRuleFile, rules)
    }
  }
}

export default {
  system: hapTasks,
  plugins:[parseRouterMap()]
}

编译完成后,在 entry 目录下会生成一个 obfuscation-router.txt 文件,直接把它引入到混淆配置里就行了。

自动生成 na vigation 页面枚举名称

另一个常见的痛点:用 na vigation 做 push 跳转时,必须提前定义好系统路由表中的页面 name,一旦写错,跳转过去就是白屏。有了前面的经验,其实可以如法炮制——动态生成一个 .ets 文件,把系统路由表中的页面名称自动转成枚举,这样每次配置路由表后,枚举值也跟着更新,再也不用手动复制粘贴了。

假设系统路由表是这样的:

{
  "routerMap": [
    {
      "name": "dialog",
      "pageSourceFile": "src/main/ets/pages/dialog/DialogPage.ets",
      "buildFunction": "dialogBuilder"
    },
    {
      "name": "web",
      "pageSourceFile": "src/main/ets/pages/web/WebPage.ets",
      "buildFunction": "webBuilder"
    },
    {
      "name": "login",
      "pageSourceFile": "src/main/ets/pages/login/LoginPage.ets",
      "buildFunction": "loginBuilder"
    }
  ]
}

对应的插件实现如下:

import { hapTasks, OhosHapContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin'
import { HvigorPlugin, HvigorNode, FileUtil } from '@ohos/hvigor'

function parseRouterMap(): HvigorPlugin {
  return {
    pluginId: 'parseRouterMap',
    apply(node: HvigorNode) {
      const hapCtx = node.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext
      const moduleJson = hapCtx.getModuleJsonOpt()
      const routerMapName = moduleJson['module']['routerMap'].split(':')[1]
      const dir = hapCtx.getModulePath()
      const srcFile = FileUtil.pathResolve(dir, 'src', 'main', 'resources', 'base', 'profile', `${routerMapName}.json`)
      const json = FileUtil.readJson5(srcFile)
      const routerMapFile = FileUtil.pathResolve(dir, 'src', 'main', 'ets', 'Pages.ets')
      FileUtil.ensureFileSync(routerMapFile)
      const routerMapArray = json['routerMap']
      let ss = ''
      for (const element of routerMapArray) {
        const name = element['name']
        ss += `  ${name} = '${name}',\n`
      }
      ss = `export enum Pages {\n${ss}}`
      FileUtil.writeFileSync(routerMapFile, ss)
    }
  }
}

export default {
  system: hapTasks,
  plugins:[parseRouterMap()]
}

运行后,在 ets 目录下会生成一个 Pages.ets 文件,内容如下:

export enum Pages {
  dialog = 'dialog',
  web = 'web',
  login = 'login',
}

之后在页面跳转时直接使用 Pages.dialog 这样的枚举值,既安全又省心。每次修改路由表,枚举文件都会自动更新,完全不需要手动维护。

本文转载于:https://www.jb51.net/program/331095uw3.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注