静态资源处理
约 676 字大约 2 分钟
2026-02-25
Vite 会把静态资源当作模块图的一部分处理。你在代码里 import 图片、字体、媒体文件时,开发阶段会返回可访问 URL,构建阶段会输出带 hash 的文件名并自动替换引用。
常见引入方式
先看总览,避免一上来就把所有资源都丢进 public 目录。
| 方式 | 示例 | 适用场景 | 说明 |
|---|---|---|---|
| 模块导入 | import logo from './logo.png' | 组件内资源 | 参与构建,自动 hash,支持缓存策略 |
new URL | new URL('./logo.png', import.meta.url).href | 动态拼接资源路径 | 适合按条件拼资源文件 |
public 目录 | '/favicon.ico' | 不需要构建处理的固定文件 | 不会被 hash,按原名输出 |
| 查询后缀 | ?url / ?raw / ?inline | 需要精细控制导入结果 | 明确指定导入后的数据形态 |
查询后缀与导入结果
这部分是最常见也最容易混淆的点。下面用代码直观看结果类型。
URL / 文本 / 内联
// 1) 默认:导入 URL(开发期是 dev URL,构建后是 hash 文件 URL)
import logoUrl from './assets/logo.svg'
// 2) 强制 URL 字符串
import bgUrl from './assets/background.png?url'
// 3) 原始文本内容(适合导入着色器、svg 源码、模板片段)
import shaderSource from './shader.glsl?raw'
// 4) 强制 base64 内联到 JS
import inlineIcon from './assets/icon.svg?inline'
// 5) 即使小于阈值也不要内联,保持独立文件
import noInlineIcon from './assets/icon.svg?no-inline'
console.log({ logoUrl, bgUrl, shaderSource, inlineIcon, noInlineIcon })Worker 资源
// 作为 Worker 构建与加载
import MyWorker from './worker.ts?worker'
const worker = new MyWorker()
worker.postMessage({ type: 'ping' })使用注意
?raw返回的是字符串,不会被当脚本执行。?inline会增大 JS 体积,适合很小且高频资源。- 资源是否自动内联还受
build.assetsInlineLimit影响。
public 目录该怎么用
public 适合“必须固定文件名且无需构建处理”的资源,例如 favicon.ico、robots.txt、第三方验证文件。
project-root
├─ public
│ ├─ favicon.ico
│ └─ robots.txt
└─ src<!-- 直接从站点根路径访问 -->
<link rel="icon" href="/favicon.ico" />如果资源需要 hash、按需加载、长期缓存控制,优先放在 src 后通过模块导入处理。
new URL(..., import.meta.url) 场景
当资源路径需要在运行时根据规则选择时,new URL 比硬编码字符串更安全。
const theme = Math.random() > 0.5 ? 'dark' : 'light'
const avatarUrl = new URL(`./assets/avatar-${theme}.png`, import.meta.url).href
const img = document.createElement('img')
img.src = avatarUrl
document.body.appendChild(img)SSR 场景提醒
new URL(..., import.meta.url) 在纯浏览器场景很稳定。涉及 SSR 时,建议先在目标框架里验证构建产物与服务端路径映射,避免服务端与客户端 URL 基准不一致。
