鸿蒙5.0实战案例:基于hvigor插件定制构建

往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)

✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~

✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✏️ 记录一场鸿蒙开发岗位面试经历~

✏️ 持续更新中......


场景描述

在编译构建的过程中如何插入使用者需要的自定义构建任务,使用者可以通过什么方式获取扩展编译构建参数从而在运行时获取自定义的参数以及自定义修改编译产物属性。

能力说明

hvigor-ohos-plugin插件支持在hvigorfile.ts里插入使用者的自定义构建任务,并且在运行时获取到自定义的一些编译参数,以及实现修改产物属性的功能。

一、 构建生命周期以及任务流程

1.构建生命周期

hvigor有三个不同的阶段,分为初始化、配置和执行,hvigor会按顺序运行这些阶段。

初始化*:

  1. 根据命令参数和hvigor-config.json5文件中的配置,设置hvigor的构建参数,并构造出hvigor对象,此对象贯穿整个hvigor生命周期,从最开始创建出来一直到此次构建结束才被销毁。

  2. 通过项目根目录下的build-profile.json5文件,创建出rootNodeDescriptor实例,并通过其中的modules字段,来初始化出工程中所有模块的NodeDescriptor对象实例。

  3. 执行项目根目录下的hvigorconfig.ts文件,可以在此文件中通过hvigor的相关API来为生命周期注册hook或在构建开始时进行其他处理。

  4. 构造出每个节点的HvigorNode对象实例。

配置:

  1. 执行每个node中的hvigorfile.ts文件,为每个node添加plugin,执行plugin的apply方法,并添加plugin的上下文。

  2. 根据前一步加载出的plugin和task,构造出DAG图。

hvigor在执行任何任务之前会构建任务依赖图,所有任务会形成一个有向无环图(DAG),如下示例图,任务之间的依赖关系用箭头进行表示:

执行:

  1. 执行选定的任务。

  2. 任务之间的依赖关系决定了任务执行顺序。

  3. 任务可以并行执行。

2.HAP基础任务流程

二、 获取自定义参数:

方式1(生成BuildProfile类文件):

HAP/HSP运行时获取编译构建参数

生成BuildProfile类文件

当前有以下几种方式可以生成BuildProfile类文件:

选中需要编译的模块,在菜单栏选择"Build > Generate Build Profile ${moduleName}"。

在菜单栏选择"Build > Build Hap(s)/APP(s) > Build Hap(s)"或"Build > Build Hap(s)/APP(s) > Build APP(s)"

生成BuildProfile类文件后,在代码中可以通过如下方式引入该文件:

  1. import BuildProfile from'BuildProfile';

  2. 通过如下方式获取到构建参数:

    @State message: string = BuildProfile.BUNDLE_NAME;

  3. 默认参数

    生成BuildProfile类文件时,Hvigor会根据当前工程构建的配置信息生成一部分默认参数,开发者可以在代码中直接使用。

表1

参数名 类型 说明
BUNDLE_NAME string 应用的Bundle名称。
BUNDLE_TYPE string 应用的Bundle类型。
VERSION_CODE number 应用的版本号。
VERSION_NAME string 应用版本号的文字描述。
TARGET_NAME string Target名称。
PRODUCT_NAME string Product名称。
BUILD_MODE_NAME string 编译模式。
DEBUG boolean 应用是否可调试。
  1. 自定义参数

开发者可以在模块级的build-profile.json5文件中增加自定义参数,在生成BuildProfile类文件后,在代码中使用自定义参数。

自定义参数可以在buildOption、buildOptionSet、targets节点下的arkOptions子节点中通过增加buildProfileFields字段实现,自定义参数通过key-value键值对的方式配置,其中value取值仅支持number、string、boolean类型。

方式2(hvigor API):

getBuildMode: () => string==>通过该方法获取编译模式(相关文档简单给出一些API)

复制代码
const node = getNode(__filename);

const appContext = node.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;

const buildMode = appContext.getBuildMode();

console.log(buildMode);

另外也提供了相关获取扩展参数的 API :示例:getExtParams4.1.2+ ==>获取全部的-p扩展参数对象。

getExtParams(): Record<string, string> =>命令行中所有配置的-p参数集合对象

复制代码
import { hvigor } from '@ohos/hvigor';

const extParams = hvigor.getParameter().getExtParams();

console.log(extParams['key']);

// 执行命令./hvigorw --sync -p key=hello,控制台打印:hello

三、 修改打包产物属性

hvigor-ohos-plugin插件支持在hvigorfile.ts里接收部分编译配置,以实现动态配置构建配置、并使能到构建的过程与结果中。

在hvigorfile.ts中,我们约定在导出的对象中的config.ohos属性里接收编译的配置,配置在overrides项中的参数,其优先级会高于在配置项中的对应字段。

工程级

appOpt:对应app.json5里的配置项字段。bundleName, bundleType, icon, label, vendor, versionCode, versionName

模块级

buildOption:对应build-profile.json5里的buildOption配置项。

arkOptions, externalNativeOptions, napiLibFilterOption, nativeLib,resOptions, sourcOption.

方法一:通过overrides动态修改配置项中的参数

复制代码
export default {

system: appTasks,

plugins: [],

config: {

ohos: {

overrides:{

appOpt: {

versionCode: getVersionCode(),

versionName: getVersionName(),

icon: getIcon()

} //app.json中的内容

}

}

}

}

function getVersionCode() {

// return 100000+Date.now().getYear();

return 1;

}

function getVersionName() {

// return `1.0.0${Date.now().getTime()}`;

return "2";

}

function getIcon() {

// return 100000+Date.now().getYear();

// return "C:\\Users\\xxx\\DevEcoStudioProjects\\DemoHvigorFile\\AppScope\\resources\\base\\media\\app_icon.png";

return "C:\\Users\\xxx\\DevEcoStudioProjects\\DemoHvigorFile\\AppScope\\resources\\base\\media\\huawei.png";

}

export default {

system: appTasks,

plugins:[customPlugin()]

};

方法二:通过hvigor API 去修改

通过odesEvaluated hook获取插件向node中注册的context,然后通过这个context操作一些任务.

首先根据hvigorfile.ts路径获取当前节点->getNode(__filename),

然后根据pluginId获取当前节点上指定插件的上下文接口信息->getContext(),

获取当前构建指定的BuildMode ->getBuildMode(),

最后根据编译模式去修改app.json5里的配置项字段从而修改产物属性.

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

import { hvigor, getNode } from '@ohos/hvigor';

hvigor.nodesEvaluated(() => {

const node = getNode(__filename);

const appContext = node.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;

const buildMode = appContext.getBuildMode();

console.log(buildMode);

console.log('projectName:', appContext.getProjectName());

const appJson5 = appContext.getAppJsonOpt();

if (appContext.getBuildMode() === 'debug') {

appJson5.app.versionName = '1.0.0';

} else {

appJson5.app.versionName = '1.0.1';

}

appContext.setAppJsonOpt(appJson5);

});

export default {

system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */

plugins:[] /* Custom plugin to extend the functionality of Hvigor. */

}

四、自定义构建任务

通过在hvigorfile.ts里插入自定义任务。

首先在hvigorfile.ts文件中只需定义一个pluginId(任务Id)和name(任务名称),并实现其中的run方法,即可创建一个任务,

然后当前node节点添加插件并执行插件的apply方法,然后调用接口pluginContext中的registerTask方法,在此方法中去编写自定义任务,设置任务名称,

实现其中的run方法如下demo打印任务名称,模块名称moduleName,模块的绝对路径modulePath,

最后在设置任务插入执行流程的位置.

复制代码
import { hapTasks } from '@ohos/hvigor-ohos-plugin';

export function customPluginFunction1(str?: string) {

return {

pluginId: 'CustomPluginID1',

apply(pluginContext) {

//注册自定义任务 接口pluginContext 方法registerTask

pluginContext.registerTask({

// 编写自定义任务

name: 'customTask1',

run: (taskContext) => {

// taskContext.moduleName;

// taskContext.modulePath;

//接口 taskContext 模块名称 moduleName 模块的绝对路径 modulePath

console.log('customTask1: ',taskContext.moduleName, taskContext.modulePath);

},

// 确认自定义任务插入位置

dependencies: ['default@BuildJS'],

postDependencies: ['default@CompileArkTS']

})

}

}

}

export function customPluginFunction2(str?: string) {

return {

pluginId: 'CustomPluginID2',

apply(pluginContext) {

pluginContext.registerTask({

name: 'customTask2',

run: (taskContext) => {

console.log('customTask2: ',taskContext.moduleName, taskContext.modulePath);

},

dependencies: ['default@BuildJS'],

postDependencies: ['default@CompileArkTS']

})

}

}

}

export function customPluginFunction3(str?: string) {

return {

pluginId: 'CustomPluginID3',

apply(pluginContext) {

pluginContext.registerTask({

name: 'customTask3',

run: (taskContext) => {

console.log('customTask3: ',taskContext.moduleName, taskContext.modulePath);

},

dependencies: ['customTask1'],

postDependencies: ['customTask2']

})

}

}

}

export default {

system: hapTasks, // Hvigor内置插件,不可修改

plugins: [customPluginFunction1(), customPluginFunction2(),customPluginFunction3()] // 自定义插件

}

定制任务插入位置效果:

相关推荐
别说我什么都不会13 小时前
ohos.net.http请求HttpResponse header中set-ccokie值被转成array类型
网络协议·harmonyos
码是生活13 小时前
鸿蒙开发排坑:解决 resourceManager.getRawFileContent() 获取文件内容为空问题
前端·harmonyos
鸿蒙场景化示例代码技术工程师13 小时前
基于Canvas实现选座功能鸿蒙示例代码
华为·harmonyos
小脑斧爱吃鱼鱼14 小时前
鸿蒙项目笔记(1)
笔记·学习·harmonyos
鸿蒙布道师15 小时前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
zhang10620915 小时前
HarmonyOS 基础组件和基础布局的介绍
harmonyos·基础组件·基础布局
马剑威(威哥爱编程)15 小时前
在HarmonyOS NEXT 开发中,如何指定一个号码,拉起系统拨号页面
华为·harmonyos·arkts
GeniuswongAir17 小时前
Flutter极速接入IM聊天功能并支持鸿蒙
flutter·华为·harmonyos
90后的晨仔20 小时前
鸿蒙ArkUI框架中的状态管理
harmonyos
别说我什么都不会2 天前
OpenHarmony 5.0(API 12)关系型数据库relationalStore 新增本地数据变化监听接口介绍
api·harmonyos