跳至內容

後端整合

注意

如果您想使用傳統後端 (例如 Rails、Laravel) 提供 HTML,但使用 Vite 提供資源,請查看 Awesome Vite 中列出的現有整合。

如果您需要自訂整合,您可以按照本指南中的步驟手動設定。

  1. 在您的 Vite 設定中,設定入口點並啟用建構清單。

    vite.config.js
    js
    export default 
    defineConfig
    ({
    build
    : {
    // generate .vite/manifest.json in outDir
    manifest
    : true,
    rollupOptions
    : {
    // overwrite default .html entry
    input
    : '/path/to/main.js',
    }, }, })

    如果您尚未停用 module preload polyfill,您也需要在您的入口點中匯入 polyfill。

    js
    // add the beginning of your app entry
    import 'vite/modulepreload-polyfill'
  2. 對於開發環境,請在您伺服器的 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>
  3. 對於生產環境:在執行 vite build 後,將會和其他資源檔案一起產生一個 .vite/manifest.json 檔案。一個範例清單檔案看起來像這樣。

    .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.cssCodeSplitfalse 時產生的 CSS 檔案,索引鍵是 style.css
    • 區塊將包含有關其靜態和動態匯入 (兩者都是對應到清單中區塊的索引鍵) 以及其對應的 CSS 和資源檔案 (如果有的話) 的資訊。
  4. 您可以使用此檔案來使用雜湊檔案名稱渲染連結或預先載入指令。

    這是一個 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 的虛擬實作範例 (這需要根據您的程式設計語言和模板語言進行調整)。

    ts
    import 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])
    }

依 MIT 授權條款發佈。(ccee3d7c)