跳轉到內容

構建生產版本

當需要為生產環境部署應用時,只需執行 vite build 命令。預設情況下,它使用 <root>/index.html 作為構建入口,並生成一個適合在靜態託管服務上部署的應用包。檢視 部署靜態站點 以獲取關於熱門服務的部署指南。

瀏覽器相容性

預設情況下,生產構建產物假定目標瀏覽器為 Baseline(基線)廣泛支援的範圍。預設支援的瀏覽器版本範圍如下:

  • Chrome >=111
  • Edge >=111
  • Firefox >=114
  • Safari >=16.4

你可以透過 build.target 配置選項指定自定義目標,最低支援 es2015。如果設定了更低的目標,Vite 依然要求滿足上述最低瀏覽器支援範圍,因為它依賴 原生 ESM 動態匯入import.meta

  • Chrome >=64
  • Firefox >=67
  • Safari >=11.1
  • Edge >=79

請注意,預設情況下,Vite 僅處理語法轉換,不提供 polyfills(墊片)。你可以訪問 https://cdnjs.cloudflare.com/polyfill/,它會根據使用者的瀏覽器 UserAgent 字串自動生成 polyfill 包。

可以透過 @vitejs/plugin-legacy 支援舊版瀏覽器,它會自動生成舊版 chunk 以及相應的 ES 語言特性 polyfills。這些舊版 chunk 只會在不支援原生 ESM 的瀏覽器中按需載入。

公共基礎路徑

如果你的專案部署在巢狀的公共路徑下,只需指定 base 配置選項,所有資源路徑都會相應地重寫。該選項也可以透過命令列引數指定,例如 vite build --base=/my/public/path/

在構建過程中,JS 匯入的資源 URL、CSS 中的 url() 引用以及 .html 檔案中的資源引用都會自動調整以遵循此選項。

例外情況是當你需要動態拼接 URL 時。在這種情況下,你可以使用全域性注入的 import.meta.env.BASE_URL 變數,它即為公共基礎路徑。注意該變數在構建時會被靜態替換,因此必須以原樣出現(例如 import.meta.env['BASE_URL'] 是無效的)。

若需更高階的基礎路徑控制,請檢視 高階基礎路徑選項

相對基礎路徑

如果你無法提前預知基礎路徑,可以設定相對基礎路徑,如 "base": "./""base": ""。這將使所有生成的 URL 相對於每個檔案進行定位。

使用相對基礎路徑時對舊版瀏覽器的支援

相對路徑需要 import.meta 支援。如果你需要支援 不支援 import.meta 的瀏覽器,可以使用 legacy 外掛

自定義構建

可以透過各種 構建配置選項 自定義構建。具體來說,你可以透過 build.rolldownOptions 直接調整底層的 Rolldown 選項

vite.config.js
js
export default defineConfig({
  build: {
    rolldownOptions: {
      // https://rolldown.rs/reference/
    },
  },
})

例如,你可以指定多個 Rolldown 輸出,並使用僅在構建時應用的外掛。

分塊策略

你可以使用 build.rolldownOptions.output.codeSplitting 來配置如何進行程式碼分塊(參考 Rolldown 文件)。如果你使用的是某個框架,請查閱其文件以瞭解如何配置分塊。

載入錯誤處理

當動態匯入載入失敗時,Vite 會觸發 vite:preloadError 事件。event.payload 包含原始的匯入錯誤。如果你呼叫了 event.preventDefault(),該錯誤將不會被丟擲。

js
window
.
addEventListener
('vite:preloadError', (
event
) => {
window
.
location
.
reload
() // for example, refresh the page
})

當進行新部署時,託管服務可能會刪除舊部署的資源。結果就是,在新部署之前訪問過你站點的使用者可能會遇到匯入錯誤。這是因為使用者裝置上執行的資源已過期,且嘗試匯入對應的舊 chunk,但該檔案已被刪除。此事件有助於處理這種情況。在這種情況下,請確保在 HTML 檔案上設定 Cache-Control: no-cache,否則舊資源仍會被引用。

檔案變更時重新構建

你可以透過 vite build --watch 啟用 rollup 觀察器,或者透過 build.watch 直接調整底層的 WatcherOptions

vite.config.js
js
export default defineConfig({
  build: {
    watch: {
      // https://rolldown.rs/reference/InputOptions.watch
    },
  },
})

啟用 --watch 標誌後,對要打包的檔案的更改將觸發重新構建。請注意,修改配置檔案及其依賴項需要重啟構建命令。

多頁應用

假設你擁有以下原始碼結構:

├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
    ├── index.html
    └── nested.js

在開發環境下,直接導航或連結到 /nested/ 即可——它能按預期工作,就像普通的靜態檔案伺服器一樣。

在構建時,你只需要將多個 .html 檔案指定為入口點:

vite.config.js
js
import { 
dirname
,
resolve
} from 'node:path'
import {
defineConfig
} from 'vite'
export default
defineConfig
({
build
: {
rolldownOptions
: {
input
: {
main
:
resolve
(import.meta.
dirname
, 'index.html'),
nested
:
resolve
(import.meta.
dirname
, 'nested/index.html'),
}, }, }, })

如果你指定了不同的根目錄 (root),請記住在解析輸入路徑時,import.meta.dirname 仍然會是你的 vite.config.js 檔案所在的資料夾。因此,你需要將你的 root 條目新增到 resolve 的引數中。

注意,對於 HTML 檔案,Vite 會忽略 rolldownOptions.input 物件中給定的名稱,而是在 dist 資料夾中生成 HTML 資源時尊重檔案的已解析 ID。這確保了結構與開發伺服器工作方式的一致性。

庫模式

當你開發面向瀏覽器的庫時,大部分時間可能是在測試/演示頁面中匯入你的實際庫。使用 Vite,你可以將 index.html 用於此目的,以獲得流暢的開發體驗。

當需要打包庫以供釋出時,請使用 build.lib 配置選項。確保將不希望打包到庫中的依賴項外部化(externalize),例如 vuereact

js
import { 
dirname
,
resolve
} from 'node:path'
import {
defineConfig
} from 'vite'
export default
defineConfig
({
build
: {
lib
: {
entry
:
resolve
(import.meta.
dirname
, 'lib/main.js'),
name
: 'MyLib',
// the proper extensions will be added
fileName
: 'my-lib',
},
rolldownOptions
: {
// make sure to externalize deps that shouldn't be bundled // into your library
external
: ['vue'],
output
: {
// Provide global variables to use in the UMD build // for externalized deps
globals
: {
vue
: 'Vue',
}, }, }, }, })
js
import { 
dirname
,
resolve
} from 'node:path'
import {
defineConfig
} from 'vite'
export default
defineConfig
({
build
: {
lib
: {
entry
: {
'my-lib':
resolve
(import.meta.
dirname
, 'lib/main.js'),
secondary
:
resolve
(import.meta.
dirname
, 'lib/secondary.js'),
},
name
: 'MyLib',
},
rollupOptions
: {
// make sure to externalize deps that shouldn't be bundled // into your library
external
: ['vue'],
output
: {
// Provide global variables to use in the UMD build // for externalized deps
globals
: {
vue
: 'Vue',
}, }, }, }, })

入口檔案應包含使用者可以從你的包中匯入的匯出內容:

lib/main.js
js
import Foo from './Foo.vue'
import Bar from './Bar.vue'
export { Foo, Bar }

使用此配置執行 vite build 時,將使用一個面向庫釋出的 Rollup 預設,並生成兩種捆綁格式:

  • esumd (針對單入口)
  • escjs (針對多入口)

格式可以透過 build.lib.formats 選項進行配置。

$ vite build
building for production...
dist/my-lib.js      0.08 kB / gzip: 0.07 kB
dist/my-lib.umd.cjs 0.30 kB / gzip: 0.16 kB

推薦的庫 package.json 配置:

json
{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.umd.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.umd.cjs"
    }
  }
}
json
{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.cjs"
    },
    "./secondary": {
      "import": "./dist/secondary.js",
      "require": "./dist/secondary.cjs"
    }
  }
}

CSS 支援

如果你的庫匯入了任何 CSS,它將被打包成一個獨立的 CSS 檔案,隨構建後的 JS 檔案一起釋出,例如 dist/my-lib.css。檔名預設為 build.lib.fileName,也可以透過 build.lib.cssFileName 進行修改。

你可以在 package.json 中匯出 CSS 檔案,供使用者匯入:

json
{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.umd.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.umd.cjs"
    },
    "./style.css": "./dist/my-lib.css"
  }
}

副檔名

如果 package.json 中沒有包含 "type": "module",Vite 為了與 Node.js 相容將生成不同的副檔名。.js 將變為 .mjs.cjs 將保持為 .cjs

環境變數

在庫模式下,所有的 import.meta.env.* 使用在生產構建時會被靜態替換。然而,process.env.* 的使用則不會,這樣庫的使用者就可以動態更改它們。如果這不是你想要的,可以使用例如 define: { 'process.env.NODE_ENV': '"production"' } 來靜態替換它們,或者使用 esm-env 以獲得與打包器和執行環境更好的相容性。

高階用法

庫模式包含了一種簡單且具有明確傾向性的配置,適用於面向瀏覽器和 JS 框架的庫。如果你正在構建非瀏覽器庫,或需要高階構建流程,可以直接使用 tsdownRolldown

高階基礎路徑選項

警告

此功能處於實驗階段。提供反饋

對於高階用例,部署的資源和公共檔案可能位於不同的路徑,例如為了使用不同的快取策略。使用者可能選擇部署到三個不同的路徑:

  • 生成的入口 HTML 檔案(可能在 SSR 期間處理)
  • 生成的帶雜湊的資源(JS、CSS 和其他型別檔案如圖片)
  • 複製的 public 檔案

在這些場景下,單一的靜態 基礎路徑 是不夠的。Vite 在構建過程中透過 experimental.renderBuiltUrl 提供了對高階基礎路徑選項的實驗性支援。

ts
experimental
: {
renderBuiltUrl
(
filename
, {
hostType
}) {
if (
hostType
=== 'js') {
return {
runtime
: `window.__toCdnUrl(${
JSON
.
stringify
(
filename
)})` }
} else { return {
relative
: true }
} }, },

如果帶雜湊的資源和公共檔案沒有部署在一起,可以使用傳遞給函式的第二個 context 引數中包含的資源 type,分別為每組定義選項。

ts
experimental
: {
renderBuiltUrl
(
filename
, {
hostId
,
hostType
,
type
}) {
if (
type
=== 'public') {
return 'https://www.domain.com/' +
filename
} else if (
path
.
extname
(
hostId
) === '.js') {
return {
runtime
: `window.__assetsPath(${
JSON
.
stringify
(
filename
)})`
} } else { return 'https://cdn.domain.com/assets/' +
filename
} }, },

注意,傳入的 filename 是已解碼的 URL,如果函式返回一個 URL 字串,它也應該是已解碼的。Vite 在渲染 URL 時會自動處理編碼。如果返回一個帶有 runtime 的物件,則需要自行在需要的地方處理編碼,因為執行時程式碼將按原樣渲染。