Vite中引入图片不支持require替代方案

434 阅读1分钟

前言

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值,方便使用。

image.png

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`]} />