output
在建置過程中,Next.js 會自動追蹤每個頁面及其依賴項,以確定部署應用程式生產版本所需的所有檔案。
此功能能大幅減少部署檔案的大小。以往使用 Docker 部署時,您需要安裝套件 dependencies 中的所有檔案才能執行 next start。從 Next.js 12 開始,您可以利用 .next/ 目錄中的輸出檔案追蹤功能,僅包含必要的檔案。
此外,這也移除了已棄用的 serverless 目標的需求,該目標可能導致各種問題並造成不必要的重複。
運作原理
在執行 next build 時,Next.js 會使用 @vercel/nft 靜態分析 import、require 和 fs 的使用情況,以確定頁面可能載入的所有檔案。
Next.js 的生產伺服器也會被追蹤其所需檔案,並輸出至 .next/next-server.js.nft.json,這些檔案可在生產環境中使用。
若要利用輸出至 .next 目錄的 .nft.json 檔案,您可以讀取每個追蹤中的檔案列表(這些檔案相對於 .nft.json 檔案的路徑),然後將它們複製到您的部署位置。
自動複製追蹤檔案
Next.js 可以自動建立一個 standalone 資料夾,僅複製生產部署所需的檔案,包括 node_modules 中的部分檔案。
要啟用此自動複製功能,您可以在 next.config.js 中進行設定:
module.exports = {
output: 'standalone',
}這將在 .next/standalone 建立一個資料夾,該資料夾可獨立部署,無需安裝 node_modules。
此外,還會輸出一個精簡的 server.js 檔案,可用於取代 next start。此精簡伺服器預設不會複製 public 或 .next/static 資料夾,因為這些檔案理想上應由 CDN 處理,但您可以手動將這些資料夾複製到 standalone/public 和 standalone/.next/static 資料夾中,之後 server.js 檔案將自動提供這些檔案。
須知事項:
- 如果您的專案需要監聽特定埠號或主機名稱,可以在執行
server.js前定義PORT或HOSTNAME環境變數。例如,執行PORT=8080 HOSTNAME=0.0.0.0 node server.js以在http://0.0.0.0:8080啟動伺服器。- 如果您的專案使用預設
loader的 圖片最佳化 功能,必須安裝sharp作為依賴項:
npm i sharpyarn add sharppnpm add sharpbun add sharp注意事項
- 在 monorepo 設定中進行追蹤時,預設會使用專案目錄作為追蹤根目錄。例如
next build packages/web-app會以packages/web-app作為追蹤根目錄,該資料夾外的任何檔案都不會被包含。若要包含此資料夾外的檔案,您可以在next.config.js中設定experimental.outputFileTracingRoot。
module.exports = {
experimental: {
// 這將包含來自 monorepo 根目錄往上兩層的檔案
outputFileTracingRoot: path.join(__dirname, '../../'),
},
}- 在某些情況下,Next.js 可能無法包含必要的檔案,或可能錯誤地包含未使用的檔案。在這些情況下,您可以在
next.config.js中分別使用experimental.outputFileTracingExcludes和experimental.outputFileTracingIncludes。每個設定接受一個物件,其鍵為 minimatch globs 以匹配特定頁面,值為相對於專案根目錄的 globs 陣列,用於在追蹤中包含或排除檔案。
module.exports = {
experimental: {
outputFileTracingExcludes: {
'/api/hello': ['./un-necessary-folder/**/*'],
},
outputFileTracingIncludes: {
'/api/another': ['./necessary-folder/**/*'],
},
},
}- 目前 Next.js 不會對輸出的
.nft.json檔案進行任何操作。這些檔案必須由您的部署平台(例如 Vercel)讀取以建立最小化部署。未來版本計劃新增一個命令來利用這些.nft.json檔案。
實驗性 turbotrace
追蹤依賴項可能很慢,因為它需要非常複雜的計算和分析。我們使用 Rust 建立了 turbotrace,作為 JavaScript 實現的更快、更智能的替代方案。
要啟用它,您可以將以下設定新增至 next.config.js:
module.exports = {
experimental: {
turbotrace: {
// 控制 turbotrace 的日誌級別,預設為 `error`
logLevel?:
| 'bug'
| 'fatal'
| 'error'
| 'warning'
| 'hint'
| 'note'
| 'suggestions'
| 'info',
// 控制 turbotrace 的日誌是否包含分析細節,預設為 `false`
logDetail?: boolean
// 顯示所有日誌訊息而不限制
// turbotrace 預設每種類別僅顯示 1 條日誌訊息
logAll?: boolean
// 控制 turbotrace 的上下文目錄
// 上下文目錄外的檔案將不會被追蹤
// 設定 `experimental.outputFileTracingRoot` 有相同效果
// 如果同時設定了 `experimental.outputFileTracingRoot` 和此選項,將使用 `experimental.turbotrace.contextDirectory`
contextDirectory?: string
// 如果程式碼中有 `process.cwd()` 表達式,可以設定此選項以告訴 `turbotrace` 追蹤時的 `process.cwd()` 值。
// 例如 require(process.cwd() + '/package.json') 將被追蹤為 require('/path/to/cwd/package.json')
processCwd?: string
// 控制 `turbotrace` 的最大記憶體使用量,單位為 `MB`,預設為 `6000`。
memoryLimit?: number
},
},
}