写点什么

鸿蒙开发 Hvigor 插件动态生成代码

作者:龙儿筝
  • 2024-11-20
    上海
  • 本文字数:2605 字

    阅读完需:约 9 分钟

Hvigor 允许开发者实现自己的插件,开发者可以定义自己的构建逻辑,并与他人共享。Hvigor 主要提供了两种方式来实现插件:基于 hvigorfile 脚本开发插件、基于 typescript 项目开发。下面以基于 hvigorfile 脚本开发插件进行介绍。

基于 hvigorfile 脚本开发

基于 hvigorfile.ts 脚本开发的方式,其优点是可实现快速开发,直接编辑工程或模块下 hvigorfile.ts 即可编写插件代码,不足之处是在多个项目中,无法方便的进行插件代码的复用和共享分发。


  1. 导入模块依赖。


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


  1. 编写插件代码。

  2. 在 hvigorfile.ts 中定义插件方法,实现 HvigorPlugin 接口。


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


  1. 在导出声明中使用插件。


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

使用 hvigorfile 插件动态生成 navigation 防混淆文件

我们在使用 navigation 的系统路由表时,每次添加新页面,都需要配置一下 release 环境防混淆。若将这些页面放在一个固定的目录下,则与我们的模块化设计相违背,若命名使用固定的前缀或后缀,总感觉有点多余,手动一个一个的添加,虽然符合我们的代码规范设计,但就是有点繁琐。有没有更方便的方式来处理这个混淆配置呢?


其实我们可以在写一个 hvigorfilew 插件来自动生成混淆配置文件。我们自定义一个 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 防混淆文件,只要引入这个文件就可以了。

使用 hvigorfile 插件动态生成 navigation 页面枚举名称

我们在我们 navigation 的 push 跳转到新页面时,都得提前定义好系统路由表中的页面 name,因为使用的 name 与系统路由表中定义的 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"    }  ]}
复制代码


我们现在实现一个 hvigorfile 插件,来解析系统路由表中的 name 字段,并生成对应的枚举值。示例如下


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 文件,并将所有 navigation 页面生成对应的枚举值,页面跳转时,使用这些枚举值就不怕出错了。Pages.ets 内容如下


export enum Pages {  dialog = 'dialog',  web = 'web',  login = 'login',}
复制代码


发布于: 刚刚阅读数: 3
用户头像

龙儿筝

关注

还未添加个人签名 2024-10-27 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙开发Hvigor插件动态生成代码_龙儿筝_InfoQ写作社区