Expo裸工程CodePush更新后图片与字体资源丢失求助
解决Expo SDK 51裸工程CodePush更新后资源丢失问题
问题根源
初始构建时,图片、字体等资源存放在原生App的bundle目录(MyApp.app/assets),而CodePush更新后,资源被解压到应用数据目录的CodePush子文件夹下。Expo的expo-asset和expo-image模块默认从原生bundle路径加载资源,导致路径不匹配无法找到资源。
解决方案
1. 修正CodePush推送命令,包含资源文件
之前仅推送Hermes bundle(.hbc),未同步推送资源文件。需要在推送时指定资源目录,确保CodePush将dist/assets下的资源一并部署:
code-push-standalone release MyApp-iOS ./dist/_expo/static/js/ios/index-123.hbc "1.0.34" \ --deploymentName Staging \ --mandatory \ --description "Hotfix: Updated login button text" \ --assetDirectory ./dist/assets
说明:
--assetDirectory参数指定资源所在目录,CodePush会自动将该目录下的文件同步到更新包中,并解压到与bundle同级的assets目录。
2. 自定义资源路径解析,适配CodePush环境
通过CodePush的API判断当前是否处于更新后的环境,动态替换资源URI的路径前缀:
import { useState, useEffect } from 'react'; import { Asset } from 'expo-asset'; import CodePush from 'react-native-code-push'; import { Image } from 'expo-image'; import * as Font from 'expo-font'; // 通用资源路径处理函数 const resolveAssetUri = async (assetModule) => { const asset = Asset.fromModule(assetModule); await asset.downloadAsync(); const updateMeta = await CodePush.getUpdateMetadata(); if (!updateMeta) return asset.uri; // 获取CodePush更新后的资源目录路径 const codePushBundlePath = updateMeta.localPath; const codePushAssetsDir = codePushBundlePath.replace(/index.*\.hbc$/, 'assets'); // 替换原生bundle路径前缀为CodePush资源目录 return asset.uri.replace(/^file:\/\/.*\/MyApp\.app\/assets/, codePushAssetsDir); }; // 图片加载示例 const LoginHeaderBackground = () => { const [imageUri, setImageUri] = useState(null); useEffect(() => { resolveAssetUri(require('../../assets/images/login/login-header-background.png')) .then(setImageUri); }, []); return imageUri ? <Image style={{ height: 360 }} source={{ uri: imageUri }} /> : null; }; // 字体加载示例 const loadAppFonts = async () => { const fontUri = await resolveAssetUri(require('../../assets/fonts/YourFont.ttf')); await Font.loadAsync({ 'YourFont': fontUri, }); };
3. 验证资源路径一致性
推送更新前,确认dist/assets目录的结构与原生工程中assets目录结构完全一致(即src/assets/**/*的层级),确保CodePush解压后资源的相对路径与初始构建一致。
4. 调整Expo导出配置(可选)
在app.json中添加packagerOpts配置,确保资源打包路径与CodePush兼容:
{ "expo": { "assetBundlePatterns": ["./src/assets/**/*"], "packagerOpts": { "assetExts": ["png", "ttf"], "sourceExts": ["js", "jsx", "ts", "tsx", "json"] }, "plugins": [ ["expo-font", { "fonts": ["./src/assets/fonts/*.ttf"] }], ["expo-asset", { "assets": ["./src/assets/images/*.png"] }] ] } }
验证步骤
- 执行
npx expo export重新导出资源与bundle - 使用修正后的CodePush命令推送更新
- 在设备上安装更新后,通过控制台打印资源URI,确认路径已替换为CodePush目录下的正确路径
内容的提问来源于stack exchange,提问作者Amir Ben Shimol
相关产品推荐
相关产品推荐

