实现图片预加载 vite 插件

实现图片预加载 vite 插件

ts
export default definConfig({
  // base: '/dist/', // 如果项目部署在二级目录,需要指定 base 路径
  plugins: [vue(), vueJsx(), preloadImages()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    }
  }
})

preloadImages 函数里指定一个图片目录,然后把目录下的所有图片都放到 head 里预加载

ts
preloadImages({
  dir: 'images/*.{jpg,png,gif,webp,svg}'
  attrs: {
    rel: 'preload'
  }
})
ts
import type { Plugin } from 'vite'
import fg from 'fast-glob'

interface PreloadImagesOptions {
  dir: string // 图片目录
  attrs: {
    rel: 'prefetch | preload' // 预加载类型
  }
}

export const preloadImages = (options: PreloadImagesOptions): Plugin => {
  const { dir, attrs = {} } = options

  return {
    name: 'vite-plugin-image-prefetch', // 插件名字,必须要有
    transformIndexHtml(html, ctx) {
      // return html.replace('<title>Vite App</title>', '<title>Hello World</title>')

      // 这样可以把图片放到 head 里预加载,但是写死了,能不能加载某个目录下的所有图片呢?
      // return [
      //    {
      //      tag: 'link',
      //       attrs: {
      //          rel: 'prefetch',
      //          href: 'https://example.com/image1.png',
      //          as: 'image'
      //       }
      //    }
      // ]

      // 获取图片目录下的所有图片
      const files = fg.sync(dir, {
        cwd: ctx.server?.config.publicDir,
      })
      console.log('files', files) // [ 'images/logo.png' ]

      const images = files.map(file => ctx.server?.config.base + file) // 加上 base 路径, 用户如果指定base 路径,也能正确加载
      console.log('images', images) // [ '/images/logo.png' ]
      return images.map((href) => {
        return {
          tag: 'link',
          attrs: {
            // prefetch 和 preload 的区别是什么?
            // 加载时机不一样,
            // perfetch 是在浏览器空闲时加载,优先级低,下次用还是要发一个请求,之前请求过了,直接用缓存就行了,
            // preload 是存到浏览器内存里,不是http缓存,优先级高,不会再发送请求了
            rel: 'prefetch',
            href,
            as: 'image',
            ...attrs, // 用户可以自定义 rel 属性
          }
        }
      })
    }
  }
}
手写常见js代码
编译文本节点
欢迎来到前端练习生ZM的小站