React函数内动态require图片报模块找不到问题求解
报错根源
React脚手架(CRA、Vite默认配置等)底层做模块打包时,require的路径解析是构建阶段静态扫描的,不支持传入完全动态的全路径变量。你直接写死require('./img/logo.png')能正常运行,是因为写死的字符串在打包时就会被工具捕获、处理对应图片资源;换成require(src)这种全路径用变量传入的写法,打包工具没法提前预判你要引入哪个文件,自然会报找不到模块的错误。
可复用的require实现方案
打包工具支持固定路径前缀 + 动态文件名的引入形式,你只需要把资源所在的固定目录写死在require内部,仅把可变的文件名作为参数传入,就能让工具在构建时扫描对应目录下的所有资源,运行时正确返回路径。改造后代码如下:
function App() { // require内必须写死资源所在的固定目录,不能把全路径都作为变量传递 const getSrcSet = (imgName) => { const ext = '.' + imgName.split('.').pop(); const baseName = imgName.replace(ext, ''); const img1x = require(`./img/${imgName}`).default; const img2x = require(`./img/${baseName}@2x${ext}`).default; return `${img1x} 1x, ${img2x} 2x`; } return ( <img src={require('./img/logo.png').default} srcSet={getSrcSet('logo.png')} alt="logo" /> ); }
这种写法下,打包工具会在构建阶段把./img/目录下所有可匹配的图片都纳入依赖管理,既保留了require引入资源的能力(自动处理资源hash、压缩、路径转换,资源不存在时构建阶段直接报错),又能复用getSrcSet逻辑,不用每张图单独写引入语句。
另外两种方案的适用场景
PUBLIC_URL拼接路径的方案:仅适合把图片放在public目录、不经过打包工具处理的场景,资源会被直接拷贝到构建产物目录,优点是写法简单,缺点是没法享受打包的资源优化能力,路径写错了也不会在构建阶段报错- 静态import方案:适合图片数量少、路径固定的场景,优点是类型校验、路径检查最严谨,缺点是复用性差,批量使用时要重复写大量引入代码。
内容的提问来源于stack exchange,提问作者mdurchholz
相关产品推荐
相关产品推荐

