output
ビルド時に、Next.js は各ページとその依存関係を自動的にトレースし、アプリケーションのプロダクションバージョンをデプロイするのに必要なすべてのファイルを決定します。
この機能はデプロイメントのサイズを大幅に削減するのに役立ちます。以前は Docker を使ってデプロイする際、next start
を実行するにはパッケージの dependencies
からすべてのファイルをインストールする必要がありました。Next.js 12 からは、.next/
ディレクトリ内の Output File Tracing を活用して必要なファイルのみを含むことができます。
さらに、これにより、さまざまな問題を引き起こす可能性があり、不要な重複を作成する非推奨の 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 は、node_modules
内の選択されたファイルを含むプロダクションデプロイメントに必要なファイルのみをコピーした standalone
フォルダを自動的に作成できます。
この自動コピーを活用するためには、next.config.js
で有効にできます。
module.exports = {
output: 'standalone',
}
これにより、node_modules
をインストールせずにデプロイできる .next/standalone
フォルダが作成されます。
加えて、next start
の代わりに使用できる最小限の server.js
ファイルも出力されます。この最小限のサーバーは、デフォルトでは public
または .next/static
フォルダをコピーしません。これらは理想的には CDN によって処理されるべきですが、手動で standalone/public
と standalone/.next/static
フォルダにコピーした後、server.js
ファイルがそれらを自動的に提供します。
これらを手動でコピーするには、next build
後に cp
コマンドラインツールを使用できます。
cp -r public .next/standalone/ && cp -r .next/static .next/standalone/.next/
ローカルで最小限の server.js
ファイルを起動するには、次のコマンドを実行します。
node .next/standalone/server.js
Good to know:
- プロジェクトが特定のポートまたはホスト名をリスニングする必要がある場合、
server.js
を実行する前にPORT
またはHOSTNAME
環境変数を設定できます。たとえば、PORT=8080 HOSTNAME=0.0.0.0 node server.js
を実行して、http://0.0.0.0:8080
でサーバーを起動します。
注意点
- モノレポのセットアップでトレースする場合、デフォルトではプロジェクトディレクトリがトレースに使用されます。たとえば、
next build packages/web-app
の場合、packages/web-app
がトレース root になり、そのフォルダ外のファイルは含まれません。このフォルダの外のファイルを含めるには、next.config.js
でoutputFileTracingRoot
を設定できます。
module.exports = {
// モノレポのベースから2つ上のディレクトリのファイルを含めます
outputFileTracingRoot: path.join(__dirname, '../../'),
}
- Next.js が必要なファイルを含められない、または使用されていないファイルを誤って含める場合があります。その場合、
outputFileTracingExcludes
およびoutputFileTracingIncludes
をnext.config.js
でそれぞれ活用できます。それぞれの設定は、特定のページと一致するキーとして minimatch globs を受け入れ、プロジェクトの root に対する globs の配列を値としてトレースに含めるまたは除外するか選択できます。
module.exports = {
outputFileTracingExcludes: {
'/api/hello': ['./un-necessary-folder/**/*'],
},
outputFileTracingIncludes: {
'/api/another': ['./necessary-folder/**/*'],
'/api/login/\\[\\[\\.\\.\\.slug\\]\\]': [
'./node_modules/aws-crt/dist/bin/**/*',
],
},
}
注意: outputFileTracingIncludes
/outputFileTracingExcludes
のキーは glob であるため、特殊文字はエスケープする必要があります。
- 現在のところ、Next.js は出力された
.nft.json
ファイルに対して何も行いません。ファイルは、たとえば Vercel などのデプロイメントプラットフォームによって読み取られ、最小限のデプロイメントを作成する必要があります。将来のリリースでは、これらの.nft.json
ファイルを利用する新しいコマンドが予定されています。
実験的な turbotrace
依存関係をトレースすることは、非常に複雑な計算と分析を必要とするため、遅くなることがあります。私たちは、JavaScript の実装に代わるより高速で賢い代替手段として Rust で turbotrace
を作成しました。
有効にするには、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のコンテキストディレクトリを制御します
// コンテキストディレクトリの外側のファイルはトレースされません
// `outputFileTracingRoot`を設定することで同じ効果が得られます
// `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
},
},
}