Expo中访问assets本地资产的正确实现方式是什么?
Expo 本地assets目录下JSON资产的正确访问方式
三类报错的核心根因
Asset API的设计定位是处理需打包、缓存、获取本地路径的非JS类静态资产(如图片、字体、音视频),JSON作为可被Metro直接解析的JS模块类型,本身不属于Asset API的适用范围,强行套用Asset流程是三类报错的核心诱因:
- 方案1报错:
require是打包阶段的模块导入语法,不支持直接传入file协议形式的字符串路径,Metro在构建阶段无法匹配该形式的模块位置,因此抛出无法解析模块的错误。 - 方案2报错:常规配置下Metro会自动将JSON文件解析为JS模块,通过
require('相对路径/catalog.json')拿到的是解析完成的JSON对象,而非Asset.loadAsync要求的、注册在资产表中的资产标识符,因此触发资产注册表缺失的报错。 - 方案3报错:
Asset.loadAsync直接传入相对路径字符串时,会将字符串识别为远程可下载的网络URL发起请求,相对路径本身不是合法的可访问资源地址,因此触发系统层的“不支持的URL”错误。
分场景的正确实现
场景1:仅需读取JSON结构化内容(绝大多数业务场景)
无需引入Asset模块,通过相对路径直接导入JSON文件即可。Metro会在打包阶段自动完成JSON内容解析,导入拿到的就是可直接操作的JS对象,无额外异步加载开销:
// 示例:当前代码文件路径为 src/screens/List/index.js // 目标资产路径为 项目根目录/assets/data/catalog.json // 计算相对路径:从当前文件向上跳转3层到项目根目录,再进入对应资产目录 import catalogData from '../../../assets/data/catalog.json'; // 直接读取JSON中的字段 console.log('目录更新时间:', catalogData.updateTime); console.log('商品列表:', catalogData.products);
场景2:需要获取JSON文件的本地磁盘路径(原生交互类场景)
如果需要将JSON文件的真实物理路径传给原生模块进行文件流操作,需先调整Metro配置,将指定路径下的JSON文件作为静态资产而非JS模块处理,之后再通过Asset API完成加载:
- 修改
metro.config.js的模块解析规则,将assets/data目录下的JSON文件加入资产扩展名列表、移出JS模块解析扩展名列表,避免被Metro解析为JS模块 - 调整配置后,通过require导入该路径下的JSON文件,会返回符合Asset API要求的资产标识对象
- 将该标识传入
Asset.loadAsync完成本地缓存加载,即可从返回结果中拿到资产的本地磁盘uri
内容的提问来源于stack exchange,提问作者rnofenko
相关产品推荐
相关产品推荐

