跳轉到內容

靜態資源處理

將資源匯入為 URL

當匯入一個靜態資源時,它將返回解析後的公共 URL:

js
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() 時,該變數應包裹在雙引號中。

js
import 
imgUrl
from './img.svg'
document
.
getElementById
('hero-img').
style
.
background
= `url("${
imgUrl
}")`

顯式 URL 匯入

未包含在內部列表或 assetsInclude 中的資源,可以使用 ?url 字尾顯式匯入為 URL。這對於匯入 Houdini Paint Worklets 等情況非常有用。

js
import 
workletURL
from 'extra-scalloped-border/worklet.js?url'
CSS.paintWorklet.addModule(
workletURL
)

顯式內聯處理

資源可以使用 ?inline?no-inline 字尾來顯式指定進行內聯或不進行內聯。

js
import 
imgUrl1
from './img.svg?no-inline'
import
imgUrl2
from './img.png?inline'

將資源匯入為字串

資源可以使用 ?raw 字尾匯入為字串。

js
import 
shaderString
from './shader.glsl?raw'

將指令碼匯入為 Worker

指令碼可以使用 ?worker?sharedworker 字尾匯入為 Web Worker。

js
// Separate chunk in the production build
import 
Worker
from './shader.js?worker'
const
worker
= new
Worker
()
js
// sharedworker
import 
SharedWorker
from './shader.js?sharedworker'
const
sharedWorker
= new
SharedWorker
()
js
// 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。

js
const imgUrl = new URL('./img.png', import.meta.url).href

document.getElementById('hero-img').src = imgUrl

這在現代瀏覽器中原生支援——事實上,Vite 在開發過程中完全不需要處理這段程式碼!

此模式還支援透過模板字串使用動態 URL。

js
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,這可能會導致執行時錯誤。

js
// Vite will not transform this
const imgUrl = new URL(imagePath, import.meta.url).href
工作原理

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
}

不支援 SSR

如果你正在使用 Vite 進行服務端渲染(SSR),此模式將無法工作,因為 import.meta.url 在瀏覽器和 Node.js 中的語義不同。伺服器 bundle 也無法預先確定客戶端的主機 URL。