前言
Vite项目开发一个H5活动页时,碰到的图片资源引入的问题,记录下Vite项目中不能使用require的替代方案,大佬们有更好的方法欢迎指点下。
正常引入资源URL
Vite和Webpack中都可以将资源引入为URL使用
import imgUrl from '@/assests/img.png';
<img src={imgUrl} />
但是在活动中,会存在大量的图片,一个一个引入比较麻烦
import headImg from '@/assets/activity/head.webp';
import logoImg from '@/assets/activity/logo.webp';
import btnImg from '@/assets/activity/btn.webp';
// ...
动态传入文件路径引入
Webpack
Webpack中可以直接使用require进行动态导入
<img src={require('@/assets/activity/head.webp')} />
Vite
Vite中可以通过结合import.meta.url和原生的URL构造器组合使用
<img src={new URL('@/assets/activity/head.webp', import.meta.url).href} />
运行时根据变量使用对应的图片
活动中,可能会根据领取状态决定按钮是否是禁用的状态,或者列表中,根据索引来使用对应的图片等操作。
Webpack
Webpack中通过require直接使用模板字符串
const status = 0
<img src={require(`@/assests/activity/btn${status === 0 ? '-disabled' : ''}.webp`)} />
Vite
Vite中实现这个功能就比较复杂了,new URL + import.meta.url的字符串必须是静态的才能分析,引入动态参数的值获取不正确
const status = 0;
const imgUrl = new URL(`@/assests/activity/btn${status === 0 ? '-disabled' : ''}.webp`, import.meta.url).href
// 无法正确获取
可以通过import.meta.global的方式,将整个文件夹的图片都引入进来
const images = import.meta.glob('@/assets/activity/*.{webp}', {
eager: true
});
console.log(images)
可以看到,获取的是一个对象,对象中值的default字段就是我们要的URL路径,我们写个方法转换下这个对象,属性名是文件名,属性值就是需要的URL值,方便使用。
const getGlobalFolderAssets = (folderAssets) => {
return Object.fromEntries(
Object.entries(folderAssets).map(([key, value]) => {
// 提取文件名作为键
const fileName = key.substring(key.lastIndexOf('/') + 1);
return [fileName, value.default];
})
);
};
const images = getGlobalFolderAssets(import.meta.glob('@/assets/activity/*.webp', {
eager: true
}));
const status = 0;
<img src={images[`btn${status === 0 ? '-disabled' : ''}.webp`]} />