当前位置: 首页 > news >正文

在 Vite 中如何处理静态资源

静态资源处理是前端工程经常遇到的问题,在真实的工程中不仅仅包含了动态执行的代码,也不可避免地要引入各种静态资源,如图片JSONWorker 文件Web Assembly 文件等等。

在 Vite 中处理静态资源(如图片、字体、CSS/JS 文件等)主要通过自动路径解析、内联优化、显式后缀控制等机制实现,同时支持生产环境下的哈希命名和压缩优化。接下来我会通过例子,配合官方文档介绍详细的处理方法。《官方文档地址》,本文章篇幅较长,但我希望大家能耐心看完,,对 vite 的学习有很大帮助!!!!

🧩 一、基础导入方式(自动 URL 处理)

接下来让我们在目前的脚手架项目来进行实际的编码,你可以在 Vite 的配置文件中配置一下别名,方便后续的图片引入:

// vite.config.ts
import path from 'path';{resolve: {// 别名配置alias: {'@assets': path.join(__dirname, 'src/assets')}}
}

通过常规 import 导入资源时,Vite 会返回解析后的 公共 URL,并根据文件大小决定是否内联为 Base64:

import imgUrl from './assets/image.png';
document.getElementById('img').src = imgUrl;
  • 开发环境:路径为 /src/assets/image.png
  • 生产环境:自动哈希化路径,如 /assets/image.2d8efhg.png
  • 内联规则:文件体积 < assetsInlineLimit(默认 4KB)时转为 Base64,减少 HTTP 请求 。
     

⚙️ 二、使用组件加载

SVG 组件加载在不同的前端框架中的实现不太相同,社区中也已经了有了对应的插件支持:(其他框架项目可以去查找相关的资料)

  • Vue3 项目中可以引入 vite-svg-loader。

  • React 项目使用 vite-plugin-svgr插件。

现在让我们在 vue3 脚手架项目中安装对应的依赖:

npm install vue-svg-loader --save-dev

或:

yarn add vue-svg-loader --dev

 在项目的 vite.config.js 文件中配置插件:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import svgLoader from 'vite-svg-loader';export default defineConfig({plugins: [vue(),svgLoader({// 默认情况下,它会将 SVG 文件转换为 Vue 组件defaultImport: 'url', // 或者 'component'}),],
});

假设将你的 SVG 文件放在 src/assets/icons 文件夹中。例如:

src/
└── assets/└── icons/└── my-icon.svg

配置完成后,你可以直接导入 SVG 文件作为 Vue 组件:

<template><div><MyIcon class="custom-icon" /></div>
</template><script setup lang="ts">
import MyIcon from './assets/icons/my-icon.svg';
</script><style scoped>
/* 这里可以添加针对 SVG 的样式 */
.custom-icon {width: 100px;height: 100px;fill: blue;
}
</style>

💡  三、显式处理方式(后缀控制)

通过后缀指定资源处理行为:

  1. ?url:强制作为 URL 引入(适用于非标准资源)

    import workletUrl from './paint-worklet.js?url';
    CSS.paintWorklet.addModule(workletUrl);
  2. ?raw:作为原始字符串引入

    import shaderCode from './shader.glsl?raw';
  3. ?worker / ?sharedworker:脚本转为 Web Worker之后我会在后面的文章单独介绍

    import Worker from './data-processor.js?worker';
    const worker = new Worker(); // 生产环境自动分离为独立 chunk
  4. ?inline:强制内联为 Base64

    import inlineIcon from './icon.png?inline';
  5. ?asset(Electron 场景):获取文件物理路径

    import iconPath from '../../build/icon.ico?asset';
    // 输出:path.join(__dirname, "./chunks/icon-xxx.ico")
    ``` [1](@ref)

📂 四、其他静态资源

除了上述的一些资源格式,Vite 也对下面几类格式提供了内置的支持:

  • 媒体类文件,包括mp4webmoggmp3wavflacaac

  • 字体类文件。包括woffwoff2eotttfotf

  • 文本类。包括webmanifestpdftxt

也就是说,你可以在 Vite 将这些类型的文件当做一个 ES 模块来导入使用。如果你的项目中还存在其它格式的静态资源,你可以通过assetsInclude配置让 Vite 来支持加载:

// vite.config.tsexport default defineConfig({// ... 已有配置 ...assetsInclude: ['**/*.jpg','**/*.png','**/*.gif','**/*.webp','**/*.woff','**/*.woff2','**/*.ttf','**/*.eot'],build: {// ... 已有配置 ...assetsInlineLimit: 4096 // 小于4KB的资源转为base64}
});

 1.图片资源 (存放在 src/assets/images/)​

<script setup lang="ts">
// 直接引用
import logo from '@/assets/images/logo.png';// 或通过路径拼接
const dynamicImage = new URL(`./assets/images/${name}.png`, import.meta.url).href;
</script><template><img :src="logo" alt="logo"><img :src="dynamicImage" alt="dynamic">
</template>

2.字体文件 (存放在 src/assets/fonts/)​

/* 在CSS中引用 */
@font-face {font-family: 'MyFont';src: url('@/assets/fonts/my-font.woff2') format('woff2');
}

3.JSON文件 (存放在 src/assets/data/)​

// 直接导入JSON
import config from '@/assets/data/config.json';// 动态导入JSON
const dynamicData = await import(`@/assets/data/${pageName}.json`);

4.公共资源 (存放在 public/ 目录)​

<!-- 直接使用相对路径 -->
<img src="/public-image.jpg" alt="public image">

public 目录的使用时需要注意:

存放无需处理的静态资源(如 robots.txt、保留原名的文件):

  • 路径规则:直接放在 <root>/public 下,通过根路径引用(如 /icon.png
  • 构建行为:原样复制到输出目录(dist),不经过哈希或压缩处理 。
     

⚠️ 注意:

  • 避免在 JS 中引用 public 资源,否则路径可能错误 
  • 内容图片建议放 public,小图标或需 Base64 内联的资源放 src/assets 

🏗️ 五、生产环境优化策略

1.单文件 或 内联

在 Vite 中,所有的静态资源都有两种构建方式,一种是打包成一个单文件,另一种是通过 base64 编码的格式内嵌到代码中。

Vite 中内置的优化方案是下面这样的:

  • 如果静态资源体积 >= 4KB,则提取成单独的文件

  • 如果静态资源体积 < 4KB,则作为 base64 格式的字符串内联

上述的4 KB即为提取成单文件的临界值,当然,这个临界值你可以通过build.assetsInlineLimit自行配置,如下代码所示:

// vite.config.ts
{build: {// 8 KBassetsInlineLimit: 8 * 1024}
}

svg 格式的文件不受这个临时值的影响,始终会打包成单独的文件,因为它和普通格式的图片不一样,需要动态设置一些属性

2.图片压缩 (强烈推荐)

图片资源的体积往往是项目产物体积的大头,如果能尽可能精简图片的体积,那么对项目整体打包产物体积的优化将会是非常明显的。在 JavaScript 领域有一个非常知名的图片压缩库imagemin,作为一个底层的压缩工具,前端的项目中经常基于它来进行图片压缩,比如 Webpack 中大名鼎鼎的image-webpack-loader。社区当中也已经有了开箱即用的 Vite 插件——vite-plugin-imagemin,首先让我们来安装它: 

npm install vite-plugin-imagemin imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo -D

 随后在 Vite 配置文件中引入:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";
import viteImagemin from "vite-plugin-imagemin";
// ... 其他已有导入 ...export default defineConfig({// ... 其他配置保持不变 ...plugins: [vue(),// ... 已有插件 ...viteImagemin({gifsicle: {optimizationLevel: 7,interlaced: false},mozjpeg: {quality: 75,progressive: true},// 无损压缩配置,无损压缩下图片质量不会变差optipng: {optimizationLevel: 7},// 有损压缩配置,有损压缩下图片质量可能会变差pngquant: {quality: [0.8, 0.9],speed: 4},svgo: {plugins: [{ name: 'removeViewBox' },{ name: 'removeEmptyAttrs', active: false }]}})]
});

⚙️ 六、配置项调整

vite.config.js 中定制行为:

export default {// 静态资源基础路径(CDN 部署时使用)base: '/dist/', // 扩展资源检测类型assetsInclude: ['*.pdf', '*.csv'],// 调整内联阈值(单位:字节)build: {assetsInlineLimit: 8 * 1024, // 8KBtarget: 'es2015' // 构建目标}
};
``` [1](@ref) [47](@ref)---### 📂 六、动态路径生成
结合 `import.meta.url` 解析资源路径(SSR 不可用):
```javascript
// 动态生成图片 URL
function getImageUrl(name) {return new URL(`./imgs/${name}.png`, import.meta.url).href;
}
  • 要求:路径必须是静态字符串,否则生产环境可能报错 

 总结:不同场景推荐方式

场景推荐方式示例
图片/字体等常规资源默认 importimport img from './logo.png'
非标准资源(如 Houdini)?url 后缀import worklet from './worklet.js?url'
原始内容(如 GLSL 代码)?raw 后缀import code from './shader.glsl?raw'
无需处理的文件(如 PDF)放 public 目录访问路径:/manual.pdf
Electron 主进程资源路径?asset 后缀import exe from './app.exe?asset'
http://www.xdnf.cn/news/785503.html

相关文章:

  • 飞算 JavaAI 赋能老项目重构:破旧立新的高效利器
  • 使用Redis的四个常见问题及其解决方案
  • redis的哨兵模式和Redis cluster
  • 5分钟申请edu邮箱【方案本周有效】
  • 基于springboot的图书管理系统的设计与实现
  • 无人机论文感想
  • 邢台山峰特种橡胶制品有限公司专题报道
  • 【后端架构师的发展路线】
  • web第九次课后作业--SpringBoot基于mybatis实现对数据库的操作
  • 006网上订餐系统技术解析:打造高效便捷的餐饮服务平台
  • 014校园管理系统技术解析:构建智慧校园管理平台
  • Ⅲ-3.计算机二级选择题(三大结构之循环结构)
  • 主线程极致优化:让CPU“零闲置“的实战方案
  • TypeScript 定义同步方法
  • web第八次课后作业--分层解耦
  • 【Zephyr 系列 6】使用 Zephyr + BLE 打造蓝牙广播与连接系统(STEVAL-IDB011V1 实战)
  • sudo docker exec -it backend bash 以交互方式(interactive)进入正在运行的 Docker 容器的命令行环境
  • linux变量的分类
  • [特殊字符] Unity 性能优化终极指南 — Text / TextMeshPro 组件篇
  • WebRTC中sdp多媒体会话协议报文详细解读
  • 深入理解 C# Razor Pages:构建现代 Web 应用的利器
  • 蓝桥杯 k倍区间
  • JsonCpp 库如何集成到Visual studio
  • 报名召集:香港科技大学(广州)智能交通学域2025年博士项目夏令营
  • Go语言学习-->编译器安装
  • 国标GB/T 28035:验收规范解读
  • 十.显式类型转换
  • 转战web3远程工作的英语学习的路线规划
  • 《前端面试题:CSS动画全面解析》
  • 机器学习在多介质环境中多污染物空间预测的应用研究