You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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"] }]
    ]
  }
}

验证步骤

  1. 执行npx expo export重新导出资源与bundle
  2. 使用修正后的CodePush命令推送更新
  3. 在设备上安装更新后,通过控制台打印资源URI,确认路径已替换为CodePush目录下的正确路径

内容的提问来源于stack exchange,提问作者Amir Ben Shimol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:25:57