EAS构建iOS预览版无法解析本地音频资源求助
Expo iOS Preview构建音频资源解析失败问题解决
问题背景
执行eas build --platform ios --profile preview构建Expo iOS预览包时,JS打包阶段报错无法找到首页导入的音频文件,但使用npx expo run:ios -d进行开发构建时完全正常。
错误信息
Unable to resolve module ../../assets/audio/meditation_10_min.mp3 from /Users/expo/workingdir/build/app/(tabs)/index.jsx: const track = require("../../assets/audio/meditation_10_min.mp3"); const player = useAudioPlayer(track);
已尝试方案
- 替换
require为常规import导入 - 使用
expo-asset的useAssetsAPI,但未处理异步加载状态导致assets为undefined - 在
app.json中配置expo-asset插件嵌入资源,仍未解决
有效解决步骤
1. 正确使用useAssets异步API
useAssets是异步加载资源的钩子,组件初始化时assets会是undefined,必须先判断加载状态,再初始化播放器:
import { useAudioPlayer } from "expo-audio"; import { useAssets } from "expo-asset"; import { Text, View } from "react-native"; export default function HomeTab() { const [assets, error] = useAssets([ require("../../assets/audio/meditation_10_min.mp3"), ]); // 资源未加载完成时显示加载状态 if (!assets) { return <View><Text>加载音频资源中...</Text></View>; } // 资源加载失败时显示错误 if (error) { return <View><Text>音频加载失败: {error.message}</Text></View>; } // 资源加载完成后初始化播放器 const player = useAudioPlayer(assets[0]); // 你的组件渲染逻辑 return <View>...</View>; }
2. 校验资源路径与打包配置
- 路径大小写检查:iOS打包对文件路径大小写敏感,开发环境可能自动忽略,确保代码中的路径和实际文件路径完全一致(包括文件名大小写)。
app.json配置修复:确保expo-asset插件的资源路径是项目根目录的相对路径,配置完成后需重新执行expo prebuild(裸工作流)或重新触发EAS构建:
"plugins": [ "expo-audio", [ "expo-asset", { "assets": ["./assets/audio/meditation_10_min.mp3"] } ] ]
3. 清理构建缓存
EAS构建可能留存旧的资源映射缓存,导致新资源无法被正确识别:
- 本地缓存清理:执行
npx expo prebuild --clean - 远程缓存清理:在Expo控制台找到对应项目的构建记录,选择「Clear Cache」后重新发起构建
4. 直接导入+手动加载资源的替代方案
如果useAssets仍有问题,可以直接导入资源并通过Asset.fromModule手动处理加载:
import { useAudioPlayer } from "expo-audio"; import { Asset } from "expo-asset"; import { useState, useEffect } from "react"; import { Text, View } from "react-native"; import meditationAudio from "../../assets/audio/meditation_10_min.mp3"; export default function HomeTab() { const [audioAsset, setAudioAsset] = useState(null); useEffect(() => { const loadAudioAsset = async () => { const asset = Asset.fromModule(meditationAudio); await asset.downloadAsync(); setAudioAsset(asset); }; loadAudioAsset(); }, []); if (!audioAsset) { return <View><Text>加载中...</Text></View>; } const player = useAudioPlayer(audioAsset); return <View>...</View>; }
内容的提问来源于stack exchange,提问作者Marc Fletcher
相关产品推荐
相关产品推荐

