静态资源处理
- 相关内容:公共基础路径
- 相关内容:
assetsInclude配置项
将资源导入为 URL
当导入一个静态资源时,它将返回解析后的公共 URL:
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。
通过 url() 内联 SVG
当将 SVG 的 URL 传递给通过 JS 手动构建的 url() 时,该变量应包裹在双引号中。
import imgUrl from './img.svg'
document.getElementById('hero-img').style.background = `url("${imgUrl}")`显式 URL 导入
未包含在内部列表或 assetsInclude 中的资源,可以使用 ?url 后缀显式导入为 URL。这对于导入 Houdini Paint Worklets 等情况非常有用。
import workletURL from 'extra-scalloped-border/worklet.js?url'
CSS.paintWorklet.addModule(workletURL)显式内联处理
资源可以使用 ?inline 或 ?no-inline 后缀来显式指定进行内联或不进行内联。
import imgUrl1 from './img.svg?no-inline'
import imgUrl2 from './img.png?inline'将资源导入为字符串
资源可以使用 ?raw 后缀导入为字符串。
import shaderString from './shader.glsl?raw'将脚本导入为 Worker
脚本可以使用 ?worker 或 ?sharedworker 后缀导入为 Web Worker。
// Separate chunk in the production build
import Worker from './shader.js?worker'
const worker = new Worker()// sharedworker
import SharedWorker from './shader.js?sharedworker'
const sharedWorker = new SharedWorker()// Inlined as base64 strings
import InlineWorker from './shader.js?worker&inline'查看 Web Worker 章节 以获取更多详细信息。
public 目录
如果你有以下资源:
- 永远不会在源代码中被引用(例如
robots.txt) - 必须保留完全相同的文件名(不进行哈希处理)
- ...或者你只是不想为了获取 URL 而先导入资源
那么你可以将资源放在项目根目录下的特殊 public 目录中。该目录中的资源在开发时会在根路径 / 提供,并在生产构建时原样复制到 dist 目录的根目录下。
该目录默认为 <root>/public,但可以通过 publicDir 选项 进行配置。
注意,你应该始终使用根绝对路径引用 public 资源——例如,public/icon.png 应在源代码中引用为 /icon.png。
在导入和 public 目录之间进行选择
通常情况下,除非特别需要 public 目录提供的保证,否则建议优先使用导入资源。
new URL(url, import.meta.url)
import.meta.url 是一个原生 ESM 功能,它暴露了当前模块的 URL。将其与原生的 URL 构造函数结合使用,我们可以利用 JavaScript 模块的相对路径获取静态资源的完整解析 URL。
const imgUrl = new URL('./img.png', import.meta.url).href
document.getElementById('hero-img').src = imgUrl这在现代浏览器中原生支持——事实上,Vite 在开发过程中完全不需要处理这段代码!
此模式还支持通过模板字符串使用动态 URL。
function getImageUrl(name) {
// note that this does not include files in subdirectories
return new URL(`./dir/${name}.png`, import.meta.url).href
}在生产构建期间,Vite 将执行必要的转换,以便在打包和资源哈希处理后,URL 仍然指向正确的位置。但是,URL 字符串必须是静态的以便于分析,否则代码将保持原样,如果 build.target 不支持 import.meta.url,这可能会导致运行时错误。
// Vite will not transform this
const imgUrl = new URL(imagePath, import.meta.url).href工作原理
Vite 会将 getImageUrl 函数转换为:
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
}不支持 SSR
如果你正在使用 Vite 进行服务端渲染(SSR),此模式将无法工作,因为 import.meta.url 在浏览器和 Node.js 中的语义不同。服务器 bundle 也无法预先确定客户端的主机 URL。
