【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越来越多,本地工程体积越来越大。
相关推荐
狗哥哥11 分钟前
Vue 3 动态菜单渲染优化实战:从白屏到“零延迟”体验
前端·vue.js
青青很轻_12 分钟前
Vue自定义拖拽指令架构解析:从零到一实现元素自由拖拽
前端·javascript·vue.js
树下水月19 分钟前
纯HTML 调用摄像头 获取拍照后的图片的base64
前端·javascript·html
蜗牛攻城狮23 分钟前
Vue 中 `scoped` 样式的实现原理详解
前端·javascript·vue.js
豆苗学前端29 分钟前
前端工程化终极指南(Webpack + Gulp + Vite + 实战项目)
前端·javascript
比老马还六29 分钟前
Bipes项目二次开发/海龟编程(六)
前端·javascript
梨子同志29 分钟前
Node.js 文件系统 fs
前端
码农胖大海30 分钟前
微前端架构(二):封装与实现
前端
瘦的可以下饭了31 分钟前
2 数组 递归 复杂度 字符串
前端·javascript
Kellen31 分钟前
ReactDOM.preload
前端·react.js