【hvigor专栏】OpenHarmony应用开发-hvigor插件之动态修改应用hap文件名

前言

在OpenHarmony应用开发中,动态修改应用hap文件名是较为常见的功能,比如文件名包含版本号、构建时间、编译模式等等。下文会以一个完整的示例为大家讲述如何实现此功能。

开发环境

DevEco Studio: DevEco Studio 6.0.0 Release(Build Version: 6.0.0.858)

开发流程

前置步骤

  1. 创建新工程。

  2. 编译工程,可以看到build/default/outputs/default/目录下生成了名为entry-default-unsigned.hap的默认hap。

新增artifactName

entry模块的build-profile.json5下新增

json 复制代码
{
  ···
  "targets": [
    {
      "name": "default",
      ···
      "output": {
        "artifactName": "samples"
      }
    }
  ]
}

新增hvigor任务

在根目录hvigorfile.ts里修改为以下代码

ts 复制代码
import { appTasks, OhosAppContext, OhosHapContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin';
import { hvigor } from '@ohos/hvigor';

// 动态修改应用hap文件名
export function dynamicChangeNamePlugin(): HvigorPlugin {
  return {
    pluginId: 'dynamicChangeNamePlugin',
    context() {
      return {
        data: 'modify output name'
      };
    },
    async apply(currentNode: HvigorNode): Promise<void> {
      // 获取app插件的上下文对象
      const appContext = currentNode.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;
      // 通过上下文对象获取从根目录build-profile.json5文件中读出来的obj对象
      const buildProfileOpt = appContext.getBuildProfileOpt();
      const appJsonOpt = appContext.getAppJsonOpt();
      // 修改obj对象为想要的,此处举例修改app中的signingConfigs
      const products = buildProfileOpt.app.products;
      let date = new Date();
      let formatDate = date.getFullYear().toString() + (date.getMonth() + 1).toString().padStart(2, '0') +
      date.getDate().toString().padStart(2, '0') + '_' + date.getHours().toString().padStart(2, '0') +
      date.getMinutes().toString().padStart(2, '0') + date.getSeconds().toString().padStart(2, '0');
      for (const product of products) {
        if (product.name == 'default') {
          product.output.artifactName = formatDate + '_' + appJsonOpt.app.versionName + '_' +
          product.output.artifactName + '_' + appContext.getBuildMode();
          console.info(`output app name: ${product.output.artifactName}`);
        }
      }
      // 将obj对象设置回上下文对象以使能到构建的过程与结果中
      appContext.setBuildProfileOpt(buildProfileOpt);
      hvigor.nodesEvaluated(async () => {
        currentNode.subNodes((node: HvigorNode) => {
          // 获取hpp插件的上下文对象
          const hapContext = node.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext;
          // 通过上下文对象获取从根目录build-profile.json5文件中读出来的obj对象
          const hapBuildProfileOpt = hapContext?.getBuildProfileOpt();
          if (hapBuildProfileOpt != undefined) {
            const targets = hapBuildProfileOpt['targets'];
            for (const target of targets) {
              if (target.name == 'default' && target.output?.artifactName != undefined) {
                target.output.artifactName = formatDate + '_' + appJsonOpt.app.versionName + '_' +
                target.output.artifactName + '_' + appContext.getBuildMode();
                console.info(`output hap name: ${target.output?.artifactName}`);
              }
            }
            hapContext.setBuildProfileOpt(hapBuildProfileOpt);
          }
        })
      })
    }
  }
}

export default {
  system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
  plugins: [
    dynamicChangeNamePlugin()
  ]       /* Custom plugin to extend the functionality of Hvigor. */
}

编译验证

  1. 编译工程,可以看到build/default/outputs/default/目录下生成了名为20251117_113634_1.0.0_samples_debug-unsigned.hap的自定义文件名hap,其中包含了构建时间、版本号、自定义产物名、编译模式、是否签名等信息。

注意事项

  1. 如果自定义文件名里包含了时间规则,那么因为时间的变化,每次打出的hap都不会覆盖前一个,而是会创建一个新的,从而导致hap越来越多,本地工程体积越来越大。
相关推荐
天蓝色的鱼鱼2 小时前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
泯泷3 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
妙码生花3 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
泯泷3 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
团团崽_七分甜3 小时前
Spring Boot 核心知识点总结
前端
lichenyang4533 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕4 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js
朦胧之4 小时前
页面白屏卡住排查方法
前端·javascript
用户593608741404 小时前
Playwright 黑魔法:用 ClipboardEvent 绕过 React 富文本编辑器
前端