【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

Vue3、Vite 和 TypeScript 的组合通常用于构建高性能的现代Web应用。对于静态图片处理,你可以采用以下步骤: 1. **安装依赖**: - 使用`npm`或`yarn`安装`vue.config.js`文件,以便配置Vite支持TypeScript:`npm install @vitejs/plugin-vue@next typescript` - 如果需要处理图片,安装一个图片处理库,如`sharp`(Node.js的高性能图像处理库),但在客户端运行Vite时,可能不会直接引入,因为Vite默认会打包到浏览器。 2. **配置Vite**: - 在`.viteignore`文件中忽略`node_modules`,防止打包过多不必要的体积。 - 更新`vite.config.ts`,添加TypeScript支持,配置Vite插件: ```typescript import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], build: { target: 'esnext', tsconfig: './tsconfig.build.json', // 根据项目需求配置正确的TS编译配置 }, }); ``` 3. **图片资源管理**: - 将图片放入`public`目录下,Vite会自动处理静态资产。 - 对于动态生成的图片(例如需要根据某些条件调整大小或添加水印),可以使用JavaScript (ES6+) 动态创建Image对象,或者在服务器端渲染时使用像`sharp`这样的库处理图片后再返回给前端。 4. **使用TypeScript**: - 引入图片处理模块时,确保正确导入并处理类型安全: ```typescript import sharp from 'sharp'; // 假设sharp是全局可用的,若不在Node环境则需引入库 async function resizeImage(src: string): Promise<Buffer> { const resized = await sharp(src) .resize(300, 200) // 设置新尺寸 .toBuffer(); // 转换为Buffer对象 return resized; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

田本初

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

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

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

打赏作者

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

抵扣说明:

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

余额充值