React Native Expo构建后无法读取assets目录CSV文件求解决方案
问题描述
开发的React Native Expo应用用于读取CSV数据,使用FileSystem和Expo Asset访问文件。开发阶段在Google Project IDX编写代码,Web版本调试及执行expo start时均正常,CSV文件可正常读取;但通过EAS构建应用后,CSV文件无法被找到,界面始终显示“Loading...”。
CSV文件位于Expo的assets目录(assets/jadwal_sholat.csv),index.tsx在app目录下。已尝试USB调试,但log.txt中无报错信息,直接使用require()路径也无效。
相关代码:
类型定义与数据加载逻辑
interface ParsedSholatTimes { Tanggal: string; Subuh: string; Dzuhur: string; Ashar: string; Maghrib: string; Isya: string; } useEffect(() => { const fetchCsvData = async () => { try { const asset: Asset = Asset.fromModule(require('../assets/jadwal_sholat.csv')); await asset.downloadAsync(); const csvFile: string = await FileSystem.readAsStringAsync(asset.localUri || ''); Papa.parse<ParsedSholatTimes>(csvFile, { header: true, complete: (results: ParseResult<ParsedSholatTimes>) => { const now = new Date(); const formattedToday = `${now.getDate()}/${now.getMonth() + 1}/${now.getFullYear()}`; const todayTimes = results.data.find((row: ParsedSholatTimes) => { const [day, month, year] = row.Tanggal.split('/').map(Number); const csvDate = new Date(year, month - 1, day); return ( csvDate.getDate() === now.getDate() && csvDate.getMonth() === now.getMonth() && csvDate.getFullYear() === now.getFullYear() ); }); if (todayTimes) { setSholatTimes(todayTimes); } else { console.log('No times found for today'); } }, }); } catch (error) { console.error('Error fetching or parsing CSV:', error); } };
界面渲染代码
{prayerTimes.map((prayer: PrayerTime, index: number) => { const borderColor = tw`border-${prayer.color}`; const bgColor = tw`bg-${prayer.color}`; return ( <View key={prayer.name} style={[tw`w-full bg-neutral-100 p-3 rounded-xl mb-3`, borderColor]}> <View style={tw`flex-row items-center justify-between`}> <View style={tw`flex-row items-center`}> <View style={[tw`rounded-full px-5 py-3 mr-2 w-44 `, bgColor]}> <Text style={tw`text-3xl font-bold text-white text-center`}>{prayer.name}</Text> </View> </View> <Text style={tw`text-4xl font-bold`}>{prayer.time || 'Loading...'}</Text> </View> </View> ); })}
解决方案
1. 确保assets在app.json中正确声明
Expo EAS构建时,只有在app.json的expo.assets数组中声明的资源才会被打包进应用。打开app.json,检查是否包含以下配置:
{ "expo": { "assets": [ "./assets/**/*" // 匹配所有assets目录下的文件 // 或者精确指定 "./assets/jadwal_sholat.csv" ] } }
2. 调整CSV文件加载逻辑(适配EAS构建环境)
EAS构建后,打包的资源路径与开发环境不同,无需调用downloadAsync,直接通过FileSystem.bundledAssets访问打包后的文件:
useEffect(() => { const fetchCsvData = async () => { try { // 直接访问打包后的CSV文件路径 const csvPath = `${FileSystem.bundledAssets}/jadwal_sholat.csv`; // 先验证文件是否存在 const fileInfo = await FileSystem.getInfoAsync(csvPath); if (!fileInfo.exists) { console.error('CSV文件不存在:', csvPath); return; } const csvFile = await FileSystem.readAsStringAsync(csvPath); Papa.parse<ParsedSholatTimes>(csvFile, { header: true, complete: (results) => { const now = new Date(); const todayTimes = results.data.find((row) => { const [day, month, year] = row.Tanggal.split('/').map(Number); const csvDate = new Date(year, month - 1, day); return ( csvDate.getDate() === now.getDate() && csvDate.getMonth() === now.getMonth() && csvDate.getFullYear() === now.getFullYear() ); }); if (todayTimes) { setSholatTimes(todayTimes); } else { console.log('今日无祈祷时间数据'); } }, error: (error) => { console.error('CSV解析错误:', error); } }); } catch (error) { console.error('加载CSV失败:', JSON.stringify(error)); // 可添加Alert提示用户 // Alert.alert('加载失败', '无法读取祈祷时间数据'); } }; fetchCsvData(); }, []);
3. 增强错误日志排查
USB调试的log.txt可能未捕获全部日志,建议:
- 使用
expo logs:device命令实时查看设备日志,获取更详细的错误信息 - 在catch块中打印完整错误对象(用
JSON.stringify),避免只打印错误消息丢失关键信息
4. 验证文件路径与大小写
- 确认CSV文件名拼写完全一致(iOS系统区分文件名大小写,比如
Jadwal_Sholat.csv和jadwal_sholat.csv会被视为不同文件) - 检查index.tsx所在目录与assets目录的相对路径是否正确(app目录下的index.tsx,相对路径
../assets/jadwal_sholat.csv是正确的)
内容的提问来源于stack exchange,提问作者Sultan Zaki
相关产品推荐
相关产品推荐

