HarmonyOS 7 / API 26 包体积治理实战:资源重复、无用文件和构建产物对比一次验清

包体积问题通常不是某一次提交突然造成的,而是每次迭代都多一点资源、多一点依赖、多一点无用文件,最后安装包变得越来越重。上架前才发现包太大,再回头清理就很被动。
这篇按 HarmonyOS 7 / API 26 工程来拆包体积治理。重点不是“删文件”三个字,而是建立一套可复现的检查:哪些资源重复,哪些文件没有被引用,依赖带来了什么产物,构建前后体积变化是否超过阈值。
先把体积分成几类
| 类型 | 常见来源 | 处理方式 |
| 图片资源 | 多套重复截图、未压缩大图 | 压缩、按尺寸拆分、删除未引用 |
| 配置文件 | 老活动配置、测试 JSON | 按环境隔离,不进 release |
| 三方依赖 | 只用一个函数却引入整包 | 替换、拆 adapter、评估必要性 |
| 本地调试文件 | mock、日志、临时导出 | 构建前拦截 |
| 重复代码产物 | 多模块重复打包 | 检查依赖边界 |
先分类,后面治理才不会变成到处乱删。
建一个构建产物快照
我会在每次 release 构建后记录一个体积快照。
~~~ts
type BundleFile = {
path: string
size: number
type: 'image' | 'config' | 'dependency' | 'code' | 'other'
}
type BundleSnapshot = {
buildNo: string
totalSize: number
files: BundleFile[]
}
function summarizeBundle(snapshot: BundleSnapshot): Record<string, number> {
return snapshot.files.reduce((sum, file) => {
sum[file.type] = (sum[file.type] || 0) + file.size
return sum
}, {} as Record<string, number>)
}
~~~
这个快照不一定要一开始就很复杂。先能统计总大小和分类大小,就能发现哪一类在涨。
案例一:图片重复导致体积慢慢涨
图片重复很常见。比如同一张示意图在不同目录放了两份,或者列表缩略图和详情图没有区分。
~~~ts
type ResourceHash = {
path: string
hash: string
size: number
}
function findDuplicatedResources(resources: ResourceHash[]): ResourceHash[][] {
const groups = new Map<string, ResourceHash[]>()
for (const item of resources) {
const list = groups.get(item.hash) || []
list.push(item)
groups.set(item.hash, list)
}
return Array.from(groups.values()).filter(list => list.length > 1)
}
~~~
输出重复文件后,不要马上删。先确认引用关系,再决定保留哪一份。
~~~ts
type ResourceUsage = {
path: string
referencedBy: string[]
}
function canRemoveResource(usage: ResourceUsage): boolean {
return usage.referencedBy.length === 0
}
~~~
这一步能避免误删。资源治理不是越狠越好,核心是删得有证据。
案例二:调试文件混进 release
第二类问题是 mock、测试 JSON、临时日志混进 release 包。
~~~ts
const forbiddenReleasePatterns = [
'/mock/',
'/debug/',
'sample-data',
'temp-export',
'.log'
]
function findForbiddenReleaseFiles(files: BundleFile[]): BundleFile[] {
return files.filter(file => {
return forbiddenReleasePatterns.some(pattern => file.path.includes(pattern))
})
}
~~~
这类检查适合放在 CI。只要 release 产物里出现这些路径,就直接失败。
~~~ts
function assertNoForbiddenFiles(files: BundleFile[]): void {
const forbidden = findForbiddenReleaseFiles(files)
if (forbidden.length === 0) {
console.info('[bundle-check] no forbidden files')
return
}
for (const file of forbidden) {
console.error('[bundle-check] forbidden file', file.path, file.size)
}
throw new Error('release bundle contains forbidden files')
}
~~~
对比构建前后变化
只看当前体积不够,要看和上一次相比涨了多少。
~~~ts
function diffSnapshot(before: BundleSnapshot, after: BundleSnapshot): { type: string, delta: number }[] {
const a = summarizeBundle(before)
const b = summarizeBundle(after)
const types = new Set([...Object.keys(a), ...Object.keys(b)])
return Array.from(types).map(type => ({
type,
delta: (b[type] || 0) - (a[type] || 0)
}))
}
function assertBundleDelta(before: BundleSnapshot, after: BundleSnapshot, limit: number): void {
const delta = after.totalSize - before.totalSize
if (delta > limit) {
throw new Error('bundle size increased too much: ' + delta)
}
}
~~~
阈值要根据项目定。比如普通迭代超过 500KB 就提示,超过 1MB 就阻断。大功能可以单独申请阈值,但要写明原因。
本地验证脚本
先造两份快照,看检查是否能跑通。
~~~ts
function verifyBundleCheck(): void {
const before: BundleSnapshot = {
buildNo: 'api26-001',
totalSize: 10_000_000,
files: [
{ path: '/resources/a.png', size: 300_000, type: 'image' },
{ path: '/src/main.abc', size: 2_000_000, type: 'code' }
]
}
const after: BundleSnapshot = {
buildNo: 'api26-002',
totalSize: 11_300_000,
files: [
{ path: '/resources/a.png', size: 300_000, type: 'image' },
{ path: '/resources/mock/sample-data.json', size: 800_000, type: 'config' },
{ path: '/src/main.abc', size: 2_100_000, type: 'code' }
]
}
console.info('[bundle-diff]', JSON.stringify(diffSnapshot(before, after)))
assertNoForbiddenFiles(after.files)
assertBundleDelta(before, after, 1_000_000)
}
~~~
预期结果是 sample-data.json 被拦住,总体积增长也会触发阈值。这样就能在 CI 阶段发现问题,而不是上架前靠人工翻目录。
包体积治理的取舍
| 做法 | 好处 | 风险 |
| 手动删大文件 | 快 | 容易漏,容易误删 |
| 每次构建生成快照 | 可追踪 | 需要维护脚本 |
| CI 设置阈值 | 能阻断体积失控 | 大功能需要例外机制 |
| 资源 hash 去重 | 能发现重复文件 | 需要配合引用检查 |
我的选择是:快照加阈值作为基本盘,重复资源和禁用路径作为专项检查。这样成本不高,但能挡住大部分体积失控。
上架前检查清单
| 检查项 | 通过标准 |
| release 产物 | 没有 mock、debug、临时日志文件 |
| 图片资源 | 没有明显重复 hash |
| 体积变化 | 相比上一版本涨幅在阈值内 |
| 依赖变化 | 新依赖有用途说明 |
| 回归记录 | 产物快照随版本保存 |
小结
HarmonyOS 7 / API 26 包体积治理,要从构建产物出发,不要靠临时翻目录。先做快照,再查重复资源、禁用路径、依赖变化和体积阈值。这样安装包变大时,能知道是哪一类在涨,也能在 CI 阶段提前拦住。
更多推荐

所有评论(0)