React+TypeScript组件中图片无法渲染的问题求助
React + TypeScript 组件动态加载图片失败问题
控制台报错
Uncaught Error: Cannot find module '../images/test.png' at webpackEmptyContext...
组件代码
import { IProject } from '../interfaces/IProject' import pin from '../svgs/pin.svg' function Project(props: { project: IProject }) { const project = props.project return ( <> <div className='project'> <img className='pin' src={pin} alt='pin' /> <div> <img alt='project gif' src={require(project.image)} /> <span>{project.title}</span> </div> </div> </> ) } export default Project
说明:图片存储在images文件夹,Project组件位于components文件夹;静态导入的pin图片加载正常。
已尝试的方案
- 直接将
require(project.image)替换为require('../images/test.png')可正常显示,但希望通过props动态传递图片路径 - 定义变量
const projectImage = '../images/test.png',使用require(projectImage)仍无效 - 创建
index.d.ts文件并添加declare module '*.jpg'、declare module '*.jpeg'、declare module '*.png'的类型声明,未解决问题 - 调整图片路径
- 安装了
file-loader
解决方案
方案1:用Webpack上下文模块预加载图片目录
Webpack需要静态解析模块路径,动态路径无法被识别。可以通过上下文模块指定图片目录,让Webpack预加载该目录下的所有图片:
import { IProject } from '../interfaces/IProject' import pin from '../svgs/pin.svg' // 定义图片上下文:参数分别为目录、是否递归子目录、匹配的文件后缀 const images = require.context('../images', false, /\.(png|jpe?g|gif)$/); function Project(props: { project: IProject }) { const project = props.project; // 注意:此时project.image应为图片文件名(如'test.png'),而非完整相对路径 const imageUrl = images(`./${project.image}`); return ( <> <div className='project'> <img className='pin' src={pin} alt='pin' /> <div> <img alt='project gif' src={imageUrl} /> <span>{project.title}</span> </div> </div> </> ) }
方案2:静态导入所有图片,用映射表匹配
若图片数量不多,可提前导入所有需要的图片,通过映射表匹配props传递的名称:
import { IProject } from '../interfaces/IProject' import pin from '../svgs/pin.svg' // 提前导入所有需要的图片 import testImg from '../images/test.png' import anotherImg from '../images/another.png' // 创建图片映射表 const imageMap = { 'test.png': testImg, 'another.png': anotherImg, } function Project(props: { project: IProject }) { const project = props.project; const imageUrl = imageMap[project.image] return ( <> <div className='project'> <img className='pin' src={pin} alt='pin' /> <div> <img alt='project gif' src={imageUrl} /> <span>{project.title}</span> </div> </div> </> ) }
方案3:将图片放入public目录,直接用绝对路径
把图片移到项目的public文件夹下,可直接通过绝对路径引用,无需Webpack打包:
假设test.png放在public/images/下,project.image的值设为/images/test.png,组件中直接使用:
<img alt='project gif' src={project.image} />
问题根源
Webpack是静态模块打包工具,编译时会解析所有import和require语句。动态路径require(project.image)无法被Webpack静态分析,因此无法识别要加载的模块;而静态导入import pin from '../svgs/pin.svg'能正常工作,是因为路径明确可被解析。
内容的提问来源于stack exchange,提问作者Jessica Bassil
相关产品推荐
相关产品推荐

