跳轉到內容

功能

最基礎的層面下,使用 Vite 進行開發與使用靜態檔案伺服器沒有什麼不同。然而,Vite 針對原生 ESM 匯入提供了許多增強功能,以支援各種在基於打包器的設定中常見的功能。

npm 依賴解析和預構建

原生 ES 匯入不支援如下形式的裸模組匯入:

js
import { someMethod } from 'my-dep'

上述匯入在瀏覽器中會報錯。Vite 會檢測到所有已提供原始碼檔案中的此類裸模組匯入,並執行以下操作:

  1. 預構建 (Pre-bundle):提升頁面載入速度,並將 CommonJS / UMD 模組轉換為 ESM。預構建步驟使用 esbuild 執行,這使得 Vite 的冷啟動速度遠快於任何基於 JavaScript 的打包器。

  2. 重寫匯入路徑:將匯入重寫為有效的 URL,例如 /node_modules/.vite/deps/my-dep.js?v=f3sf2ebd,以便瀏覽器能夠正確匯入它們。

依賴強快取

Vite 透過 HTTP 頭快取依賴請求,如果你想在本地編輯或除錯依賴,請參考此處的步驟。

模組熱替換 (HMR)

Vite 在原生 ESM 之上提供了 HMR API。具有 HMR 功能的框架可以利用該 API 提供即時、精確的更新,而無需重新載入頁面或清除應用程式狀態。Vite 為 Vue 單檔案元件React Fast Refresh 提供了第一方的 HMR 整合。此外,還有透過 @prefresh/vite 實現的 Preact 官方整合。

請注意,你不需要手動設定這些功能——當你透過 create-vite 建立應用時,所選模板已為你預先配置好了。

TypeScript

Vite 開箱即支援匯入 .ts 檔案。

僅轉譯 (Transpile Only)

請注意,Vite 僅對 .ts 檔案進行轉譯,**不會**執行型別檢查。它預設型別檢查由 IDE 和構建過程處理。

Vite 不在轉換過程中執行型別檢查的原因是兩者的工作方式存在根本差異。轉譯可以在單檔案基礎上進行,這與 Vite 的按需編譯模式完美契合。相比之下,型別檢查需要了解整個模組圖。將型別檢查強行植入 Vite 的轉換管道將不可避免地犧牲 Vite 的速度優勢。

Vite 的任務是儘可能快地將源模組轉換為能在瀏覽器中執行的形式。因此,我們建議將靜態分析檢查與 Vite 的轉換管道分離開來。這一原則同樣適用於 ESLint 等其他靜態分析檢查。

  • 對於生產構建,你可以在執行 Vite 構建命令的同時執行 tsc --noEmit

  • 在開發過程中,如果你需要 IDE 提示之外的檢查,我們建議在單獨的程序中執行 tsc --noEmit --watch,或者如果希望在瀏覽器中直接看到型別錯誤,可以使用 vite-plugin-checker

Vite 使用 esbuild 將 TypeScript 轉譯為 JavaScript,速度比原生 tsc 快約 20~30 倍,且 HMR 更新可在 50 毫秒內反映到瀏覽器中。

使用 僅型別匯入和匯出 (Type-Only Imports and Export) 語法以避免潛在問題(例如僅型別的匯入被錯誤地打包),例如:

ts
import type { T } from 'only/types'
export type { T }

TypeScript 編譯器選項

Vite 會遵守 tsconfig.json 中的部分選項,並設定相應的 esbuild 選項。對於每個檔案,Vite 使用離其最近的父目錄中的 tsconfig.json。如果該 tsconfig.json 包含 references 欄位,Vite 將使用滿足 includeexclude 欄位的被引用配置檔案。

當選項在 Vite 配置和 tsconfig.json 中同時設定時,Vite 配置中的值具有更高優先順序。

tsconfig.jsoncompilerOptions 下的某些配置欄位需要特別注意。

isolatedModules

應設定為 true

這是因為 esbuild 僅執行轉譯且不具備型別資訊,它不支援 const enum 和隱式僅型別匯入等特定功能。

你必須在 tsconfig.jsoncompilerOptions 下設定 "isolatedModules": true,這樣 TS 就會對那些無法在獨立轉譯下正常工作的功能發出警告。

如果某個依賴無法很好地處理 "isolatedModules": true,你可以暫時設定 "skipLibCheck": true 來抑制錯誤,直到該問題在上方遊得到修復。

useDefineForClassFields

如果 TypeScript 目標版本為 ES2022 或更高(包括 ESNext),其預設值將為 true。這與 TypeScript 4.3.2+ 的行為一致。其他 TypeScript 目標版本預設為 false

true 是標準的 ECMAScript 執行時行為。

如果你使用的庫嚴重依賴類欄位(class fields),請注意該庫的預期用法。雖然大多數庫都期望 "useDefineForClassFields": true,但如果你的庫不支援,你可以明確地將 useDefineForClassFields 設定為 false

target

Vite 會忽略 tsconfig.json 中的 target 值,遵循與 esbuild 相同的行為。

要在開發環境中指定目標,可以使用 esbuild.target 選項,其預設值為 esnext(以進行最小化轉譯)。在構建時,build.target 選項的優先順序高於 esbuild.target,也可以根據需要進行設定。

emitDecoratorMetadata

此選項僅得到部分支援。完全支援需要 TypeScript 編譯器進行型別推斷,而目前不支援。詳情請參閱 Oxc Transformer 文件

paths

可以指定 resolve.tsconfigPaths: true 來告訴 Vite 使用 tsconfig.json 中的 paths 選項來解析匯入。

請注意,此功能有效能損耗,且 TypeScript 團隊不建議使用此選項來改變外部工具的行為

影響構建結果的其他編譯器選項

skipLibCheck

Vite 入門模板預設將 "skipLibCheck": "true" 設定為開啟,以避免對依賴項進行型別檢查,因為它們可能只選擇支援特定的 TypeScript 版本和配置。瞭解更多資訊請見 vuejs/vue-cli#5688

客戶端型別

Vite 的預設型別是針對其 Node.js API 的。若要為 Vite 應用中的客戶端程式碼進行環境填充(shim),可以在 tsconfig.json 中的 compilerOptions.types 新增 vite/client

tsconfig.json
json
{
  "compilerOptions": {
    "types": ["vite/client", "some-other-global-lib"]
  }
}

注意,如果指定了 compilerOptions.types,則只有這些包會被包含在全域性作用域中(而不是所有可見的 ”@types” 包)。自 TS 5.9 起,推薦這樣做。

使用三斜槓指令 (Triple-slash directive)

或者,你可以新增一個 d.ts 宣告檔案:

vite-env.d.ts
typescript
/// <reference types="vite/client" />

vite/client 提供了以下型別填充:

  • 資源匯入(例如匯入 .svg 檔案)
  • import.meta.env 上 Vite 注入的 常量 型別
  • import.meta.hotHMR API 的型別

提示

若要覆蓋預設型別,請新增包含你自定義型別的型別定義檔案,然後在 vite/client 之前新增型別引用。

例如,要將 *.svg 的預設匯入改為 React 元件:

  • vite-env-override.d.ts(包含你型別定義的檔案)
    ts
    declare module '*.svg' {
      const content: React.FC<React.SVGProps<SVGElement>>
      export default content
    }
  • 如果你正在使用 compilerOptions.types,請確保該檔案已包含在 tsconfig.json 中。
    tsconfig.json
    json
    {
      "include": ["src", "./vite-env-override.d.ts"]
    }
  • 如果你正在使用三斜槓指令,請更新包含 vite/client 引用的檔案(通常是 vite-env.d.ts)。
    ts
    /// <reference types="./vite-env-override.d.ts" />
    /// <reference types="vite/client" />

HTML

HTML 檔案在 Vite 專案中處於核心位置,作為應用程式的入口點,使得構建單頁應用和多頁應用變得簡單。

專案根目錄下的任何 HTML 檔案都可以透過其對應的目錄路徑直接訪問:

  • <root>/index.html -> https://:5173/
  • <root>/about.html -> https://:5173/about.html
  • <root>/blog/index.html -> https://:5173/blog/index.html

由 HTML 元素(如 <script type="module" src><link href>)引用的資源會被處理並打包作為應用的一部分。以下是支援的完整元素列表:

  • <audio src>
  • <embed src>
  • <img src><img srcset>
  • <image href><image xlink:href>
  • <input src>
  • <link href><link imagesrcset>
  • <object data>
  • <script type="module" src>
  • <source src><source srcset>
  • <track src>
  • <use href><use xlink:href>
  • <video src><video poster>
  • <meta content>
    • 僅當 name 屬性匹配 msapplication-tileimagemsapplication-square70x70logomsapplication-square150x150logomsapplication-wide310x150logomsapplication-square310x310logomsapplication-configtwitter:image 時。
    • 或者僅當 property 屬性匹配 og:imageog:image:urlog:image:secure_urlog:audioog:audio:secure_urlog:videoog:video:secure_url 時。
html
<!doctype html>
<html>
  <head>
    <link rel="icon" href="/favicon.ico" />
    <link rel="stylesheet" href="/src/styles.css" />
  </head>
  <body>
    <img src="/src/images/logo.svg" alt="logo" />
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

要對某些元素停用 HTML 處理,可以新增 vite-ignore 屬性,這在引用外部資源或 CDN 時非常有用。

框架

所有現代框架都與 Vite 保持著整合。大多數框架外掛由各自的框架團隊維護,Vue 和 React 的官方 Vite 外掛除外,它們由 vite 組織維護。

檢視 外掛指南 以獲取更多資訊。

JSX

.jsx.tsx 檔案也開箱即支援。JSX 轉譯同樣透過 esbuild 處理。

你所選的框架將預設配置好 JSX(例如,Vue 使用者應使用官方的 @vitejs/plugin-vue-jsx 外掛,它提供了 Vue 3 特定的功能,包括 HMR、全域性元件解析、指令和插槽)。

如果在使用自定義框架時使用 JSX,可以使用 esbuild 選項配置自定義 jsxFactoryjsxFragment。例如,Preact 外掛會使用:

vite.config.js
js
import { 
defineConfig
} from 'vite'
export default
defineConfig
({
esbuild
: {
jsxFactory
: 'h',
jsxFragment
: 'Fragment',
}, })

更多詳情請檢視 esbuild 文件

你可以使用 jsxInject(這是一個 Vite 特有選項)注入 JSX 輔助程式,從而避免手動匯入。

vite.config.js
js
import { 
defineConfig
} from 'vite'
export default
defineConfig
({
esbuild
: {
jsxInject
: `import React from 'react'`,
}, })

CSS

匯入 .css 檔案將透過帶有 HMR 支援的 <style> 標籤將內容注入頁面。

@import 內聯與重定位

Vite 預配置了透過 postcss-import 支援 CSS @import 內聯。Vite 別名在 CSS @import 中同樣適用。此外,所有的 CSS url() 引用,即使匯入的檔案處於不同目錄,也會自動重定位,以確保引用正確。

Sass 和 Less 檔案也支援 @import 別名和 URL 重定位(參見 CSS 預處理器)。

PostCSS

如果專案包含有效的 PostCSS 配置(任何 postcss-load-config 支援的格式,如 postcss.config.js),它將自動應用於所有匯入的 CSS。

注意,CSS 壓縮將在 PostCSS 之後執行,並使用 build.cssTarget 選項。

CSS Modules

任何以 .module.css 結尾的 CSS 檔案都被視為 CSS modules 檔案。匯入此類檔案將返回對應的模組物件:

example.module.css
css
.red {
  color: red;
}
js
import 
classes
from './example.module.css'
document
.
getElementById
('foo').
className
=
classes
.
red

CSS modules 行為可以透過 css.modules 選項進行配置。

如果設定 css.modules.localsConvention 以啟用 camelCase locals(例如 localsConvention: 'camelCaseOnly'),你也可以使用具名匯入。

js
// .apply-color -> applyColor
import { 
applyColor
} from './example.module.css'
document
.
getElementById
('foo').
className
=
applyColor

CSS 預處理器

由於 Vite 僅針對現代瀏覽器,建議使用原生 CSS 變數配合實現 CSSWG 草案的 PostCSS 外掛(如 postcss-nesting),並編寫標準的、符合未來標準的 CSS。

儘管如此,Vite 確實提供了對 .scss.sass.less.styl.stylus 檔案的內建支援。無需安裝特定的 Vite 外掛,但必須安裝相應的預處理器本身:

bash
# .scss and .sass
npm add -D sass-embedded # or sass

# .less
npm add -D less

# .styl and .stylus
npm add -D stylus

如果使用 Vue 單檔案元件,這也將自動啟用 <style lang="sass"> 等功能。

Vite 改進了 Sass 和 Less 的 @import 解析,以便 Vite 別名也能生效。此外,匯入的 Sass/Less 檔案內與根檔案不在同一目錄的相對 url() 引用也會自動重定位,以確保準確性。由於 API 限制,不支援重定位以變數或插值開頭的 url() 引用。

由於 Stylus 的 API 限制,不支援 @import 別名和 URL 重定位。

你也可以透過在副檔名前新增 .module 來結合使用 CSS modules 和預處理器,例如 style.module.scss

停用 CSS 注入頁面

可以透過 ?inline 查詢引數關閉 CSS 內容的自動注入。在這種情況下,處理後的 CSS 字串將像往常一樣作為模組的預設匯出返回,但樣式不會注入到頁面中。

js
import './foo.css' // will be injected into the page
import 
otherStyles
from './bar.css?inline' // will not be injected

注意

從 Vite 5 開始,已移除從 CSS 檔案進行的預設匯入和具名匯入(例如 import style from './foo.css')。請改為使用 ?inline 查詢。

Lightning CSS

從 Vite 4.4 開始,實驗性支援 Lightning CSS。你可以透過在配置檔案中新增 css.transformer: 'lightningcss' 並安裝可選的 lightningcss 依賴來選擇使用它。

bash
npm add -D lightningcss

如果啟用,CSS 檔案將由 Lightning CSS 而非 PostCSS 處理。要進行配置,可以將 Lightning CSS 選項傳遞給 css.lightningcss 配置選項。

要配置 CSS Modules,請使用 css.lightningcss.cssModules 而不是 css.modules(後者配置的是 PostCSS 處理 CSS modules 的方式)。

預設情況下,Vite 使用 esbuild 來壓縮 CSS。Lightning CSS 也可以作為 CSS 壓縮器使用,配置為 build.cssMinify: 'lightningcss'

靜態資源

匯入靜態資源將返回其被提供時的已解析公共 URL。

js
import 
imgUrl
from './img.png'
document
.
getElementById
('hero-img').src =
imgUrl

特殊查詢可以修改資源的載入方式。

js
// Explicitly load assets as URL (automatically inlined depending on the file size)
import 
assetAsURL
from './asset.js?url'
js
// Load assets as strings
import 
assetAsString
from './shader.glsl?raw'
js
// Load Web Workers
import 
Worker
from './worker.js?worker'
js
// Web Workers inlined as base64 strings at build time
import 
InlineWorker
from './worker.js?worker&inline'

更多詳情請見 靜態資源處理

JSON

JSON 檔案可以直接匯入——也支援具名匯入。

js
// import the entire object
import 
json
from './example.json'
// import a root field as named exports - helps with tree-shaking! import {
field
} from './example.json'

Glob 匯入

Vite 支援透過特殊的 import.meta.glob 函式從檔案系統匯入多個模組。

js
const 
modules
= import.meta.
glob
('./dir/*.js')

以上程式碼將被轉換為以下形式:

js
// code produced by vite
const modules = {
  './dir/bar.js': () => import('./dir/bar.js'),
  './dir/foo.js': () => import('./dir/foo.js'),
}

然後你可以遍歷 modules 物件的鍵來訪問相應的模組。

js
for (const path in modules) {
  modules[path]().then((mod) => {
    console.log(path, mod)
  })
}

匹配到的檔案預設透過動態匯入進行懶載入,並在構建時拆分為單獨的塊。如果你希望直接匯入所有模組(例如依賴這些模組中的副作用先執行),可以將 { eager: true } 作為第二個引數傳入。

js
const 
modules
= import.meta.
glob
('./dir/*.js', {
eager
: true })

以上程式碼將被轉換為以下形式:

js
// code produced by vite
import * as __vite_glob_0_0 from './dir/bar.js'
import * as __vite_glob_0_1 from './dir/foo.js'
const modules = {
  './dir/bar.js': __vite_glob_0_0,
  './dir/foo.js': __vite_glob_0_1,
}

多個模式

第一個引數可以是一個 glob 陣列,例如:

js
const 
modules
= import.meta.
glob
(['./dir/*.js', './another/*.js'])

否定模式

同樣支援否定 glob 模式(以 ! 開頭)。要從結果中排除某些檔案,可以將排除的 glob 模式新增到第一個引數中。

js
const 
modules
= import.meta.
glob
(['./dir/*.js', '!**/bar.js'])
js
// code produced by vite
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
}

具名匯入

可以使用 import 選項僅匯入模組的部分內容。

ts
const 
modules
= import.meta.
glob
('./dir/*.js', {
import
: 'setup' })
ts
// code produced by vite
const modules = {
  './dir/bar.js': () => import('./dir/bar.js').then((m) => m.setup),
  './dir/foo.js': () => import('./dir/foo.js').then((m) => m.setup),
}

當與 eager 結合使用時,甚至可以對這些模組啟用 Tree-shaking。

ts
const 
modules
= import.meta.
glob
('./dir/*.js', {
import
: 'setup',
eager
: true,
})
ts
// code produced by vite:
import { setup as __vite_glob_0_0 } from './dir/bar.js'
import { setup as __vite_glob_0_1 } from './dir/foo.js'
const modules = {
  './dir/bar.js': __vite_glob_0_0,
  './dir/foo.js': __vite_glob_0_1,
}

設定 importdefault 可匯入預設匯出。

ts
const 
modules
= import.meta.
glob
('./dir/*.js', {
import
: 'default',
eager
: true,
})
ts
// code produced by vite:
import { default as __vite_glob_0_0 } from './dir/bar.js'
import { default as __vite_glob_0_1 } from './dir/foo.js'
const modules = {
  './dir/bar.js': __vite_glob_0_0,
  './dir/foo.js': __vite_glob_0_1,
}

自定義查詢

你也可以使用 query 選項為匯入提供查詢,例如將資源匯入為字串為 URL

ts
const 
moduleStrings
= import.meta.
glob
('./dir/*.svg', {
query
: '?raw',
import
: 'default',
}) const
moduleUrls
= import.meta.
glob
('./dir/*.svg', {
query
: '?url',
import
: 'default',
})
ts
// code produced by vite:
const moduleStrings = {
  './dir/bar.svg': () => import('./dir/bar.svg?raw').then((m) => m['default']),
  './dir/foo.svg': () => import('./dir/foo.svg?raw').then((m) => m['default']),
}
const moduleUrls = {
  './dir/bar.svg': () => import('./dir/bar.svg?url').then((m) => m['default']),
  './dir/foo.svg': () => import('./dir/foo.svg?url').then((m) => m['default']),
}

你也可以提供自定義查詢供其他外掛使用。

ts
const 
modules
= import.meta.
glob
('./dir/*.js', {
query
: {
foo
: 'bar',
bar
: true },
})

基礎路徑

你也可以使用 base 選項為匯入提供基礎路徑。

ts
const 
modulesWithBase
= import.meta.
glob
('./**/*.js', {
base
: './base',
})
ts
// code produced by vite:
const modulesWithBase = {
  './dir/foo.js': () => import('./base/dir/foo.js'),
  './dir/bar.js': () => import('./base/dir/bar.js'),
}

base 選項只能是相對於匯入者檔案的目錄路徑或相對於專案根目錄的絕對路徑。不支援別名和虛擬模組。

只有作為相對路徑的 glob 才會被解釋為相對於已解析的 base。

如果提供了 base,所有結果模組的鍵都會被修改為相對於該 base。

Glob 匯入注意事項

請注意:

  • 這是 Vite 特有的功能,不是 Web 或 ES 標準。
  • Glob 模式被視為匯入說明符:它們必須是相對的(以 ./ 開頭)、絕對的(以 / 開頭,解析為相對於專案根目錄)或別名路徑(參見 resolve.alias 選項)。
  • Glob 匹配透過 tinyglobby 完成——請查閱其文件瞭解支援的 glob 模式
  • 還要注意,import.meta.glob 中的所有引數必須作為字面量傳遞。你不能在其中使用變數或表示式。

動態匯入

類似於 glob 匯入,Vite 也支援變數的動態匯入。

ts
const module = await import(`./dir/${file}.js`)

注意,變數僅代表一級深度的檔名。如果 file'foo/bar',匯入將會失敗。更多高階用法,可以使用 glob 匯入功能。

還要注意,動態匯入必須符合以下規則才能被打包:

  • 匯入必須以 ./../ 開頭:import(`./dir/${foo}.js`) 是有效的,但 import(`${foo}.js`) 是無效的。
  • 匯入必須以副檔名結尾:import(`./dir/${foo}.js`) 是有效的,但 import(`./dir/${foo}`) 是無效的。
  • 匯入自身目錄必須指定檔名模式:import(`./prefix-${foo}.js`) 是有效的,但 import(`./${foo}.js`) 是無效的。

強制執行這些規則是為了防止意外匯入非預期的打包檔案。例如,如果沒有這些規則,import(foo) 會打包檔案系統中的所有內容。

WebAssembly

預編譯的 .wasm 檔案可以使用 ?init 匯入。預設匯出將是一個初始化函式,返回一個 WebAssembly.Instance 的 Promise。

js
import 
init
from './example.wasm?init'
init
().
then
((
instance
) => {
instance
.
exports
.
test
()
})

初始化函式還可以接收一個 importObject,該物件作為第二個引數傳遞給 WebAssembly.instantiate

js
init
({
imports
: {
someFunc
: () => {
/* ... */ }, }, }).
then
(() => {
/* ... */ })

在生產構建中,小於 assetInlineLimit.wasm 檔案將被內聯為 base64 字串。否則,它們將被視為靜態資源並在需要時獲取。

注意

目前不支援 WebAssembly 的 ES 模組整合提案。請使用 vite-plugin-wasm 或其他社群外掛來處理此需求。

對於 SSR 構建,僅支援 Node.js 相容的執行時。

由於缺乏一種通用的載入檔案方法,.wasm?init 的內部實現依賴於 node:fs 模組。這意味著該功能在 SSR 構建中僅適用於 Node.js 相容的執行時。

訪問 WebAssembly 模組

如果你需要訪問 Module 物件(例如為了多次例項化它),請使用顯式 URL 匯入來解析資源,然後進行例項化。

js
import 
wasmUrl
from 'foo.wasm?url'
const
main
= async () => {
const
responsePromise
=
fetch
(
wasmUrl
)
const {
module
,
instance
} =
await WebAssembly.
instantiateStreaming
(
responsePromise
)
/* ... */ }
main
()

Web Workers

使用建構函式匯入

Web worker 指令碼可以使用 new Worker()new SharedWorker() 進行匯入。相比 worker 字尾,這種語法更接近標準,是建立 worker 的推薦方式。

ts
const worker = new Worker(new URL('./worker.js', import.meta.url))

Worker 建構函式也接受選項,可用於建立“模組化”worker:

ts
const worker = new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
})

只有當 new URL() 建構函式直接用於 new Worker() 宣告內時,worker 檢測才會生效。此外,所有選項引數必須是靜態值(即字串字面量)。

使用查詢字尾匯入

透過在匯入請求後附加 ?worker?sharedworker,可以直接匯入 Web worker 指令碼。預設匯出將是一個自定義 worker 建構函式:

js
import 
MyWorker
from './worker?worker'
const
worker
= new
MyWorker
()

Worker 指令碼也可以使用 ESM import 語句而不是 importScripts()注意:在開發階段,這依賴於瀏覽器原生支援,但在生產構建中,它會被編譯掉。

預設情況下,worker 指令碼將在生產構建中作為單獨的 chunk 輸出。如果你希望將 worker 內聯為 base64 字串,請新增 inline 查詢:

js
import 
MyWorker
from './worker?worker&inline'

如果你希望將 worker 作為 URL 獲取,請新增 url 查詢:

js
import 
MyWorker
from './worker?worker&url'

有關配置所有 worker 打包的詳細資訊,請參閱 Worker 選項

內容安全策略 (CSP)

為了部署 CSP,由於 Vite 的內部機制,必須設定某些指令或配置。

'nonce-{RANDOM}'

當設定了 html.cspNonce 時,Vite 會為任何 <script><style> 標籤,以及用於樣式表和模組預載入的 <link> 標籤新增帶有指定值的 nonce 屬性。此外,設定此選項後,Vite 將注入一個 meta 標籤(<meta property="csp-nonce" nonce="PLACEHOLDER" />)。

無論是在開發過程中還是構建後,Vite 在必要時都會使用 property="csp-nonce" 的 meta 標籤中的 nonce 值。

警告

確保每次請求都將佔位符替換為唯一值。這一點至關重要,否則極易繞過資源的安全策略。

data:

預設情況下,在構建期間,Vite 會將小資源內聯為資料 URI。因此,必須為相關指令(如 img-srcfont-src)允許 data:,或者透過設定 build.assetsInlineLimit: 0 來停用它。

警告

請勿為 script-src 允許 data:,這將允許注入任意指令碼。

許可證

Vite 可以使用 build.license 選項生成構建中使用的所有依賴項的許可證檔案。它可以被託管以展示並宣告應用所使用的依賴項。

vite.config.js
js
import { 
defineConfig
} from 'vite'
export default
defineConfig
({
build
: {
license
: true,
}, })

這將生成一個 .vite/license.md 檔案,其輸出可能如下所示:

md
# Licenses

The app bundles dependencies which contain the following licenses:

## dep-1 - 1.2.3 (CC0-1.0)

CC0 1.0 Universal

...

## dep-2 - 4.5.6 (MIT)

MIT License

...

若要在不同路徑下提供該檔案,你可以傳遞 { fileName: 'license.md' },這樣它就會在 https://example.com/license.md 下提供。有關更多資訊,請參閱 build.license 文件。

構建最佳化

下列功能作為構建過程的一部分自動應用,無需顯式配置,除非你想停用它們。

CSS 程式碼分割

Vite 會自動提取非同步塊(async chunk)中使用的 CSS 並生成一個單獨的檔案。當相關的非同步塊被載入時,CSS 檔案會自動透過 <link> 標籤載入,並且保證非同步塊僅在 CSS 載入後才會被評估,以避免 FOUC(無樣式內容閃爍)

如果你更希望將所有 CSS 提取到單個檔案中,可以透過設定 build.cssCodeSplitfalse 來停用 CSS 程式碼分割。

預載入指令生成

Vite 會自動為構建後的 HTML 中的入口 chunk 及其直接匯入生成 <link rel="modulepreload"> 指令。

非同步塊載入最佳化

在實際應用中,Rollup 經常會生成“公共”塊——即兩個或多個其他 chunk 共享的程式碼。結合動態匯入,出現以下場景非常普遍:

Entry async chunk A common chunk C async chunk B dynamic import direct import

在非最佳化場景下,當非同步塊 A 被匯入時,瀏覽器必須先請求並解析 A,才能發現它還需要公共塊 C。這會導致額外的網路往返。

Entry ---> A ---> C

Vite 會自動重寫程式碼分割的動態匯入呼叫,增加一個預載入步驟,以便在請求 A 時,並行獲取 C

Entry ---> (A + C)

C 可能還有進一步的匯入,這在未最佳化場景下會導致更多往返。Vite 的最佳化將追蹤所有直接匯入,以徹底消除這些往返,無論匯入深度如何。