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

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

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

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

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

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

✏️ 持续更新中……


概述

在进行编译构建的过程中,开发者可以通过定制hvigor插件,扩展构建逻辑,实现个性化的打包流程。

定制hvigor插件,通常有以下目的:

  • 满足自定义任务需求。

每个项目可能有独特的构建需求和流程,定制插件可以根据项目的具体要求来扩展hvigor构建的功能。

  • 加强构建任务可维护性。

定制插件可以将某些复杂的构建逻辑封装在同一个地方,使得项目的构建配置更加清晰和易于维护。可以自动化执行某些特定任务,减少手动干预,确保构建过程的一致可靠。

  • 提升团队协作效率。

在团队开发中,定制插件可以确保所有团队成员使用相同的构建流程和标准,减少因个人配置差异导致的问题,从而提升团队协作的效率。

具体到应用场景上,定制插件可以根据不同的构建需求调整编译产物属性,从而实现灵活的构建管理。

本文以自定义编译产物的文件名及路径为案例来介绍如何定制hvigor插件。

基本概念

定制hvigor插件开发时,涉及以下概念:

  • hvigor:基于TS实现的构建任务编排工具,主要提供任务管理机制,包括任务注册编排、工程模型管理、配置管理等关键能力。
  • hvigor-ohos-plugin:hvigor默认提供的构建插件,利用hvigor的任务编排机制实现应用/元服务构建任务流的执行,完成HAP/App的构建打包,应用于应用/元服务的构建。
  • Task:即构建任务,作为hvigor构建过程中的基本工作单元,构建项目的具体工作由Task描述表达,比如源码编译任务,打包任务或签名任务等。每一种任务的执行逻辑由plugin插件提供。
  • 编译产物:即工程/模块编译后的目标,是项目打包生成的用于依赖或运行的包文件,包括HAP(应用安装运行的基本单位)、HAR(静态共享包)、HSP(动态共享包)以及App(可上架的完整应用程序)等多种类型。

实现原理

定制hvigor插件,就是在编译构建的过程中插入开发者需要的自定义任务,将这些自定义任务抽象后封装成可复用的部分,通过输出plugin插件的目标形式,实现编译构建个性化逻辑的复用和共享分发。

如上图所示,hvigor插件的工作原理:

  1. 开发者编写自定义插件plugin,在插件中自定义任务Task,在项目构建脚本中应用插件。
  2. hvigor-ohos-plugin将默认构建任务和自定义插件任务,都装进hvigor任务流。
  3. hvigor任务流按序执行的过程中,hvigor在节点处检查,如果有自定义任务注册,执行相应的自定义任务逻辑。

开发流程

hvigor主要提供了两种方式以实现插件的开发:

  • 基于hvigorfile脚本开发
  • 基于typescript项目开发

两种方式的核心逻辑实现类似,都是以TS文件编写Task任务方法,区别主要在共享和应用方式上。

二者对比如下:

表1 定制hvigor插件的两种方式对比

插件项目 代码开发 共享方式 插件使用 特点总结
基于hvigorfile脚本 不创建项目 直接编辑工程/模块中hvigorfile.ts文件 不发布,复制代码实现共享 代码逻辑直接应用于编辑工程/模块 开发使用快速;共享复用不方便
基于typescript项目 新建npm项目 新建custom-plugin.ts文件 npm打包发布共享,或离线包共享 hvigor-config.json5中配置插件依赖,或安装离线包 易于分发、共享和维护;发布使用流程相对多

下文的场景实例采用[基于typescript项目开发的方法描述,开发者也可以将插件逻辑代码直接写于hvigorfile.ts中,切换为基于hvigorfile脚本开发的实现方式。

定制hvigor插件涉及的相关能力,可查阅扩展构建API。

自定义编译产物的文件名及路径

场景描述

以名为library的module生成HAR包为例,默认情况下,HAR包编译产物的生成路径在library/build/default/outputs/default目录下,文件名为library.har。

而开发者在用于生产的环境中,可能需要根据项目情况,使编译产物输出到指定路径,并更改其文件名,例如:带有版本号的文件名,或带有开发者名称等信息的文件名。

下面示例中用oh-package.json5中配置的属性修改HAR包文件名,同时将生成路径改为library/build/default/outputs/target。

开发步骤

  1. 初始化typescript项目:配置npm环境,安装typescript依赖,新建一个npm项目做为插件的工程。
  2. 开发插件:对插件项目配置HarmonyOS镜像仓库,安装hvigor开发依赖,然后进行插件开发,以下是该场景的插件逻辑实现。
    1. 在新建的custom-plugin.ts文件中,编写任务函数renameHarTask。
    2. 在函数中注册自定义任务,使用pluginContext.registerTask方法。
    3. 通过taskContext得到modulePath(模块路径)、moduleName(模块文件名),拼装得到编译产物的原始文件路径。
    4. 根据需要,读取oh-package.json5中配置属性,拼接生成目标文件名。
    5. 使用fs.mkdir创建指定目录,再调用fs.rename,将编译产物移动到目标路径,并修改为新文件名。

插件代码示例如下:

import fs from 'fs'

interface OhPackage {
    name: string;
    version: number;
    description: string;
    author: string;
}

export function renameHarTask(str?: string) {
    return {
        pluginId: 'RenameHarTaskID',
        apply(pluginContext) {
            pluginContext.registerTask({
                // 编写自定义任务
                name: 'renameHarTask',
                run: (taskContext) => {
                    // 读取oh-package.json5,解析出version
                    const packageFile = taskContext.modulePath+'\\oh-package.json5';
                    console.log('file: ', packageFile);
                    let fileContent = fs.readFileSync(packageFile, 'utf8');
                    console.log(fileContent);
                    const content: OhPackage = JSON.parse(fileContent);
                    const version = content.version;
                    const author = content.author;

                    console.log('renameHarTask: ', taskContext.moduleName, taskContext.modulePath);
                    const sourceFile = taskContext.modulePath + '\\build\\default\\outputs\\default\\' + taskContext.moduleName + '.har';
                    const targetPath = taskContext.modulePath + '\\build\\default\\outputs\\target\\';
                    const targetFile = targetPath
                        + taskContext.moduleName + '-' + version + '-' + author +'.har';
                    console.log('renameHarTask: sourceFile: ', sourceFile);
                    console.log('renameHarTask: targetFile: ', targetFile);

                    // 创建目录
                    fs.mkdir(targetPath, { recursive: true }, (err) => {
                        if (err) throw err;
                        // 移动并修改产物文件名
                        fs.rename(sourceFile, targetFile, (err)=> {
                            console.log('err: ' + err);
                        });
                    });
                },
                // 确认自定义任务插入位置
                dependencies: ['default@PackageHar'],
                postDependencies: ['assembleHar']
            })
        }
    }
}
  1. 共享插件:有两种方式可选。
    • 发布插件:插件遵循npm发布规范,将其打包后发布到公共或自建的镜像仓库中。
    • 共享离线包:将插件工程压缩打包后分享出去。
  2. 使用插件:在工程中的hvigor/hvigor-config.json5中,添加已发布的插件(或离线包插件)依赖,执行DevEco Studio菜单File -> Sync and Refresh Project进行工程Sync后,在模块中的hvigorfile.ts导入并使用插件方法。
import { harTasks } from '@ohos/hvigor-ohos-plugin';
import { renameHarTask } from 'custom-plugin';

export default {
    system: harTasks,
    plugins:[renameHarTask()] // 应用自定义插件
}
  1. 执行Build -> Make Module编译,编译产物的文件名被修改为“name-version-author.har”的组成形式,同时生成路径从default目录改到了target目录下。结果如下图:

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐