為生產環境建置
當您準備將應用程式部署到生產環境時,只需執行 vite build
命令。預設情況下,它會使用 <root>/index.html
作為建置入口點,並產生一個適用於透過靜態託管服務提供的應用程式套件。請查看部署靜態網站以取得有關常用服務的指南。
瀏覽器相容性
生產套件假設支援現代 JavaScript。預設情況下,Vite 以支援原生 ES 模組、原生 ESM 動態引入和import.meta
的瀏覽器為目標。
- Chrome >=87
- Firefox >=78
- Safari >=14
- Edge >=88
您可以透過build.target
設定選項指定自訂目標,其中最低目標為 es2015
。
請注意,預設情況下,Vite 僅處理語法轉換,而不涵蓋 polyfill。您可以查看 https://cdnjs.cloudflare.com/polyfill/,它會根據使用者的瀏覽器 UserAgent 字串自動產生 polyfill 套件。
舊版瀏覽器可以透過 @vitejs/plugin-legacy 支援,它會自動產生舊版區塊和相應的 ES 語言功能 polyfill。舊版區塊僅在不支援原生 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.rollupOptions
直接調整底層的Rollup 選項。
export default defineConfig({
build: {
rollupOptions: {
// https://rollup.dev.org.tw/configuration-options/
},
},
})
例如,您可以使用僅在建置期間應用程式的外掛指定多個 Rollup 輸出。
區塊策略
您可以使用 build.rollupOptions.output.manualChunks
設定區塊的分割方式(請參閱Rollup 文件)。如果您使用框架,請參考其文件以設定區塊的分割方式。
載入錯誤處理
當 Vite 無法載入動態引入時,會發出 vite:preloadError
事件。event.payload
包含原始引入錯誤。如果您呼叫 event.preventDefault()
,則不會拋出錯誤。
window.addEventListener('vite:preloadError', (event) => {
window.location.reload() // for example, refresh the page
})
當發生新的部署時,託管服務可能會刪除先前部署的資源。因此,在新的部署之前造訪您網站的使用者可能會遇到引入錯誤。發生此錯誤的原因是該使用者裝置上執行的資源已過時,並且它嘗試引入相應的已刪除舊區塊。此事件對於解決此情況很有用。
在檔案變更時重建
您可以使用 vite build --watch
啟用 Rollup 監看器。或者,您可以透過 build.watch
直接調整底層的WatcherOptions
。
export default defineConfig({
build: {
watch: {
// https://rollup.dev.org.tw/configuration-options/#watch
},
},
})
啟用 --watch
旗標後,變更 vite.config.js
以及任何要綁定的檔案,都會觸發重建。
多頁應用程式
假設您有以下原始碼結構
├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
├── index.html
└── nested.js
在開發期間,只需導覽或連結至 /nested/
- 它的運作方式與一般的靜態檔案伺服器相同。
在建置期間,您需要做的就是將多個 .html
檔案指定為入口點
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
nested: resolve(__dirname, 'nested/index.html'),
},
},
},
})
如果您指定不同的根目錄,請記住,當解析輸入路徑時,__dirname
仍然是您的 vite.config.js 檔案的資料夾。因此,您需要將您的 root
項目新增至 resolve
的參數中。
請注意,對於 HTML 檔案,Vite 會忽略在 rollupOptions.input
物件中給定項目的名稱,而是在 dist 資料夾中產生 HTML 資源時尊重檔案的已解析 ID。這可確保與開發伺服器的運作方式保持一致的結構。
程式庫模式
當您開發以瀏覽器為導向的程式庫時,您很可能會將大部分時間花在引入實際程式庫的測試/示範頁面上。透過 Vite,您可以將 index.html
用於此目的,以獲得流暢的開發體驗。
當您準備為發佈捆綁您的程式庫時,請使用 build.lib
設定選項。請確保也外部化您不想捆綁到程式庫中的任何依賴項,例如 vue
或 react
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'lib/main.js'),
name: 'MyLib',
// the proper extensions will be added
fileName: 'my-lib',
},
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 { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
lib: {
entry: {
'my-lib': resolve(__dirname, 'lib/main.js'),
secondary: resolve(__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,它會與建置的 JS 檔案一起捆綁為單一 CSS 檔案,例如 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
將會變成 .js
。
環境變數
在程式庫模式中,所有 import.meta.env.*
用法都會在為生產環境建置時靜態取代。然而,process.env.*
用法不會,因此您的程式庫的消費者可以動態變更它。如果這是不理想的,您可以使用 define: { 'process.env.NODE_ENV': '"production"' }
來靜態取代它們,或者使用 esm-env
以獲得與捆綁器和執行環境的更好的相容性。
進階基礎選項
警告
此功能為實驗性功能。提供意見反應。
對於進階使用案例,部署的資源和公開檔案可能會位於不同的路徑,例如使用不同的快取策略。使用者可能會選擇在三個不同的路徑中部署
- 產生的入口 HTML 檔案(可能會在 SSR 期間處理)
- 產生的雜湊資源(JS、CSS 和其他檔案類型,例如影像)
- 複製的公開檔案
在這些情況下,單一靜態 base 不足以滿足需求。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
的物件,則應自行處理需要的編碼,因為 runtime 程式碼會按原樣渲染。