HarmonyOS开发:自动化构建

举报
Jack20 发表于 2026/06/24 16:50:10 2026/06/24
【摘要】 HarmonyOS开发:自动化构建📌 核心要点:hvigorw是鸿蒙的构建引擎——搞懂它的命令体系、缓存机制和产物管理,构建速度能从5分钟压到1分钟以内。 背景与动机你有没有数过,从点击"运行"到应用安装到设备上,要等多久?一个小项目可能30秒就搞定了。但项目一大,模块一多,3分钟、5分钟甚至10分钟都有可能。一天构建20次,光等构建就花了一个多小时。更别提CI环境里,构建慢意味着流水线...

HarmonyOS开发:自动化构建

📌 核心要点:hvigorw是鸿蒙的构建引擎——搞懂它的命令体系、缓存机制和产物管理,构建速度能从5分钟压到1分钟以内。

背景与动机

你有没有数过,从点击"运行"到应用安装到设备上,要等多久?

一个小项目可能30秒就搞定了。但项目一大,模块一多,3分钟、5分钟甚至10分钟都有可能。一天构建20次,光等构建就花了一个多小时。更别提CI环境里,构建慢意味着流水线排队,团队效率直接拉胯。

构建慢的常见原因:

  • 依赖重复下载:每次构建都重新拉ohpm包
  • 全量编译:改了一个文件,整个项目重新编译
  • 产物混乱:不知道哪些产物有用、哪些可以清理
  • 配置低效:多模块项目没有优化构建顺序

这些问题不是DevEco Studio的锅,而是你没搞懂底层构建工具hvigorw的脾气。它就像一个厨师——你给它正确的食材和步骤,它出菜很快;你瞎指挥,它就只能慢工出细活。

核心原理

hvigorw是HarmonyOS的构建命令行工具,底层基于Node.js,用TypeScript编写构建脚本。它和Android的Gradle定位类似,但架构完全不同。

flowchart TB
    A[hvigorw命令] --> B{解析参数}
    B --> C[加载hvigor-config.json5]
    C --> D[初始化构建图]
    D --> E[解析模块依赖]
    E --> F[执行Task]
    
    F --> G[预处理]
    G --> H[编译ArkTS]
    H --> I[打包资源]
    I --> J[生成HAP/APP]
    
    J --> K{产物类型}
    K -->|HAP| L[单模块安装包]
    K -->|APP| M[上架发布包]
    K -->|HAR| N[共享库包]
    
    classDef cmd fill:#E17055,stroke:#D63031,color:#fff
    classDef process fill:#00CEC9,stroke:#00B894,color:#fff
    classDef product fill:#6C5CE7,stroke:#5B4BC9,color:#fff
    classDef decision fill:#FFEAA7,stroke:#FDCB6E,color:#333
    
    class A cmd
    class B,C,D,E,F,G,H,I process
    class J,K decision
    class L,M,N product

hvigorw的核心概念:

概念 说明 类比
Task 最小构建单元 Gradle的Task
Module 构建模块 Android的Module
Product 构建产物配置 Gradle的Product Flavor
Mode 构建模式(module/rebuild) Gradle的Build Type
Plugin 构建插件 Gradle Plugin

构建命令的基本格式:

hvigorw [task] --mode [mode] -p module=[module] -p product=[product]

代码实战

基础用法:hvigorw构建命令

先掌握最常用的构建命令,这是自动化的基础。

# ===== 最基础的构建命令 =====

# 构建HAP(单模块安装包,用于调试和安装)
./hvigorw assembleHap

# 构建APP(上架发布包,包含所有模块)
./hvigorw assembleApp

# 构建HAR(共享库,供其他模块引用)
./hvigorw assembleHar

# ===== 指定模块和产品 =====

# 构建指定模块的HAP
./hvigorw assembleHap --mode module -p module=entry@default -p product=default

# 构建指定模块的APP
./hvigorw assembleApp --mode module -p module=entry@default -p product=default

# ===== 清理命令 =====

# 清理构建产物
./hvigorw clean

# 彻底清理(包括缓存)
./hvigorw clean --no-daemon

# ===== 其他常用命令 =====

# 查看所有可用Task
./hvigorw --list

# 查看构建帮助
./hvigorw --help

# 查看版本信息
./hvigorw --version

# 干跑模式(不实际执行,只显示会做什么)
./hvigorw assembleHap --dry-run

这里有个重要细节:--mode module和默认模式的区别

  • 默认模式:构建所有模块,适合全量构建
  • --mode module:只构建指定模块,适合增量构建和CI环境

CI环境里一定要用--mode module,不然10个模块全量构建,时间直接翻倍。

进阶用法:多模块构建配置

真实项目通常是多模块的:entry主模块 + feature功能模块 + shared共享库。构建顺序和配置直接影响效率。

// build-profile.json5 - 多模块构建配置
{
  "app": {
    "signingConfigs": [],
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "5.0.0(12)",
        "runtimeSdkVersion": "5.0.0(12)",
        "buildOption": {
          // 构建优化配置
          "strictMode": {
            "useNormalizedOhmUrl": true  // 严格模式,依赖URL规范化
          },
          // ArkTS编译优化
          "arkOptions": {
            "compilerOptions": {
              "sourceMap": false  // 生产构建关闭sourceMap,加快编译
            }
          }
        }
      },
      {
        // 开发调试配置
        "name": "debug",
        "signingConfig": "debug",
        "buildOption": {
          "arkOptions": {
            "compilerOptions": {
              "sourceMap": true  // 调试构建开启sourceMap
            }
          }
        }
      }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        { "name": "default", "applyToProducts": ["default", "debug"] }
      ]
    },
    {
      "name": "feature_home",
      "srcPath": "./features/home",
      "targets": [
        { "name": "default", "applyToProducts": ["default", "debug"] }
      ]
    },
    {
      "name": "shared_utils",
      "srcPath": "./shared/utils",
      "targets": [
        { "name": "default", "applyToProducts": ["default", "debug"] }
      ]
    }
  ]
}

多模块项目的构建脚本,关键是控制构建顺序:

#!/bin/bash
# multi_module_build.sh - 多模块构建脚本

set -e

echo "===== 开始多模块构建 ====="
START_TIME=$(date +%s)

# 第一步:构建共享库(其他模块依赖它)
echo "📦 构建共享库模块..."
./hvigorw assembleHar --mode module -p module=shared_utils@default -p product=default --no-daemon

# 第二步:并行构建功能模块(它们之间互不依赖)
echo "📦 构建功能模块..."
./hvigorw assembleHap --mode module -p module=feature_home@default -p product=default --no-daemon

# 第三步:构建入口模块并打包APP
echo "📦 构建入口模块..."
./hvigorw assembleApp --mode module -p module=entry@default -p product=default --no-daemon

END_TIME=$(date +%s)
ELAPSED=$((END_TIME - START_TIME))
echo "✅ 构建完成,耗时: ${ELAPPED}秒"

完整示例:构建缓存优化与产物管理

构建缓存是提速的关键。hvigorw支持增量构建,但需要正确配置。

// hvigorfile.ts - 构建缓存优化配置
import { hapTasks, appTasks, harTasks, OhosHarContext, OhosHapContext, OhosAppContext } from '@ohos/hvigor-ohos-plugin';

// 缓存配置
const CACHE_CONFIG = {
  // 启用构建缓存
  enableCache: true,
  // 缓存目录(CI环境建议用共享目录)
  cacheDir: process.env.CI ? '/cache/hvigor-cache' : '.hvigor/cache',
  // 缓存最大大小(MB)
  maxCacheSize: 2048,
};

// 构建产物管理
export default {
  system: appTasks,
  plugins: [{
    // 自定义构建插件:产物清理和归档
    apply() {
      this.registerTask({
        name: 'archiveProduct',
        run: () => {
          console.log('📦 归档构建产物...');
          const fs = require('fs');
          const path = require('path');
          
          // 产物目录
          const outputDir = 'entry/build/default/outputs/default';
          const archiveDir = `archive/${Date.now()}`;
          
          if (fs.existsSync(outputDir)) {
            fs.mkdirSync(archiveDir, { recursive: true });
            
            // 复制HAP文件
            const files = fs.readdirSync(outputDir);
            files.forEach(file => {
              if (file.endsWith('.hap') || file.endsWith('.app')) {
                fs.copyFileSync(
                  path.join(outputDir, file),
                  path.join(archiveDir, file)
                );
                console.log(`  ✅ 归档: ${file}`);
              }
            });
            
            // 写入构建信息
            const buildInfo = {
              timestamp: new Date().toISOString(),
              gitHash: require('child_process').execSync('git rev-parse HEAD').toString().trim(),
              nodeVersion: process.version,
            };
            fs.writeFileSync(
              path.join(archiveDir, 'build-info.json'),
              JSON.stringify(buildInfo, null, 2)
            );
          }
        }
      });
    }
  }],
  buildConfig: {
    // 增量构建配置
    incrementalBuild: true,
    // 并行编译
    parallelCompile: true,
    // ArkTS编译优化
    arkOptions: {
      compilerOptions: {
        // 生产环境关闭sourceMap
        sourceMap: process.env.BUILD_TYPE !== 'release',
        // 开启编译缓存
        incremental: true,
      }
    }
  }
};

构建产物管理的最佳实践——定期清理、按需归档:

#!/bin/bash
# manage_build_artifacts.sh - 构建产物管理脚本

# ===== 1. 清理过期产物 =====
echo "🧹 清理过期构建产物..."

# 删除7天前的归档
find archive/ -type d -mtime +7 -exec rm -rf {} + 2>/dev/null || true

# 删除构建临时文件
find entry/build/ -name "*.tsbuildinfo" -delete 2>/dev/null || true

# ===== 2. 产物大小分析 =====
echo "📊 构建产物大小分析..."

HAP_FILE="entry/build/default/outputs/default/entry-default-signed.hap"
if [ -f "$HAP_FILE" ]; then
    HAP_SIZE=$(stat -f%z "$HAP_FILE" 2>/dev/null || stat -c%s "$HAP_FILE" 2>/dev/null)
    HAP_SIZE_MB=$((HAP_SIZE / 1024 / 1024))
    echo "  HAP大小: ${HAP_SIZE_MB}MB"
    
    # 大小阈值检查(超过50MB告警)
    if [ $HAP_SIZE_MB -gt 50 ]; then
        echo "  ⚠️ HAP包超过50MB,请检查资源文件!"
    fi
fi

# ===== 3. 产物内容检查 =====
echo "🔍 产物内容检查..."

# 解压HAP检查内容(HAP本质是ZIP格式)
if command -v unzip &> /dev/null; then
    TEMP_DIR=$(mktemp -d)
    unzip -q "$HAP_FILE" -d "$TEMP_DIR" 2>/dev/null || true
    
    # 检查是否有debug符号
    if grep -r "console.log\|console.debug\|console.info" "$TEMP_DIR" --include="*.js" -q 2>/dev/null; then
        echo "  ⚠️ 发现debug日志,生产构建应移除"
    fi
    
    # 检查资源文件大小
    LARGE_FILES=$(find "$TEMP_DIR" -type f -size +1M 2>/dev/null)
    if [ -n "$LARGE_FILES" ]; then
        echo "  ⚠️ 发现大文件(>1MB):"
        echo "$LARGE_FILES"
    fi
    
    # 清理临时目录
    rm -rf "$TEMP_DIR"
fi

echo "✅ 产物管理完成"

踩坑与注意事项

坑1:增量构建不生效

改了一行代码,结果全量重新编译了?增量构建没生效通常是因为缓存被破坏。

解决方案

# 检查缓存状态
ls -la .hvigor/cache/

# 如果缓存损坏,清理后重新构建
./hvigorw clean
./hvigorw assembleHap

# CI环境确保缓存目录持久化
# GitLab CI
cache:
  paths:
    - .hvigor/cache/

坑2:多模块循环依赖

A模块依赖B模块,B模块又依赖A模块,构建直接死循环。

解决方案:严格按层级划分模块——shared库在最底层,feature模块在中间,entry在最上层。禁止上层模块被下层依赖。

// 模块依赖层级
// Layer 0: shared_utils(纯工具库,不依赖任何模块)
// Layer 1: shared_network(网络库,只依赖shared_utils)
// Layer 2: feature_home(功能模块,依赖shared_utils和shared_network)
// Layer 3: entry(入口模块,依赖所有模块)

坑3:构建产物找不到

构建成功了,但HAP文件不知道去哪了。

解决方案:记住鸿蒙构建产物的标准路径。

项目根目录/
├── entry/
│   └── build/
│       └── default/
│           └── outputs/
│               └── default/
│                   ├── entry-default-signed.hap     # 签名后的HAP
│                   ├── entry-default-unsigned.hap   # 未签名的HAP
│                   └── entry-default.app            # APP包
├── shared_utils/
│   └── build/
│       └── default/
│           └── outputs/
│               └── default/
│                   └── shared_utils-default.har     # HAR

坑4:hvigorw版本不一致

本地DevEco Studio用的hvigorw 4.x,CI环境装的是3.x,构建配置不兼容。

解决方案:在项目中锁定hvigorw版本,CI环境使用项目自带的hvigorw。

// hvigor-config.json5
{
  "modelVersion": "4.0.2",  // 锁定版本
  "dependencies": {
    "@ohos/hvigor-ohos-plugin": "4.0.2"  // 锁定插件版本
  }
}
# CI环境使用项目自带的hvigorw,不依赖全局安装
chmod +x ./hvigorw
./hvigorw assembleHap --no-daemon

坑5:构建内存溢出

大项目构建时Node.js进程OOM(Out of Memory),构建直接崩。

解决方案:增加Node.js内存限制。

# 临时增加内存限制
export NODE_OPTIONS="--max-old-space-size=8192"
./hvigorw assembleHap --no-daemon

# 或者在hvigorw脚本中直接修改
# 打开 hvigorw.bat(Windows)或 hvigorw(macOS/Linux)
# 找到 node 命令行,添加 --max-old-space-size=8192

HarmonyOS 6适配说明

HarmonyOS 6对构建系统做了几项重要升级:

  1. hvigorw 5.x:新版本构建速度提升约30%,支持更细粒度的增量编译。升级方法:更新hvigor-config.json5中的modelVersion

  2. ArkCompiler优化:HarmonyOS 6的Ark编译器支持AOT(Ahead-of-Time)编译,构建时可以选择开启AOT以提升运行时性能,但构建时间会增加。

  3. 多产物配置增强:一个模块可以配置多个Product,支持同时构建手机版和平板版。

  4. 构建缓存共享:HarmonyOS 6的hvigorw支持分布式缓存,CI集群中的构建节点可以共享缓存,大幅减少重复编译。

  5. 产物格式优化:新的HAP格式支持更好的压缩率,构建产物体积平均减少10-15%。

总结

构建自动化是CI/CD的基础——构建本身都跑不快、跑不稳,后面的流水线再漂亮也是空中楼阁。

维度 评价
学习难度 ⭐⭐⭐ hvigorw命令不算复杂,但多模块配置和缓存优化需要经验
使用频率 ⭐⭐⭐⭐⭐ 每次构建都会用到,是开发效率的直接决定因素
重要程度 ⭐⭐⭐⭐⭐ 构建速度影响整个团队的产出效率

几个关键提醒:

  • --mode module是CI标配,别用默认模式全量构建
  • 缓存配置好,构建快一倍,CI环境记得持久化缓存目录
  • 模块依赖要分层,循环依赖是万恶之源
  • 产物管理别忽视,定期清理、大小检查、内容审计
  • 版本要锁定,本地和CI环境的hvigorw版本必须一致

构建搞定了,下一步是让测试也自动化——每次构建完自动跑测试,有问题立刻知道。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。