部署
恭喜,是時候發佈到正式環境了。
您可以部署使用 Vercel 管理的 Next.js,或自行託管在 Node.js 伺服器、Docker 映像檔,甚至是靜態 HTML 檔案上。使用 next start
部署時,所有 Next.js 功能都受到支援。
正式版建置
執行 next build
會產生應用程式的最佳化版本以供正式環境使用。HTML、CSS 和 JavaScript 檔案會根據您的頁面建立。JavaScript 會使用 Next.js 編譯器 進行編譯,瀏覽器套件會進行最小化,以協助達到最佳效能並支援所有現代瀏覽器。
Next.js 會產生一個標準部署輸出,適用於 Next.js 的託管和自行託管部署。這確保所有功能在這兩種部署方法中都受到支援。在下一個主要版本中,我們會將此輸出轉換為我們的 建置輸出 API 規範。
使用 Vercel 託管 Next.js
Next.js 的建立者和維護者 Vercel,為您的 Next.js 應用程式提供託管式基礎架構和開發者體驗平台。
部署到 Vercel 是零設定的,並提供額外的增強功能,以實現全球範圍的可擴展性、可用性和效能。然而,所有 Next.js 功能在自行託管時仍然受到支援。
深入了解 Vercel 上的 Next.js 或 免費部署範本 來試用看看。
自行託管
您可以透過三種不同的方式自行託管 Next.js
🎥 觀看:深入了解自行託管 Next.js → YouTube (45 分鐘)。
Node.js 伺服器
Next.js 可以部署到任何支援 Node.js 的託管服務供應商。請確保您的 package.json
檔案中有 "build"
和 "start"
指令碼
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
接著,執行 npm run build
來建置您的應用程式。最後,執行 npm run start
來啟動 Node.js 伺服器。此伺服器支援所有 Next.js 功能。
Docker 映像檔
Next.js 可以部署到任何支援 Docker 容器的託管服務供應商。當您部署到容器協調器(例如 Kubernetes)或在任何雲端供應商的容器內執行時,可以使用這種方法。
- 在您的機器上安裝 Docker
- 複製我們的範例(或 多環境範例)
- 建置您的容器:
docker build -t nextjs-docker .
- 執行您的容器:
docker run -p 3000:3000 nextjs-docker
透過 Docker 執行的 Next.js 支援所有 Next.js 功能。
靜態 HTML 匯出
Next.js 可以先以靜態網站或單頁應用程式 (SPA) 的形式啟動,之後再選擇性地升級以使用需要伺服器的功能。
由於 Next.js 支援這種 靜態匯出 方式,它可以在任何可以提供 HTML/CSS/JS 靜態資源的網路伺服器上部署和託管。這包括 AWS S3、Nginx 或 Apache 等工具。
以 靜態匯出 方式運行不支援需要伺服器的 Next.js 功能。了解更多。
注意事項
- 伺服器組件 在靜態匯出中受到支援。
功能
圖片優化
使用 next start
部署時,透過 next/image
進行的 圖片優化 可在自行託管的環境下以零設定運作。如果您希望使用個別的服務來優化圖片,您可以設定圖片載入器。
透過在 next.config.js
中定義自訂圖片載入器,圖片優化功能可以與 靜態匯出 一起使用。請注意,圖片是在運行時進行優化的,而不是在建置期間。
注意事項
- 在基於 glibc 的 Linux 系統上,圖片優化可能需要 額外設定 以防止過度使用記憶體。
- 深入瞭解 已優化圖片的快取行為 以及如何設定 TTL。
- 如果您願意,也可以 停用圖片優化,並仍然保留使用
next/image
的其他優點。例如,如果您是自己另外優化圖片。
中介軟體
使用 next start
部署時,中介軟體 可在自行託管的環境下以零設定運作。由於它需要存取傳入請求,因此在使用 靜態匯出 時不受支援。
中介軟體使用所有可用 Node.js API 的子集作為 運行環境,以協助確保低延遲,因為它可能在應用程式中的每個路由或資源之前運行。此運行環境不需要在「邊緣」運行,並且可以在單一區域的伺服器中運作。要在多個區域運行中介軟體,需要額外的設定和基礎架構。
如果您希望添加需要所有 Node.js API 的邏輯(或使用外部套件),您可以將此邏輯作為佈局中的伺服器組件來移動。例如,檢查標頭和重新導向。您也可以使用標頭、Cookie 或查詢參數,透過 next.config.js
來重新導向或重寫。如果這不起作用,您也可以使用自訂伺服器。
環境變數
Next.js 可支援建置時和執行階段的環境變數。
預設情況下,環境變數僅在伺服器上可用。要將環境變數公開給瀏覽器,它必須以 NEXT_PUBLIC_
作為前綴。然而,這些公開的環境變數將在 next build
期間被內嵌到 JavaScript 捆綁包中。
要讀取執行階段環境變數,我們建議使用 getServerSideProps
或逐步採用 App Router。
這允許您使用單個 Docker 映像,並透過具有不同值的多個環境進行升級。
注意事項
- 您可以使用
register
函式在伺服器啟動時執行程式碼。- 我們不建議使用 runtimeConfig 選項,因為它不適用於獨立輸出模式。相反地,我們建議逐步採用 App Router。
快取和 ISR
Next.js 可以快取回應、產生的靜態頁面、建置輸出和其他靜態資源,例如圖片、字體和腳本。
快取和重新驗證頁面(使用增量靜態再生)使用相同的共享快取。預設情況下,此快取儲存在 Next.js 伺服器上的檔案系統(磁碟)中。在使用 Pages 和 App Router 自行託管時,這會自動運作。
如果您想要將快取的頁面和資料保存到持久儲存空間,或在多個容器或 Next.js 應用程式的執行個體之間共享快取,則可以設定 Next.js 快取位置。
自動快取。您可以設定圖片的 TTL。
Cache-Control
標頭設定為 s-maxage: <getStaticProps 中的 revalidate 值>, stale-while-revalidate
。這個重新驗證時間在您的 getStaticProps
函式 中以秒為單位定義。如果您設定 revalidate: false
,它將預設為一年的快取期限。Cache-Control
標頭為 private, no-cache, no-store, max-age=0, must-revalidate
,以防止使用者特定資料被快取。這適用於應用程式路由器和頁面路由器。這也包含草稿模式。靜態資源
如果您想在不同的網域或 CDN 上託管靜態資源,您可以在 next.config.js
中使用 assetPrefix
設定。Next.js 在擷取 JavaScript 或 CSS 檔案時會使用此資源前綴。將您的資源分離到不同的網域確實會帶來額外的 DNS 和 TLS 解析時間的缺點。
設定快取
預設情況下,產生的快取資源將儲存在記憶體(預設為 50MB)和磁碟上。如果您使用容器協調平台(如 Kubernetes)託管 Next.js,則每個 Pod 都將擁有快取的副本。由於預設情況下 Pod 之間不共用快取,為防止顯示過時資料,您可以設定 Next.js 快取以提供快取處理程式並停用記憶體內快取。
若要設定自行託管時的 ISR/資料快取位置,您可以在 next.config.js
檔案中設定自訂處理程式
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // disable default in-memory caching
}
然後,在專案的根目錄中建立 cache-handler.js
,例如
const cache = new Map()
module.exports = class CacheHandler {
constructor(options) {
this.options = options
}
async get(key) {
// This could be stored anywhere, like durable storage
return cache.get(key)
}
async set(key, data, ctx) {
// This could be stored anywhere, like durable storage
cache.set(key, {
value: data,
lastModified: Date.now(),
tags: ctx.tags,
})
}
async revalidateTag(tags) {
// tags is either a string or an array of strings
tags = [tags].flat()
// Iterate over all entries in the cache
for (let [key, value] of cache) {
// If the value's tags include the specified tag, delete this entry
if (value.tags.some((tag) => tags.include(tag))) {
cache.delete(key)
}
}
}
}
使用自訂快取處理器能確保所有裝載 Next.js 應用程式的 Pod 之間的一致性。例如,您可以將快取值儲存到任何地方,像是 Redis 或 AWS S3。
注意事項
revalidatePath
是基於快取標籤之上的便利層。呼叫revalidatePath
將會以提供頁面的特殊預設標籤呼叫revalidateTag
函式。
建置快取
Next.js 在 next build
期間會產生一個 ID,用於識別正在提供服務的應用程式版本。應使用相同的建置版本並啟動多個容器。
如果您為環境的每個階段都重新建置,則需要產生一個一致的建置 ID 以供容器之間使用。請在 next.config.js
中使用 generateBuildId
指令。
module.exports = {
generateBuildId: async () => {
// This could be anything, using the latest git hash
return process.env.GIT_HASH
},
}
版本偏差
Next.js 會自動減輕大多數 版本偏差 的情況,並在偵測到版本偏差時自動重新載入應用程式以取得新的資源。例如,如果 deploymentId
不符,頁面之間的轉換將會執行硬性導航,而不是使用預先擷取的值。
當應用程式重新載入時,如果應用程式未設計為在頁面導航之間保持狀態,則可能會遺失應用程式狀態。例如,使用 URL 狀態或本地儲存空間會在頁面重新整理後保留狀態。但是,像 useState
這樣的組件狀態將會在此類導航中遺失。
Vercel 為 Next.js 應用程式提供額外的 偏差保護,以確保即使在新版本部署後,舊版用戶端仍然可以使用先前版本的資源和函式。
您可以在 next.config.js
檔案中手動設定 deploymentId
屬性,以確保每個請求都使用 ?dpl
查詢字串或 x-deployment-id
標頭。
手動優雅關閉
在自行託管時,您可能希望在伺服器因 SIGTERM
或 SIGINT
訊號關閉時執行程式碼。
您可以將環境變數 NEXT_MANUAL_SIG_HANDLE
設定為 true
,然後在 _document.js
檔案中註冊該訊號的處理程式。您需要直接在 package.json
腳本中註冊環境變數,而不是在 .env
檔案中。
注意事項:
next dev
不支援手動訊號處理。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "NEXT_MANUAL_SIG_HANDLE=true next start"
}
}
if (process.env.NEXT_MANUAL_SIG_HANDLE) {
process.on('SIGTERM', () => {
console.log('Received SIGTERM: cleaning up')
process.exit(0)
})
process.on('SIGINT', () => {
console.log('Received SIGINT: cleaning up')
process.exit(0)
})
}
上線檢查清單
靜態匯出
多區域
持續整合 (CI) 建置快取
這有幫助嗎?