React JS中使用require动态加载本地图片无法正常显示问题求助
问题诱因
- 打包工具静态解析限制:项目使用的webpack等打包工具在构建阶段会静态扫描可识别的资源依赖,你的路径写法虽然有固定的
../../Assets/前缀,但部分配置下工具不会默认遍历整个Assets目录打包所有资源,运行时请求的资源路径不存在。 - 模块导出规则兼容问题:如果项目开启了ES模块兼容CommonJS的配置,require引入图片资源后返回的是一个ESModule对象,真实的资源路径存放在
default属性下,直接将整个返回值赋值给src属性会导致路径错误。
修复方案
方案1:兼容模块导出规则(最快修复)
直接在require调用后取default属性,适配ESModule的导出规则:
<img alt={image} src={require(`../../Assets/${image}`).default}/>
该方案生效的前提是你的打包工具配置了对动态路径前缀的识别,会自动打包
../../Assets/下的所有资源。
方案2:静态映射表引入(最稳定)
提前将所有需要用到的图片引入并生成映射表,打包工具只会打包明确用到的资源,不会产生冗余文件:
import React from 'react'; import './produto.css' // 提前创建图片映射表 const imgMap = { 'super-mario-odyssey.png': require('../../Assets/super-mario-odyssey.png'), 'call-of-duty-infinite-warfare.png': require('../../Assets/call-of-duty-infinite-warfare.png'), 'the-witcher-iii-wild-hunt.png': require('../../Assets/the-witcher-iii-wild-hunt.png'), 'call-of-duty-wwii.png': require('../../Assets/call-of-duty-wwii.png'), 'mortal-kombat-xl.png': require('../../Assets/mortal-kombat-xl.png'), 'shards-of-darkness.png': require('../../Assets/shards-of-darkness.png'), 'terra-media-sombras-de-mordor.png': require('../../Assets/terra-media-sombras-de-mordor.png'), 'fifa-18.png': require('../../Assets/fifa-18.png'), 'horizon-zero-dawn.png': require('../../Assets/horizon-zero-dawn.png') } function Produto({data}) { const { id, name, price, score, image } = data; return <div className='produto-card-container' key={id}> <div className='produto-card-flex'> <img alt={image} src={imgMap[image]}/> </div> </div> } export default Produto;
方案3:使用public目录托管(适合大量图片场景)
如果你的图片数量很多,不方便维护映射表,可以将所有图片放到项目public目录下的Assets文件夹中,直接使用公共路径拼接访问:
<img alt={image} src={`${process.env.PUBLIC_URL}/Assets/${image}`}/>
注意:该方案下的图片不会被打包工具添加哈希后缀,更新资源时需要注意浏览器缓存问题。
内容的提问来源于stack exchange,提问作者Matheus Martins
相关产品推荐
相关产品推荐

