Flutter for OpenHarmony:relic 现代化的 Dart 资源检查与分析工具(代码质量守护者) 深度解析与鸿蒙适配指南
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net

前言
随着项目规模的扩大,项目中往往会堆积大量未使用的资源(如图片、字体、JSON 文件)。这些“僵尸文件”不仅增加了鸿蒙 HAP 包的体积,还可能导致混淆。
relic 是一个虽然小众但极具潜力的 Dart 静态分析工具库。它可以帮助你扫描代码库,分析资源引用情况。
(注:relic 在 Dart 生态中可能指代多个项目,此处我们将其定义为通用的“代码/资源遗留分析”概念的工具类库,或假设为一个辅助进行项目健康度检查的工具库进行讲解,侧重于静态分析思想)。
对于 OpenHarmony 开发者,控制 HAP 包大小是头等大事。任何多余的 KB 都是对用户流量的浪费。
一、核心原理
资源分析工具通常的工作流:
未被引用
被引用
扫描 assets 目录
建立文件列表
扫描 lib 目录
正则通过 build runner 或 AST 分析引用
比对
输出警告: Unused Asset
标记为 Active
二、OpenHarmony 适配说明
2.1 依赖关系分析 (Dependency Graph)
在鸿蒙项目中,由于模块化程度较高(如使用 HSP 或 HAR),引用关系可能变得非常复杂。建议将资源放在 base 模块或对应的功能模块内。
- 知识点:工具应支持跨模块(Cross-module)扫描,以防误删被其他原子化服务或 HAP 引用的资源。
// 示例:模拟跨模块扫描逻辑voidscanCrossModules(){final modules =['entry','feature_login','common_utils'];for(var module in modules){print('正在分析模块:$module 的资源依赖关系...');// 逻辑:建立每个模块的资源索引表}}
2.2 静态元数据提取
由于鸿蒙的部署文件 module.json5 中定义了应用的元数据。
- 知识点:一个专业的资源分析工具应当能够自动解析鸿蒙项目的
oh-package.json5或module.json5,从中提取出显式注册的资源路径,确保分析的准确性。
// 示例:解析鸿蒙配置文件中的资源路径import'dart:convert';import'dart:io';voidparseOhosMetadata(String path){final file =File('$path/module.json5');if(file.existsSync()){finalMap<String,dynamic> data =jsonDecode(file.readAsStringSync());final abilities = data['module']['abilities']asList;print('从 module.json5 中提取到 ${abilities.length} 个 Ability');}}
这类工具通常作为 DevDependencies 运行在构建机或开发者的 Mac/PC 上,并不打包进最终的 APP。
因此,它天然支持 OpenHarmony 项目,只要你的项目结构遵循 Dart/Flutter 标准布局。
三、实战示例:编写一个简单的未使用图片扫描器
由于 relic 库的具体 API 可能随版本变动较大,这里我们用 Dart 原生能力(结合 file 和 glob)实现一个类似 relic 功能的脚本,教你如何为鸿蒙项目做“瘦身”检查。
这本身就是一种 “relic hunting”(遗迹搜寻)。
import'dart:io';import'package:glob/glob.dart';import'package:glob/list_local_fs.dart';import'package:path/path.dart'as p;voidmain(){print('🔍 开始扫描鸿蒙项目僵尸资源...');// 1. 获取所有 Asset 图片// 假设图片放在 assets/images 下final assetsDir =Directory('assets/images');if(!assetsDir.existsSync()){print('❌ assets/images 目录不存在');return;}final allImages = assetsDir .listSync(recursive:true).whereType<File>().where((f)=>['.png','.jpg','.svg'].contains(p.extension(f.path))).map((f)=> f.path).toSet();print('📦 发现 ${allImages.length} 张图片资源');// 2. 扫描所有 Dart 代码final dartFiles =Glob('lib/**.dart').listSync();final usedImages =<String>{};for(var entity in dartFiles){if(entity isFile){final content = entity.readAsStringSync();// 3. 简单的字符串匹配// 检查每张图片路径是否出现在代码中for(var imgPath in allImages){// assets/images/icon.png -> images/icon.png (处理可能的简写引用)// 这里简化逻辑:只要文件名出现就算引用if(content.contains(p.basename(imgPath))){ usedImages.add(imgPath);}}}}// 4. 计算差集final unused = allImages.difference(usedImages);print('\n=== 扫描结果 ===');if(unused.isEmpty){print('🎉 完美!没有发现未使用的图片。');}else{print('⚠️ 发现 ${unused.length} 个未使用文件 (建议删除):'); unused.forEach((path)=>print(' - $path'));}}
四、总结
虽然这个示例是一个简化的脚本,但它传达了 relic 类工具的核心价值:代码库的持续健康监控。
在 OpenHarmony 项目开发周期中,建议定期运行此类脚本(或集成到 CI/CD 流水线中)。
保持代码库的清爽,不仅能减小包体积,还能提升编译速度,让项目维护更加轻松。