15-拆包后资源跟着页面走-同步迁移页面资源和导出边界

📅 2026/7/10 5:12:46
15-拆包后资源跟着页面走-同步迁移页面资源和导出边界
第15篇拆包后资源跟着页面走同步迁移页面、资源、路由和导出边界摘要HSP 拆包不能只移动页面文件。页面进了 feature HSP专属图片、字符串、路由表、Builder 和对外导出也要一起迁移。否则构建时资源找不到、运行时入口白屏、宿主继续 import 内部页面拆包就只是换了目录。我遇到过一次功能拆包详情页文件已经进了 HSP但空态图还在 entry首页入口还写旧路径最后为了编过又把页面从 HSP 导回宿主。这个过程暴露的不是一个资源名错误而是页面 owner 没有迁干净。这篇文章会把问题拆成几个可落地的点拆出页面、资源、路由、服务和导出的 owner。给每个关键边界放具体代码或配置。用反向搜索确认旧路径和反向依赖退出。用构建和真实入口验证拆分后的运行链路。适用环境和边界本文默认讨论 Stage 模型下的模块化工程宿主负责应用入口feature HSP/HAR 承载业务能力common 层承载稳定公共能力。维度建议边界宿主层启动、窗口、全局导航、应用级资源feature 层业务页面、专属资源、业务路由common 层跨业务模型、工具和通用组件验证方式构建、首页入口、返回路径、旧路径搜索不展开内容不讨论动态下发只处理工程拆分拆模块前先确认 owner不然很容易把页面搬走资源、路由和导出还留在旧地方。先把故障链路复盘出来模块拆分失败的表现通常不止一个。资源报错、白屏、反向依赖和返回错乱经常一起出现。阶段表面现象更深的原因应该看到的结果编译资源或导入找不到页面和资源 owner 分离所属模块能独立解析资源运行入口白屏路由表或 Builder 未对齐按注册名进入目标页维护feature import entry公共能力没有下沉依赖方向保持单向返回页面栈乱跳跨模块导航没有统一入口宿主导航层收口这张表能提醒我们拆包不是一个文件移动动作而是一组边界迁移。页面、资源、路由和导出只迁一半后面一定会在构建或真机入口里暴露。先定 owner再写代码owner 表先于代码修改。每个对象必须知道自己归哪个模块后面才能判断旧路径该删还是该保留兼容。对象归属不要越界做的事业务页面feature HSP直接依赖 entry 页面专属资源渲染页面所在模块放进 common 充当杂物路由名feature 定义宿主引用多个入口散写路径公共模型common HAR跟着某个业务页面走宿主入口entryimport feature 内部页面如果一个文件删除某个 feature 时应该一起消失它大概率属于 feature如果多个业务稳定复用才考虑放到 common。先写迁移清单这一步要把拆分动作落到具体文件上避免只移动页面而漏掉资源、路由或导出。learning_feature owns: - src/main/ets/pages/LearningDetailPage.ets - src/main/resources/base/media/learning_empty.png - src/main/resources/base/element/string.json - src/main/resources/base/profile/router_map.json entry owns: - app startup - global Navigation container - visible home entry清单先把页面、资源、路由和宿主入口分开。迁移时按清单推进就不会只搬页面文件。页面专属资源跟着 HSP 走这一步要把拆分动作落到具体文件上避免只移动页面而漏掉资源、路由或导出。Componentstruct LearningEmptyState{build(){Column({space:10}){Image($r(app.media.learning_empty)).width(144).height(144)Text($r(app.string.learning_empty_title)).fontColor($r(app.color.text_secondary))}}}组件在 HSP 内渲染图片和字符串也应由 HSP 拥有。宿主不需要知道这张空态图叫什么。router_map 注册稳定入口这一步要把拆分动作落到具体文件上避免只移动页面而漏掉资源、路由或导出。{routerMap:[{name:LearningDetail,pageSourceFile:src/main/ets/pages/LearningDetailPage.ets,buildFunction:LearningDetailBuilder}]}跨模块入口使用稳定路由名不暴露页面文件路径。后续页面重命名只要路由名不变宿主入口不用改。module.json5 引用 profile这一步要把拆分动作落到具体文件上避免只移动页面而漏掉资源、路由或导出。{ module: { name: learning_feature, type: shared, routerMap: $profile:router_map } }路由表放在 profile 后还要在模块配置里声明。只写了router_map.json但没挂到模块上运行时仍可能找不到页面。Builder 和参数边界对齐这一步要把拆分动作落到具体文件上避免只移动页面而漏掉资源、路由或导出。interfaceLearningDetailParam{courseId:stringfrom:string}BuilderexportfunctionLearningDetailBuilder(name:string,param:Object){constpayloadparamasLearningDetailParamLearningDetailPage({courseId:payload.courseId,source:payload.from})}Builder 是跨模块参数入口。这里要把参数读清楚缺字段时页面应能展示错误态而不是在更深层才崩。HSP 对外导出收窄这一步要把拆分动作落到具体文件上避免只移动页面而漏掉资源、路由或导出。// learning_feature/src/main/ets/index.etsexport{LearningRoutes}from./navigation/LearningRoutesexport{installLearningRoutes}from./navigation/LearningInstaller宿主只需要路由名和安装入口不需要 import HSP 的内部页面、组件和服务。导出越少模块越稳。用反向搜索把旧路径清掉拆完要反向搜索旧路径和反向依赖。构建能过不代表旧入口已经干净。rgentry/src/main|pages/LearningDetailPage|learning_emptyentry features common rgfrom .*entry|bundle:entry|LearningDetailentry features common命中后逐个判断资源是否该迁、路由名是否统一、feature 是否反向依赖宿主。验证路径要覆盖真实操作模块拆分必须走真实入口。执行hvigorw assembleHap --no-daemon。从首页入口进入 feature 页面。检查空态图、字符串和主题资源是否正常。从目标页返回宿主首页确认页面栈正确。从搜索、通知或最近记录等边缘入口进入同一页面。清空应用数据后首次进入确认没有依赖旧缓存。这组验证不要只在一个入口上跑。很多问题在主流程里看不出来切换页面、返回、清空数据、改主题、断网、换宽屏后才会暴露。风险和回退方案风险触发场景处理方式只搬页面资源仍在 entry专属资源随页面迁移导出过多宿主 import 内部组件只导出路由和安装入口路由散写多个入口使用旧路径统一路由名common 膨胀业务资源被放公共层按生命周期判断 owner回退方案的价值不是保守而是让一次修复能分阶段落地。先保住主路径再删除旧逻辑排查时才不会把多个变量混在一起。常见问题和处理方式现象常见原因处理方式资源找不到资源没跟页面走迁入 feature resources入口白屏路由表和 Builder 不匹配对齐注册名和导出函数feature 依赖 entry公共能力放错层下沉到 common HAR返回错乱跨模块栈没有收口宿主统一导航入口这些问题看起来分散本质上都和 owner、状态来源、刷新时机和验证范围有关。只修一个按钮通常不够要让同一类路径都走回同一套规则。这次问题给我的复盘拆包要迁移 owner不只是迁移文件复盘这类问题时我会先把用户看到的现象落到工程 owner 上再看代码是不是沿着同一条边界走。只要 owner 不清后面就会变成谁顺手谁修owner 清楚以后验证也能回到具体路径而不是靠感觉判断。真正落到项目里我会用这份小清单收尾先把用户看到的现象对应到具体 owner避免只改表面 UI。再确认写入、读取、刷新、路由或资源是否沿着同一条链路。搜索旧入口、旧 key、硬编码值或临时输出能解释的保留解释不通的收口。用真实入口走一遍主路径再补空态、失败态、返回、重启或宽屏路径。把剩余风险写清楚下一次维护时就不用重新猜当时为什么这么改。小结拆包要迁移所有权拆包要迁移 owner不只是迁移文件 这类问题最终都要回到 owner、代码边界和真实路径验证不能只看某个片段是否写得顺眼。2. 再确认写入、读取、刷新、路由或资源是否沿着同一条链路。3. 搜索旧入口、旧 key、硬编码值或临时输出能解释的保留解释不通的收口。4. 用真实入口走一遍主路径再补空态、失败态、返回、重启或宽屏路径。5. 把剩余风险写清楚下一次维护时就不用重新猜当时为什么这么改。小结拆包要迁移所有权拆包要迁移 owner不只是迁移文件 这类问题最终都要回到 owner、代码边界和真实路径验证不能只看某个片段是否写得顺眼。