後端整合
注意
如果您想使用傳統後端 (例如 Rails、Laravel) 提供 HTML,但使用 Vite 提供資源,請查看 Awesome Vite 中列出的現有整合。
如果您需要自訂整合,您可以按照本指南中的步驟手動設定。
在您的 Vite 設定中,設定入口點並啟用建構清單。
jsexport default
defineConfig({build: { // generate .vite/manifest.json in outDirmanifest: true,rollupOptions: { // overwrite default .html entryinput: '/path/to/main.js', }, }, })如果您尚未停用 module preload polyfill,您也需要在您的入口點中匯入 polyfill。
js// add the beginning of your app entry import 'vite/modulepreload-polyfill'
對於開發環境,請在您伺服器的 HTML 模板中注入以下內容 (將
https://127.0.0.1:5173
替換為 Vite 正在運行的本地 URL)。html<!-- if development --> <script type="module" src="https://127.0.0.1:5173/@vite/client"></script> <script type="module" src="https://127.0.0.1:5173/main.js"></script>
為了正確地提供資源,您有兩種選擇。
- 確保伺服器已設定為將靜態資源請求代理到 Vite 伺服器。
- 設定
server.origin
,以便產生的資源 URL 將使用後端伺服器 URL 而不是相對路徑進行解析。
這是為了讓圖像等資源能夠正確載入。
請注意,如果您使用 React 和
@vitejs/plugin-react
,您還需要在上述腳本之前添加此內容,因為該外掛無法修改您正在提供的 HTML (將https://127.0.0.1:5173
替換為 Vite 正在運行的本地 URL)。html<script type="module"> import RefreshRuntime from 'https://127.0.0.1:5173/@react-refresh' RefreshRuntime.injectIntoGlobalHook(window) window.$RefreshReg$ = () => {} window.$RefreshSig$ = () => (type) => type window.__vite_plugin_react_preamble_installed__ = true </script>
對於生產環境:在執行
vite build
後,將會和其他資源檔案一起產生一個.vite/manifest.json
檔案。一個範例清單檔案看起來像這樣。json{ "_shared-B7PI925R.js": { "file": "assets/shared-B7PI925R.js", "name": "shared", "css": ["assets/shared-ChJ_j-JJ.css"] }, "_shared-ChJ_j-JJ.css": { "file": "assets/shared-ChJ_j-JJ.css", "src": "_shared-ChJ_j-JJ.css" }, "baz.js": { "file": "assets/baz-B2H3sXNv.js", "name": "baz", "src": "baz.js", "isDynamicEntry": true }, "views/bar.js": { "file": "assets/bar-gkvgaI9m.js", "name": "bar", "src": "views/bar.js", "isEntry": true, "imports": ["_shared-B7PI925R.js"], "dynamicImports": ["baz.js"] }, "views/foo.js": { "file": "assets/foo-BRBmoGS9.js", "name": "foo", "src": "views/foo.js", "isEntry": true, "imports": ["_shared-B7PI925R.js"], "css": ["assets/foo-5UjPuW-k.css"] } }
- 該清單具有
Record<name, chunk>
結構。 - 對於入口點或動態入口點區塊,索引鍵是專案根目錄的相對 src 路徑。
- 對於非入口點區塊,索引鍵是產生的檔案的基本名稱,並加上
_
前綴。 - 對於當
build.cssCodeSplit
為false
時產生的 CSS 檔案,索引鍵是style.css
。 - 區塊將包含有關其靜態和動態匯入 (兩者都是對應到清單中區塊的索引鍵) 以及其對應的 CSS 和資源檔案 (如果有的話) 的資訊。
- 該清單具有
您可以使用此檔案來使用雜湊檔案名稱渲染連結或預先載入指令。
這是一個 HTML 模板範例,用於渲染正確的連結。此處的語法僅用於說明,請替換為您的伺服器模板語言。
importedChunks
函式僅用於說明,Vite 不會提供。html<!-- if production --> <!-- for cssFile of manifest[name].css --> <link rel="stylesheet" href="/{{ cssFile }}" /> <!-- for chunk of importedChunks(manifest, name) --> <!-- for cssFile of chunk.css --> <link rel="stylesheet" href="/{{ cssFile }}" /> <script type="module" src="/{{ manifest[name].file }}"></script> <!-- for chunk of importedChunks(manifest, name) --> <link rel="modulepreload" href="/{{ chunk.file }}" />
具體來說,產生 HTML 的後端應包含以下標籤,其中包含清單檔案和入口點。
- 入口點區塊的
css
清單中每個檔案的<link rel="stylesheet">
標籤。 - 遞迴追蹤入口點
imports
清單中的所有區塊,並為每個匯入區塊的每個 CSS 檔案包含<link rel="stylesheet">
標籤。 - 入口點區塊的
file
索引鍵的標籤 (JavaScript 的<script type="module">
或 CSS 的<link rel="stylesheet">
)。 - 選擇性地,對於每個匯入的 JavaScript 區塊的
file
,使用<link rel="modulepreload">
標籤,再次遞迴追蹤從入口點區塊開始的匯入。
依照上述範例清單,對於入口點
views/foo.js
,應在生產環境中包含以下標籤。html<link rel="stylesheet" href="assets/foo-5UjPuW-k.css" /> <link rel="stylesheet" href="assets/shared-ChJ_j-JJ.css" /> <script type="module" src="assets/foo-BRBmoGS9.js"></script> <!-- optional --> <link rel="modulepreload" href="assets/shared-B7PI925R.js" />
而對於入口點
views/bar.js
,應包含以下內容。html<link rel="stylesheet" href="assets/shared-ChJ_j-JJ.css" /> <script type="module" src="assets/bar-gkvgaI9m.js"></script> <!-- optional --> <link rel="modulepreload" href="assets/shared-B7PI925R.js" />
importedChunks
的虛擬實作TypeScript 中
importedChunks
的虛擬實作範例 (這需要根據您的程式設計語言和模板語言進行調整)。tsimport type { Manifest, ManifestChunk } from 'vite' export default function importedChunks( manifest: Manifest, name: string, ): ManifestChunk[] { const seen = new Set<string>() function getImportedChunks(chunk: ManifestChunk): ManifestChunk[] { const chunks: ManifestChunk[] = [] for (const file of chunk.imports ?? []) { const importee = manifest[file] if (seen.has(file)) { continue } seen.add(file) chunks.push(...getImportedChunks(importee)) chunks.push(importee) } return chunks } return getImportedChunks(manifest[name]) }
- 入口點區塊的