HarmonyOS鸿蒙Next中构建har包时如何剔除resources目录下面的资源文件

HarmonyOS鸿蒙Next中构建har包时如何剔除resources目录下面的资源文件 资源图片和主题色存放在AHar模块的resources目录下面, 构建AHar包时, 如何剔除此har包resources目录下面资源文件, 尝试过在此har模块的build-profile.json5文件中剔除了资源文件夹, 但是在把AHar打包之后, 引用到工程中, 界面的字体颜色和图片都看不到了

8 回复

在鸿蒙(HarmonyOS)构建 HAR 包时,若需剔除resources目录下的资源文件(如图片、主题色等),需兼顾构建配置剔除资源引用工程补充资源两个环节。直接剔除资源后界面异常(字体颜色、图片丢失)的核心原因是:HAR 包内的代码仍依赖这些资源的 ID,但资源被物理移除后,引用工程未提供对应的替代资源。以下是具体解决方案:

一、正确剔除 HAR 包中的资源文件

鸿蒙的 HAR 打包流程会默认将resources目录下的资源(elementmediaprofile等)编译并打包到 HAR 中。若需剔除,需通过Hvigor 构建脚本在打包前主动删除资源文件(而非仅在build-profile.json5中声明排除,后者可能不生效)。

步骤 1:在 HAR 模块中添加自定义 Hvigor 任务

在 HAR 模块的hvigorfile.js中,新增剔除资源的任务,在assembleHar任务执行前删除resources目录下的目标文件:

// AHar模块/hvigorfile.js
const { appTasks } = require('@ohos/hvigor-ohos-plugin');
const fs = require('fs');
const path = require('path');

// 定义需要剔除的资源目录(按需调整,如全部剔除则写'resources')
const RESOURCES_TO_REMOVE = [
  'src/main/resources/media', // 剔除图片资源
  'src/main/resources/element' // 剔除主题色(color、string等)
];

// 剔除资源的任务
task('removeResources', () => {
  const moduleRoot = __dirname; // 当前HAR模块根目录
  RESOURCES_TO_REMOVE.forEach(resourcePath => {
    const fullPath = path.join(moduleRoot, resourcePath);
    if (fs.existsSync(fullPath)) {
      // 递归删除目录(谨慎操作,确保路径正确)
      const deleteDir = (dir) => {
        if (fs.existsSync(dir)) {
          fs.readdirSync(dir).forEach(file => {
            const curPath = path.join(dir, file);
            if (fs.statSync(curPath).isDirectory()) {
              deleteDir(curPath); // 递归删除子目录
            } else {
              fs.unlinkSync(curPath); // 删除文件
            }
          });
          fs.rmdirSync(dir); // 删除空目录
        }
      };
      deleteDir(fullPath);
      console.log(`已剔除资源:${fullPath}`);
    }
  });
});

// 重构assembleHar任务:先剔除资源,再打包
const originalAssembleHar = appTasks.assembleHar;
appTasks.assembleHar = task('assembleHar', async () => {
  await executeTask('removeResources'); // 执行资源剔除
  await originalAssembleHar.execute(); // 执行原打包任务
  console.log('HAR打包完成(已剔除指定资源)');
});

// 导出任务
exports.default = {
  ...appTasks,
  removeResources
};

步骤 2:验证 HAR 包是否已剔除资源

执行打包命令后,解压生成的 HAR 包(位于AHar/build/outputs/har/AHar.har),检查是否存在resources目录下的目标资源:

# 打包命令
hvigor run --module AHar assembleHar

# 解压验证(以zip命令为例)
unzip AHar.har -d AHar_unzip
# 检查AHar_unzip/resources目录下是否已无被剔除的资源

二、解决 “引用工程中资源丢失” 的问题

剔除 HAR 中的资源后,引用该 HAR 的工程(如主工程)必须提供与 HAR 中依赖的资源 ID 完全一致的资源,否则会出现 “字体颜色丢失、图片不显示” 的问题(因 HAR 内的代码仍通过资源 ID 引用,如$r('app.color.theme_color'))。

步骤 1:梳理 HAR 中依赖的资源 ID

需明确 HAR 模块的代码中引用了哪些资源(避免遗漏),例如:

  • 图片资源:$r('app.media.logo')(对应media/logo.png
  • 主题色:$r('app.color.theme_primary')(对应element/color.json中的theme_primary

可通过搜索 HAR 模块的代码,收集所有$r(...)形式的资源引用,整理成资源 ID 清单。

步骤 2:在引用工程中补充资源

在引用 HAR 的主工程(或其他模块)的resources目录下,创建与 HAR 中依赖的资源 ID 完全一致的资源:

主工程/
└── src/main/resources/
    ├── media/
    │   └── logo.png  # 与HAR中引用的app.media.logo对应
    └── element/
        └── color.json  # 包含theme_primary等主题色定义

示例color.json

{
  "color": [
    {
      "name": "theme_primary",
      "value": "#FF007DFF" // 主工程定义的主题色(需与HAR预期一致)
    }
  ]
}

步骤 3:确保资源引用优先级正确

鸿蒙的资源引用遵循 “就近原则”:当主工程与 HAR 包含相同 ID 的资源时,主工程的资源会覆盖 HAR 中的资源。因此,即使 HAR 未剔除资源,主工程也可通过同名 ID 覆盖;若 HAR 已剔除资源,主工程的资源会被 HAR 中的代码直接引用。

三、注意事项

  1. 不可剔除未被主工程覆盖的资源:若 HAR 中存在某些资源,主工程未提供对应的 ID,剔除后会导致运行时错误(Resource not found)。需确保所有被 HAR 引用的资源 ID 在主工程中都有定义。
  2. 避免剔除profile等关键资源resources/profile目录下的配置文件(如页面路由、权限配置)可能被 HAR 内部逻辑依赖,剔除前需确认无引用。
  3. Hvigor 脚本路径准确性RESOURCES_TO_REMOVE中的路径需与实际项目结构一致(如src/main/resources还是main/resources,取决于模块类型)。
  4. 版本控制:若多人协作,需同步 HAR 的资源 ID 清单给主工程开发者,确保资源 ID 一致。

总结

剔除 HAR 中的资源需通过Hvigor 脚本主动删除,但核心是引用工程必须补充对应的资源 ID。这一方案适用于 “资源由主工程统一管理,HAR 仅提供业务逻辑” 的场景(如 SDK 分发)。若仅是为了减小 HAR 体积,更推荐通过资源压缩仅剔除冗余资源(而非全部),避免因资源缺失导致界面异常。

更多关于HarmonyOS鸿蒙Next中构建har包时如何剔除resources目录下面的资源文件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


你好,不应该删除har包中的resources资源文件。

在编译构建HAP时,DevEco Studio会从hap模块及依赖的har模块中收集资源文件,集中放到hap的resources文件中。所以har可通过 Text($r(‘app.string.string_in_har2’)) 访问资源。如果删除,资源访问就会异常。

如果不同模块下的资源文件出现重名冲突时,DevEco Studio会按照以下优先级进行覆盖(优先级由高到低):

AppScope里面的资源。
HAP包自身模块。
依赖的HAR模块,如果依赖的多个HAR之间有资源冲突,会按照工程oh-package.json5中dependencies下的依赖顺序进行覆盖,依赖顺序在前的优先级较高。

很简单的,只需要修改har文件的后缀名为zip格式。然后解压缩。然后删掉你不要的resource资源。然后重新打包就行了。

伙伴您好, 操作到最后一步删掉不要的resource资源的时候, 此时是一个文件夹, 请问如何再次打包成har,

用命令行再打成har包,tar -cvzf ./xxx.har package,

伙伴您好, 使用这个指令打成har包, 把此har引用到工程中后, 也是界面的字体颜色和图片都看不到了,

在HarmonyOS鸿蒙Next中构建har包时,若需剔除resources目录下的特定资源文件,可在工程的build-profile.json5文件中配置excludeResources字段。具体操作为在对应模块的buildOptions内添加该字段,并指定需要排除的资源文件路径或模式。此配置会在编译打包阶段生效,使指定资源不被包含在最终的har包中。

在HarmonyOS Next中,构建HAR包时剔除resources目录下的资源文件,通常是为了减小包体积或避免资源冲突。你遇到的问题(剔除后界面字体颜色和图片丢失)是因为HAR包的资源在编译时会被主工程引用,直接剔除会导致依赖缺失。

正确的方法是通过资源限定符或条件编译来控制资源是否被打包,而不是直接删除resources目录。以下是具体方案:

1. 使用资源限定符(推荐)

  • resources目录下,通过文件夹命名限定符(如en_USdark等)区分资源。构建HAR时,默认只会打包无限定符或与目标匹配的资源。
  • 示例
    将需要剔除的资源放入特定限定符目录(如resources-raw),并在build-profile.json5中配置排除该目录:
    {
      "buildOption": {
        "resourceFilter": {
          "exclude": ["resources-raw/**"]
        }
      }
    }
    

2. 条件编译(通过编译变量控制)

  • build-profile.json5中定义编译变量,动态控制资源是否包含:
    {
      "buildOption": {
        "externalNativeOptions": {
          "variables": {
            "EXCLUDE_RESOURCES": true  // 自定义变量
          }
        }
      }
    }
    
  • 在模块的oh-package.json5中配置资源路径时,根据变量判断:
    {
      "resourceFilters": [
        {
          "name": "exclude_resources",
          "src": ["resources"],
          "target": "EXCLUDE_RESOURCES ? '' : 'resources'"
        }
      ]
    }
    

3. 分模块构建

  • 将需要剔除的资源独立为子模块,主HAR包通过dependencies依赖该模块,并在构建时选择是否包含此子模块。

注意事项:

  • 直接删除resources目录会导致主工程编译时找不到资源引用,从而出现界面异常。
  • 如果资源需动态替换,建议将资源保留在HAR中,通过资源ID引用,主工程可通过同名资源覆盖。

若以上方案仍无法解决,请检查主工程的resource配置是否与HAR包资源路径匹配。

回到顶部