Nuxt 不僅支持服務端渲染 (SSR),還提供了靜態網站生成 (SSG) 的強大功能,讓開發者能將網站輕鬆部署到任何支援 JAMstack 的平台上。
本文將深入介紹如何利用 Nuxt 生成靜態網站,並詳細探討如何控制生成過程中的各種行為和配置選項。從預渲染設置到 assets 輸出管理,一步步展示如何靈活地掌控 Nuxt 靜態網站的生成。
在 Nuxt 中生成靜態網站非常簡單,只需要執行以下的指令即可。
nuxt generate
默認情況下,Nuxt 會在生成靜態網站時將每個頁面進行預渲染,並生成對應的 HTML 檔案。
如果你希望生成一個僅用於客戶端渲染 (Client-Side Rendering) 的 SPA 網站,可以通過在配置中將 ssr
設置為 false
來禁用預渲染功能。
export default defineNuxtConfig({
ssr: false
})
Nuxt 使用 Nitro 進行預渲染,並將靜態網站輸出至預設的 .output/public
目錄下。
如果需要更改輸出目錄,可以通過以下配置來控制輸出路徑:
export default defineNuxtConfig({
nitro: {
output: {
dir: resolve('./.my-output'),
publicDir: path.join(__dirname, './.my-output/public'),
}
}
})
在預渲染並生成靜態網站後,Nuxt 預設會產生以下的目錄結構。
在這個章節,我們將介紹每個檔案和目錄的用途,並探討相關配置。
_nuxt
這個目錄包含網站的 assets 檔案,也包括所有的 CSS 和 JavaScript 文件。
你可以通過配置 app.buildAssetsDir
更改該目錄的名稱。
export default defineNuxtConfig({
app: {
buildAssetsDir: '/_my_assets/'
}
})
_nuxt/builds
該目錄包含 App Manifest 的相關文件,這些文件提供了最新構建的 routes
及 timestamp
等。
如果你不需要這些功能,可以通過配置 experimental.appManifest
關閉此功能,從而避免生成該目錄。
export default defineNuxtConfig({
experimental: {
appManifest: false
}
})
_nuxt/*.js
Nuxt 使用 Vite 的 Rollup 進行 JavaScript 打包。
你可以通過配置 vite.build
的 rollupOptions
來控制 JavaScript 文件的輸出格式,以下提供了幾個常見的配置示例:
output.entryFileNames
, output.chunkFileNames
)export default defineNuxtConfig({
vite: {
build: {
rollupOptions: {
output: {
entryFileNames: '_nuxt/my-[name]-[hash].js',
chunkFileNames: '_nuxt/my-[name]-[hash].js'
}
}
}
}
})
*.js
檔案合併為單一文件 (output.inlineDynamicImports
)export default defineNuxtConfig({
vite: {
build: {
rollupOptions: {
output: {
inlineDynamicImports: true
}
}
}
}
})
_nuxt/*.css
和其他 assets你可以通過配置 vite.build
來控制 CSS 和其他 assets 的輸出格式,以下提供了一些設定範例:
自定義輸出檔名格式 (rollupOptions.output.assetFileNames
)
export default defineNuxtConfig({
vite: {
build: {
rollupOptions: {
output: {
assetFileNames: '_nuxt/my-[name]-[hash].[ext]',
// or
assetFileNames: (assetInfo) => {
if (assetInfo?.name?.endsWith('.css'))
return '_nuxt/style-[name]-[hash].css'
return '_nuxt/[name]-[hash].[ext]'
}
}
}
}
}
})
這個設置將影響所有 assets,包括圖片、字體等。
將所有 *.css
檔案合併為單一文件 (cssCodeSplit
)
export default defineNuxtConfig({
vite: {
build: {
cssCodeSplit: false
}
}
})
對於存放在 assets/
目錄下的其他檔案(如圖片、字型等),它們可能會被複製到 _nuxt
目錄中。
如果你希望強制將所有資產文件內嵌(inline),而不是複製到 _nuxt
目錄,你可以使用以下配置來實現:
export default defineNuxtConfig({
vite: {
build: {
assetsInlineLimit: Number.MAX_SAFE_INTEGER
}
}
})
_payload.json
該文件在 SSR 或預渲染過程中用來傳遞頁面的 payload 資料。
如果你不需要外部載入該文件,並希望在生成靜態網站時不生成此文件,可以通過配置 payloadExtraction
來禁用它。
export default defineNuxtConfig({
experimental: {
payloadExtraction: false
}
})
200.html
和 404.html
這兩個文件在 SSG 時生成,作為 SPA 網站的 fallback 頁面。
如果你不需要這些文件,可以通過配置 nitro.prerender.ignore
來避免生成。
export default defineNuxtConfig({
nitro: {
prerender: {
ignore: ['/200.html', '/404.html']
}
}
})
index.html
Nuxt 會為你網站的每個頁面都生成對應的 index.html
文件,作為靜態網站的入口。
這些 Resource Hints 可以幫助瀏覽器提前加載資源,從而加快網站加載速度。
<!DOCTYPE html>
<html data-capo="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preload" as="fetch" crossorigin="anonymous" href="/_payload.json?93d23bea-82a5-406d-92a4-feb73d5bf1b8">
<link rel="modulepreload" as="script" crossorigin href="/_nuxt/D9xaLgge.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/BXlAlM0q.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/BRJtm5m-.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/CZvqSstT.js">
<script type="module" src="/_nuxt/D9xaLgge.js" crossorigin></script>
</head>
<body>
...
</body>
</html>
如果需要禁用 preload
和 prefetch
,可以使用 Nuxt Hooks 的 build:manifest
進行自定義,以下示範了如何禁用這些功能:
export default defineNuxtConfig({
hooks: {
'build:manifest': (manifest) => {
console.log('manifest', manifest)
for (const key in manifest) {
manifest[key].dynamicImports = []
manifest[key].prefetch = false
manifest[key].preload = false
}
}
}
})
Nuxt 不僅提供了簡單易用的靜態網站生成功能,還通過預設配置進行了大量優化,幫助開發者在構建網站時省去許多繁瑣的步驟。無論是預渲染、assets 管理還是目錄結構,Nuxt 都處理得井然有序。
同時,Nuxt 也保留了高度的自定義空間,允許開發者靈活地控制每個輸出細節,從而實現更加精細的網站優化和配置。這種平衡了簡單性與靈活性的設計,使 Nuxt 成為生成高效靜態網站的理想選擇。
本文的心得分享來自我最近的一個開源項目 nuxt-single-html
🌟,這是一個可以將 Nuxt 網站所有 JavaScript, CSS 和其他 assets 內嵌到單個 HTML 文件中的工具,適用於一些特殊場景下的靜態網站生成需求,歡迎前往查看。