【Vite】如何阻止Vite对较小图片的默认处理

前言

项目中使用一大一小两张图片

在这里插入图片描述
在这里插入图片描述

但是打包结果中并未发现小图

在这里插入图片描述

这是由于 Vite 默认的优化手段,当图片小于 4KB 时,会处理为 base64,在打包后的 JS 中可以查看

在这里插入图片描述

执行 npm run preview 查看线上环境发现,打印的图片路径也为base64,大部分情况下,这种差异不会有影响,但如果强制要求图片必须完全一致,就需要阻止 Vite 这个默认优化手段。

在这里插入图片描述

方法一:取消默认优化

通过 assetsInlineLimit 将默认的 4096 变为 0,这个选项只会影响生产环境

export default defineConfig({
  plugins: [react()],
  build: {
    assetsInlineLimit: 0,
  },
})

分别执行 npm run buildnpm run preview,可以发现小图也正常处理了

在这里插入图片描述

在这里插入图片描述

但是丢失了 Vite 本身的优化行为,所以并不推荐这种方法。

方法二:自己写一个Vite插件(推荐)

为了确保图片在开发和生产环境下的完全一致,但又要保证 Vite 默认优化行为,只能修改开发环境,保证与开发环境下的优化机制一致。

Vite 配置选项里并没有针对开发环境的配置,需要自己写一个

const myPlugin = (limit = 4096) => {
  return {
    name: "my-plugin",
    transform(code, id) {
      console.log(id)
      if (process.env.NODE_ENV !== "development") {
        return
      }
    },
  }
}

export default defineConfig({
  plugins: [react(), myPlugin()],
})

Vite 基于 Rollup 的插件系统,transform 是 rollup 钩子,用于在代码模块被加载和打包之前,对模块内容进行修改或转换。code 是模块的内容,id 是模块的路径。

在这里插入图片描述

使用 node 环境下的 fs 读取文件状态并查看

import fs from "node:fs"

const myPlugin = (limit = 4096) => {
  return {
    name: "my-plugin",
    async transform(code, id) {
      if (process.env.NODE_ENV !== "development") {
        return
      }
      // 根据需求筛选要处理的文件
      if (!id.endsWith(".png") || !id.endsWith(".jpg")) {
        return
      }
      const stat = await fs.promises.stat(id)
      console.log(stat)
    },
  }
}

在这里插入图片描述

只需要对 size 进行判断,并在恰当时机(小于4kb)转为 base64 即可

import fs from "node:fs"

const myPlugin = (limit = 4096) => {
  return {
    name: "my-plugin",
    async transform(code, id) {
      if (process.env.NODE_ENV !== "development") {
        return
      }
      if (!id.endsWith(".png") && !id.endsWith(".jpg")) {
        return
      }
      const stat = await fs.promises.stat(id)
      if (stat.size > limit) {
        return
      }
      const buffer = await fs.promises.readFile(id)
      const base64 = buffer.toString("base64")
      const dataurl = `data:image/png;base64,${base64}`
      console.log(dataurl)
    },
  }
}

在这里插入图片描述

最后将处理好的 base64 返回即可

const myPlugin = (limit = 4096) => {
  return {
    name: "my-plugin",
    async transform(code, id) {
      if (process.env.NODE_ENV !== "development") {
        return
      }
      if (!id.endsWith(".png") && !id.endsWith(".jpg")) {
        return
      }
      const stat = await fs.promises.stat(id)
      if (stat.size > limit) {
        return
      }
      const buffer = await fs.promises.readFile(id)
      const base64 = buffer.toString("base64")
      const dataurl = `data:image/png;base64,${base64}`

      return {
        code: `export default ${JSON.stringify(dataurl)}`,
      }
    },
  }
}

查看开发环境

在这里插入图片描述

如果想要将插件发布到npm,请看本人另一篇文章:如何将开发的vite插件发布到npm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田本初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值