Expo EAS dev client首次启动Metro时Android端重复打包如何修复
EAS Dev Client 安卓冷启动触发两次Metro打包问题排查与修复
排查方向1:expo-dev-client 版本自带的预加载逻辑缺陷
- 这是该问题最高发的诱因:3.2.x及更早版本的expo-dev-client,冷启动时会先发起一次预加载请求拉取基础运行时资源,等主应用实例初始化完成后,不会复用预加载的缓存,会再次发起完整的业务bundle请求,刚好匹配「仅首次启动触发两次打包、按r重载/按a重开应用均正常」的特征。
- 验证方式:带debug参数启动Metro:
DEBUG=metro,expo-dev-client npx expo start --dev-client,查看两次bundle请求的标识,如果能看到其中一次带preload标记即可确认。 - 修复方案:直接将expo-dev-client升级到3.3.0以上版本,官方已经修复了预加载缓存复用的问题;如果暂时无法升级依赖,可以在
metro.config.js中增加短时效的请求缓存逻辑,相同bundle hash的请求10秒内直接返回缓存结果,不重复执行打包。
排查方向2:安卓模拟器系统连通性探测误触发
- Android 13及以上版本的官方模拟器,冷启动新安装应用时会自动发起一次localhost端口连通性探测,这个请求会被Metro识别为正式的bundle拉取请求,触发额外一次打包流程。
- 验证方式:查看Metro日志中两次请求的进程标识,如果其中一次请求的来源UID为系统进程标识(0开头),同时模拟器私人DNS设置为自动/开启状态即可确认。
- 修复方案:启动Metro时指定绑定本地回环地址,不要全网段监听:
npx expo start --dev-client --host 127.0.0.1;也可以直接在模拟器设置中关闭私人DNS、关闭开发者选项里的网络连通性检查开关。
排查方向3:入口文件重复注册(低优先级)
- 如果自定义过Dev Client启动逻辑、或者手动修改过入口注册代码,重复调用
AppRegistry.registerComponent也可能触发双打包,不过该问题一般在热重载时也会复现,可放在最后排查。 - 验证方式:在项目入口文件(通常为
index.js或App.js)最顶部加一行打印日志,冷启动时如果日志输出两次即可确认。 - 修复方案:核对
app.json中expo.entryPoint配置和实际入口路径一致,移除重复的入口注册代码。
临时规避方案:首次启动等两次打包都完成后,按一次r键触发热重载,后续调试过程中就不会再出现重复打包引发的运行异常。
内容的提问来源于stack exchange,提问作者Bassel Turky
相关产品推荐
相关产品推荐

