Expo裸工作流未连接Metro时React Native矢量图标不显示问题
问题现象
在Expo bare workflow(裸工作流)环境中,未连接Metro打包服务时React Native矢量图标无法正常显示
当前项目依赖
"@react-navigation/native": "^6.0.10", "@react-navigation/stack": "^6.2.1", "expo": "~45.0.0", "expo-constants": "^13.1.1", "expo-file-system": "^14.0.0", "expo-media-library": "^14.1.0", "expo-screen-orientation": "^4.2.0", "expo-splash-screen": "~0.15.1", "expo-sqlite": "~10.2.0", "expo-status-bar": "~1.3.0", "expo-video-thumbnails": "^6.3.0", "react": "17.0.2", "react-dom": "17.0.2", "react-native": "0.68.2", "react-native-gesture-handler": "^2.4.2", "react-native-get-random-values": "^1.8.0", "react-native-ionicons": "^4.6.5", "react-native-safe-area-context": "^4.2.5", "react-native-screens": "^3.13.1", "react-native-web": "0.17.7", "react-redux": "^8.0.2", "redux": "^4.2.0", "redux-thunk": "^2.4.1", "uuid": "^8.3.2"
- 预期效果:图标正常渲染展示
- 实际异常:图标位置显示空白/方块乱码
排查思路
按优先级从高到低排查:
- 校验图标依赖和Expo版本的兼容性:当前安装的
react-native-ionicons是社区维护的原生包,不是Expo官方适配的矢量图标包,裸工作流场景下不会自动完成原生端字体资源链接。连接Metro时资源由本地打包服务实时推送所以显示正常,打离线包/断开Metro时字体资源未被打入原生安装包,就会出现加载失败。 - 核对原生端字体配置:安卓端检查
android/app/src/main/assets/fonts目录下是否存在对应图标字体文件(如Ionicons.ttf);iOS端检查Xcode项目的Copy Bundle Resources构建阶段是否引入了对应字体文件,同时Info.plist中Fonts provided by application配置项是否包含对应字体文件名。 - 排查构建缓存影响:如果之前配置过字体,大概率是原生构建缓存、Metro缓存未清理,导致新构建的包未携带最新字体资源。
- 检查组件引用正确性:确认导入的图标组件和实际安装的依赖包匹配,不存在跨包引用、路径错误问题。
可行解决方案
方案1:替换为Expo官方适配图标包(适配成本最低,兼容裸工作流)
- 卸载不兼容的社区依赖包:
npm uninstall react-native-ionicons # 用yarn的话执行 yarn remove react-native-ionicons - 安装和Expo SDK 45版本完全匹配的官方矢量图标包:
expo install @expo/vector-icons - 执行预构建同步原生端资源(SDK 45版本不会自动链接该包的原生资源):
# 同步安卓端资源 npx expo prebuild -p android --clean # 同步iOS端资源 npx expo prebuild -p ios --clean - 完全卸载手机上已安装的旧版本安装包,重新构建原生包安装,断开Metro即可正常显示图标。
方案2:保留现有react-native-ionicons依赖,手动补全原生字体配置
如果不想替换现有依赖,手动将字体资源打入原生包即可:
- 找到
node_modules/react-native-ionicons/fonts目录下的Ionicons.ttf字体文件 - 安卓端配置:将ttf文件复制到
android/app/src/main/assets/fonts目录下,不存在fonts文件夹就手动新建 - iOS端配置:打开ios目录下的.xcworkspace项目文件,把ttf文件拖入项目资源目录,勾选
Copy items if needed;同时打开项目的Info.plist文件,添加Fonts provided by application配置项,新增一行值为Ionicons.ttf - 全量清理缓存后重新打包:
# 清理Metro缓存 npx react-native start --reset-cache # 安卓端清理构建缓存后打release包 cd android && ./gradlew clean && cd .. && npx react-native run-android --variant=release # iOS端在Xcode中执行Clean Build Folder后重新打release包
方案3:手动打离线Bundle校验资源打包情况
如果不确定资源是否被正确打入包内,可以先手动打包离线jsbundle放到原生资源目录验证:
# 打包安卓离线bundle及对应资源 npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/ # 打包完成后重新构建安卓安装包即可
注意:所有操作完成后必须完全卸载手机上的旧安装包再安装新构建的包,避免旧缓存干扰测试结果。
内容的提问来源于stack exchange,提问作者Tushar Vimal
相关产品推荐
相关产品推荐

