需求描述:
根据后台返回的图片名称,加载静态资源中所对应名称的图标
为了方便,项目期初并没有将静态资源放到类似于 OSS 这样的静态服务器上面,而是放到了项目中
问题描述:
组件渲染过程中需要动态渲染img元素,于是使用了node的require模块,再使用es6模板字符串动态拼接src路径:
<img className="w-16" src={require(`assets/images/weatherIcons/${weatherInfo?.icon}.png`)} alt="" />
保存编译后控制台会报如下错误:
如果路径写死不使用变量的话:
<img className="w-16" src={require(`assets/images/weatherIcons/100.png`)} alt="" />
就不会报错,于是分析了一波:
项目是用webpack5 + react17 来构建的,webpack编译过程中会将一定大小以内的图片转换为base64格式的,如果写死路径就没问题,关键是使用了变量后,webpack 首先会编译ts、tsx等,此时带变量的路径会编译成‘assets/images/weatherIcons/100.png’,但是本地的图标资源已经编译成了base64格式的,所以会找不到匹配的图标,就会报找不到模块的错误(可能描述不够准确,欢迎补充)。
于是想了个s操作,将所有的图标资源放到一个数组中,名称为键,路径为值:
但是几十上百个图标这么去写有点儿费时间,于是有了s操作二:
const getImages = (path, toPath) => {
fs.readdir(path, function (error, files) {
if (!error) {
const newFiles = files.map(item => {
let name = item.split('.')[0]
return {
[name]: `require(${toPath + item})`
}
})
fs.writeFile('./images.json', JSON.stringify(newFiles), function (err) {
if (err) {
res.status(500).send('Server is error...')
}
})
} else {
console.log(error);
}
})
}
getImages("./public/images/", "assets/images/weatherIcons/")
使用node的内置模块fs,readdir读出,writeFile写入,最后生成json文件:
最后根据需要将值替换掉多余的引号就行了。
如果有更好的方法,欢迎留言。