構建生產版本
當需要為生產環境部署應用時,只需執行 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 選項。
export default defineConfig({
build: {
rolldownOptions: {
// https://rolldown.rs/reference/
},
},
})例如,你可以指定多個 Rolldown 輸出,並使用僅在構建時應用的外掛。
分塊策略
你可以使用 build.rolldownOptions.output.codeSplitting 來配置如何進行程式碼分塊(參考 Rolldown 文件)。如果你使用的是某個框架,請查閱其文件以瞭解如何配置分塊。
載入錯誤處理
當動態匯入載入失敗時,Vite 會觸發 vite:preloadError 事件。event.payload 包含原始的匯入錯誤。如果你呼叫了 event.preventDefault(),該錯誤將不會被丟擲。
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。
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 檔案指定為入口點:
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),例如 vue 或 react。
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',
},
},
},
},
})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',
},
},
},
},
})入口檔案應包含使用者可以從你的包中匯入的匯出內容:
import Foo from './Foo.vue'
import Bar from './Bar.vue'
export { Foo, Bar }使用此配置執行 vite build 時,將使用一個面向庫釋出的 Rollup 預設,並生成兩種捆綁格式:
es和umd(針對單入口)es和cjs(針對多入口)
格式可以透過 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 配置:
{
"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"
}
}
}{
"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 檔案,供使用者匯入:
{
"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 以獲得與打包器和執行環境更好的相容性。
高階基礎路徑選項
警告
此功能處於實驗階段。提供反饋。
對於高階用例,部署的資源和公共檔案可能位於不同的路徑,例如為了使用不同的快取策略。使用者可能選擇部署到三個不同的路徑:
- 生成的入口 HTML 檔案(可能在 SSR 期間處理)
- 生成的帶雜湊的資源(JS、CSS 和其他型別檔案如圖片)
- 複製的 public 檔案
在這些場景下,單一的靜態 基礎路徑 是不夠的。Vite 在構建過程中透過 experimental.renderBuiltUrl 提供了對高階基礎路徑選項的實驗性支援。
experimental: {
renderBuiltUrl(filename, { hostType }) {
if (hostType === 'js') {
return { runtime: `window.__toCdnUrl(${JSON.stringify(filename)})` }
} else {
return { relative: true }
}
},
},
如果帶雜湊的資源和公共檔案沒有部署在一起,可以使用傳遞給函式的第二個 context 引數中包含的資源 type,分別為每組定義選項。
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 的物件,則需要自行在需要的地方處理編碼,因為執行時程式碼將按原樣渲染。
