本文为稀土技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!

上一篇我们介绍了 HarmonyOS 项目中 havigor 文件结构,以及优化构建性能的几种配置:增量构建、并行构建、守护进程配置等,同时好简单介绍了如何自定义 havigor 任务。

本篇将继续介绍 hvigor 的编译构建和插件开发。

Hvigor 构建任务图

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

HarmonyOS编译构建工具: Havigor(下)

hvigorfile.ts 文件中的构建脚本以及后面我们要介绍的 hvigor 插件都将通过任务依赖机制对任务依赖图做出影响。

Hvigor 构建生命周期

hvigor 构建的生命周期可以分为三个不同的阶段,分为初始化、配置和执行,hvigor会按顺序运行这些阶段。如下图:

HarmonyOS编译构建工具: Havigor(下)

上图呈现了 havigor 构建生命周期(Build Lifecycle),包含了构建和部署过程中的不同阶段。它分为三个主要部分:

  1. 初始化(Initialization)

    1. 根据命令参数和 hvigor-config.json5文件中的配置,设置hvigor构建参数。
    2. 检测build-profile.json5文件。
    3. 初始化 hvigor 进程并创建监听机制。
    4. 初始化环境变量,创建构建工程模型。
    5. 为每个项目创建一个 project 实例。
  2. 配置(Configuration)

    1. 根据工程和每个模块的 hvigorfile.ts文件评估参与构建的任务。

    2. 为请求的任务创建任务依赖图。

  3. 执行(Execution)

    • 执行选定的任务。
    • 任务之间的依赖关系决定了任务执行顺序。
    • 任务可以并行执行。

这张图很好的展现了任务的配置和依赖关系,以及在构建过程中的执行顺序。通过这样的系统,可以确保构建过程的高效和准确性。

Havigor 插件开发

除了上一篇介绍的在hvigorfile.ts文件中自定义任务以外,我们还可以实现自己的 havigor 插件,定义自己的构建逻辑,并且可以将我们自己开发的插件共享给其他开发者使用。hvigor 提供了两种方式来实现插件开发:

  1. 基于hvigorfile 脚本开发插件
  2. 基于 TypeScript 项目开发插件

基于 hvigorfile 脚本开发

基于这个方式开发的插件,优点是课已实现快速开发。直接边界 project 或者 module 下的hvigorfile.ts文件即可编写插件代码;但不足的是无法在多个项目中实现插件开发复用和分发。具体实现方式如下:

1.导入模块依赖

// 导入接口
import { HvigorPlugin, HvigorNode } from '@ohos/hvigor';

2.编写插件代码

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

/**
 * 自定义插件 routePlugin
 * @returns 
 */
function routePlugin(): HvigorPlugin {
    return {
        pluginId: 'routePlugin',
        apply(node: HvigorNode) {
            // 插件主体
            console.log('hello routePlugin!');
        }
    }
}

3.插件应用

export default {
    system: appTasks,  /* Built-in plugin of Hvigor. It cannot be modified. */
    plugins:[
        routePlugin() // 应用自定义的 routePlugin 插件
    ]         /* Custom plugin to extend the functionality of Hvigor. */
}

4.执行自定义的插件

当我们在执行 hvigor 命令时,插件中的 apply 方法就会被调用。

HarmonyOS编译构建工具: Havigor(下)

完整的插件代码如下:

import { appTasks } from '@ohos/hvigor-ohos-plugin';
import { HvigorPlugin, HvigorNode } from '@ohos/hvigor';
export default {
    system: appTasks,  /* Built-in plugin of Hvigor. It cannot be modified. */
    plugins:[
        routePlugin() // 应用自定义的 routePlugin 插件
    ]         /* Custom plugin to extend the functionality of Hvigor. */
}
/**
 * 自定义插件 routePlugin
 * @returns
 */
function routePlugin(): HvigorPlugin {
    return {
        pluginId: 'routePlugin',
        apply(node: HvigorNode) {
            // 插件主体
            console.log('hello routePlugin!');
        }
    }
}

上述这段代码是在项目根目录下的 hvigorfile.ts文件中实现的。同样的,我们也可以在 module 中的hvigorfile.ts文件里来实现插件。

基于 TypeScript 项目开发

此方式开发插件能很好的解决上一种方式导出的插件代码不能复用、无法共享分发的问题。因此这也是首推的插件开发方式。

基于 TS 项目来开发 hvigor 插件,要求 Node.js 版本在 16~18

基于 TS 项目来开发插件,主要包含以下四个步骤:

  1. 初始化 TypeScript 项目;

  2. 开发插件;

  3. 发布插件;

  4. 使用插件。

1.初始化 TypeScript 项目

1.1 创建一个空目录ROUTE-PLUGIN

mkdir ROUTE-PLUGIN //创建空目录ROUTE-PLUGIN
cd ROUTE-PLUGIN //进入空目录ROUTE-PLUGIN

1.2 安装 typescript 模块

# 全局安装TypeScript
npm install typescript -g

1.3 初始化 nmp 项目,生成package.json文件

# 初始化一个npm项目
npm init
================
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (route-plugin) com.anjuke.harmony.route.plugin
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /Users/Baron/Work/Develop/HarmonyOS/Projects/ROUTE-PLUGIN/package.json:
{
  "name": "com.anjuke.harmony.route.plugin",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
Is this OK? (yes) 

1.4 生成typescript配置文件 typescript.json

tsc --init
===============
Created a new tsconfig.json with:                                                                                       
                                                                                                                     TS 
  target: es2016
  module: commonjs
  strict: true
  esModuleInterop: true
  skipLibCheck: true
  forceConsistentCasingInFileNames: true
You can learn more at https://aka.ms/tsconfig

1.5 typescript项目初始化完成

HarmonyOS编译构建工具: Havigor(下)

2.开发插件

2.1 添加依赖声明

打开package.json添加dependencies配置。

"dependencies": {
    "@ohos/hvigor": "4.0.4"
}

2.2 安装依赖

npm install

使用上述命令或者在页面提示中点击 npm install 来安装依赖

2.3 编写插件代码

创建route-plugin.ts文件,编写插件代码。

import { HvigorPlugin, HvigorNode } from '@ohos/hvigor';
/**
 * 自定义插件 routePlugin
 * @returns
 */
function routePlugin(): HvigorPlugin {
    return {
        pluginId: 'routePlugin',
        apply(node: HvigorNode) {
            // 插件主体
            console.log('hello routePlugin!');
        }
    }
}

2.4 导出插件

在根目录下创建index.ts文件,并在该文件中声明插件方法的导出。

export { customPlugin } from './src/plugin/route-plugin';

3.发布插件

typescript项目本质上是一种npm项目,插件发布流程与npm发布流程一致。

发布npm包流程:

3.1 生成AccessToken

执行如下命令,注册并登录npm仓库,在用户目录下.npmrc文件中自动生成token信息。

npm login

3.2 发布npm包

执行如下命令,将npm项目打包并发布至镜像仓库。

npm publish

4.使用插件

4.1 添加依赖

在工程下的hvigor/hvigor-config.json5文件中添加自定义的插件依赖(也可以将插件包放在本地,通过相对路径的方式添加依赖)。

 "dependencies": {
    "@ohos/hvigor-ohos-plugin": "4.0.4",
    "route-plugin": "1.0.0"   // 添加自定义插件依赖
  }

4.2 安装依赖

  • 方式1:执行编辑区右上角Install Now或执行菜单File -> Sync and Refresh Project进行工程 Sync 后,IDE将会根据hvigor-config.json5中的依赖配置自动安装。

  • 方式2:使用hvigorw命令行工具执行任一命令,命令行工具会自动执行安装构建依赖。

    ./hvigorw --sync
    

4.3 导入插件

根据插件编写时基于的node节点,确定导入的节点所在的hvigorfile.ts文件,在hvigorfile.ts中导入插件。

import { routePlugin } from 'route-plugin';

4.4 使用插件

将自定义插件添加到export default的plugins中。

export default {
    system: appTasks,  /* Built-in plugin of Hvigor. It cannot be modified. */
    plugins:[
        routePlugin() // 应用自定义的 routePlugin 插件
    ]         /* Custom plugin to extend the functionality of Hvigor. */
}

好了,编译构建工具 hvigor 的介绍就到这里了。