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/*.jsNuxt 使用 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.htmlNuxt 會為你網站的每個頁面都生成對應的 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 文件中的工具,適用於一些特殊場景下的靜態網站生成需求,歡迎前往查看。