静态资源处理
静态资源处理
- 相关:构建基础路径
- 相关:
assetsInclude配置项
将资源导入为 URL
导入静态资源会返回解析后的公共 URL 以供使用:
js twoslash
import 'vite/client'
// ---cut---
import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl
例如,imgUrl 在开发环境会是 /src/img.png,在生产构建中会变成 /assets/img.2d8efhg.png。
其行为类似于 webpack 的 file-loader。区别在于导入既可以使用绝对公共路径(开发时基于项目根目录),也可以使用相对路径。
- CSS 中的
url()引用以相同方式处理。 - 如果使用 Vue 插件,Vue SFC 模板中的资源引用会自动转换为导入。
- 常见的图片、媒体和字体文件类型会自动被识别为资源。你可以使用
assetsInclude选项 扩展内部列表。 - 被引用的资源会作为构建资源图的一部分,获得哈希文件名,并可被插件用于优化处理。
- 小于
assetsInlineLimit选项 字节的资源会被内联为 Base64 数据 URL。 - Git LFS 占位符会自动排除在内联之外,因为它们不包含所代表文件的内容。如需内联,请确保在构建前通过 Git LFS 下载文件内容。
- 默认情况下,TypeScript 不会将静态资源导入识别为有效模块。要解决此问题,请引入
vite/client。
::: tip 通过 url() 内联 SVG
当通过 JS 手动构造 url() 并传入 SVG 的 URL 时,变量需要用双引号包裹。
js twoslash
import 'vite/client'
// ---cut---
import imgUrl from './img.svg'
document.getElementById('hero-img').style.background = `url("${imgUrl}")`
显式 URL 导入
内部列表或
assetsInclude中未包含的资源,可以使用?url后缀显式导入为 URL。例如,这在导入 Houdini Paint Worklets 时非常有用。
js twoslashimport 'vite/client' // ---cut--- import workletURL from 'extra-scalloped-border/worklet.js?url' CSS.paintWorklet.addModule(workletURL)显式内联处理
资源可以使用
?inline或?no-inline后缀分别显式导入为内联或非内联。
js twoslashimport 'vite/client' // ---cut--- import imgUrl1 from './img.svg?no-inline' import imgUrl2 from './img.png?inline'将资源导入为字符串
资源可以使用
?raw后缀导入为字符串。
js twoslashimport 'vite/client' // ---cut--- import shaderString from './shader.glsl?raw'将脚本导入为 Worker
脚本可以使用
?worker或?sharedworker后缀导入为 Web Worker。
js twoslashimport 'vite/client' // ---cut--- // 生产构建中的独立 chunk import Worker from './shader.js?worker' const worker = new Worker()
js twoslashimport 'vite/client' // ---cut--- // sharedworker import SharedWorker from './shader.js?sharedworker' const sharedWorker = new SharedWorker()
js twoslashimport 'vite/client' // ---cut--- // 内联为 Base64 字符串 import InlineWorker from './shader.js?worker&inline'查看 Web Worker 部分 了解更多详情。
public目录如果你有以下资源:
- 在源代码中从未被引用(例如
robots.txt)- 必须保持完全相同的文件名(不进行哈希)
- ……或者你只是不想为了获取 URL 而先导入资源
那么你可以将资源放在项目根目录下的专用
public目录中。此目录中的资源在开发环境中会以根路径/提供服务,并原样复制到 dist 目录的根目录。该目录默认为
<root>/public,但可以通过publicDir选项 进行配置。注意,你应始终使用根绝对路径来引用
public资源——例如,public/icon.png在源代码中应引用为/icon.png。 tip 在导入和public目录之间做选择
一般而言,除非你确实需要 public 目录提供的保证,否则请优先导入资源。
new URL(url, import.meta.url)
import.meta.url 是一个原生 ESM 特性,用于暴露当前模块的 URL。将其与原生 URL 构造函数 结合,我们可以使用来自 JavaScript 模块的相对路径获取静态资源的完整解析后 URL:
jsconst imgUrl = new URL('./img.png', import.meta.url).href document.getElementById('hero-img').src = imgUrl这在现代浏览器中可以原生运行——实际上,Vite 在开发环境中完全不需要处理这段代码!
此模式还支持通过模板字符串创建动态 URL:
jsfunction getImageUrl(name) { // 注意:这不包含子目录中的文件 return new URL(`./dir/${name}.png`, import.meta.url).href }在生产构建期间,Vite 会执行必要的转换,以便即使在打包和资源哈希之后,URL 仍然指向正确的位置。但是,URL 字符串必须是静态的才能被分析,否则代码将保持原样,如果
build.target不支持import.meta.url,可能会导致运行时错误。
js// Vite 不会转换此代码 const imgUrl = new URL(imagePath, import.meta.url).href ``` details 工作原理
Vite 会将 getImageUrl 函数转换为:
js
import __img0png from './dir/img0.png'
import __img1png from './dir/img1.png'
function getImageUrl(name) {
const modules = {
'./dir/img0.png': __img0png,
'./dir/img1.png': __img1png,
}
return new URL(modules[`./dir/${name}.png`], import.meta.url).href
}
::: warning 不适用于 SSR
此模式不适用于使用 Vite 进行服务端渲染(SSR)的情况,因为import.meta.url在浏览器和 Node.js 中具有不同的语义。服务端 bundle 也无法提前确定客户端主机 URL。
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
