output
build の間に、Next.js は各ページとその依存関係を自動的に追跡し、アプリケーションの production version をデプロイするために必要なすべてのファイルを決定します。
この機能は、size、つまりデプロイメントのサイズを大幅に削減します。以前は、Docker でデプロイする際には、dependencies
のすべてのファイルをインストールしてnext start
を実行する必要がありました。しかし、Next.js12 からは、.next/
ディレクトリの Output File Tracing を活用して、必要なファイルのみを含めることができます。
さらに、これにより非推奨の serverless
target が必要なくなり、さまざまな問題を引き起こしたり、不必要な重複を作り出したりすることを防ぎます。
How it Works
next build
の間に、Next.js は@vercel/nft
を使ってimport
、require
、そしてfs
の使用を静的に分析し、ページが読み込み可能な全ファイルを特定します。
Next.js の production server もその必要なファイルのために追跡され、.next/next-server.js.nft.json
で出力されます。これは production で活用できます。
.nft.json
ファイルが.next
出力ディレクトリに出力されるのを利用するには、各トレースで.nft.json
ファイルに相対的なファイルのリストを読み込み、それらをあなたのデプロイメント位置にコピーすることができます。
Automatically Copying Traced Files
Next.js は、node_modules
内の選択されたファイルを含む production デプロイメントのための必要なファイルのみをコピーするstandalone
フォルダを自動的に作成することができます。
この自動コピーツールを活用するために、あなたのnext.config.js
でそれを有効にすることができます:
module.exports = {
output: 'standalone',
}
これにより、.next/standalone
にフォルダが作成され、node_modules
をインストールせずに単体でデプロイすることができます。
さらに、最小限のserver.js
ファイルも出力されます。これはnext start
の代わりに使用することができます。この最小限の server は、通常これらは CDN によって処理されるべきであるため、public
や.next/static
フォルダを default でコピーしません。ただし、これらのフォルダはstandalone/public
およびstandalone/.next/static
フォルダに手動でコピーすることができ、その後server.js
ファイルはこれらを自動的に提供します。
Good to know:
- もしプロジェクトが特定の port または hostname を listen する必要がある場合、
server.js
を実行する前にPORT
またはHOSTNAME
の environment variables を定義できます。例えば、http://0.0.0.0:8080
上で server を start するには、PORT=8080 HOSTNAME=0.0.0.0 node server.js
を実行します。- あなたのプロジェクトがImage Optimizationを default の
loader
として使用している場合、依存関係としてsharp
をインストールする必要があります。
npm i sharp
yarn add sharp
pnpm add sharp
bun add sharp
Caveats
- モノレポのセットアップでトレースを行う際には、プロジェクトディレクトリが default としてトレースに使用されます。
next build packages/web-app
の場合、packages/web-app
がトレースの root となり、そのフォルダの外側のファイルは含まれません。このフォルダの外側のファイルを含めるためには、next.config.js
内でexperimental.outputFileTracingRoot
を設定できます。
module.exports = {
experimental: {
// this includes files from the monorepo base two directories up
outputFileTracingRoot: path.join(__dirname, '../../'),
},
}
- Next.js が必要なファイルを含めることができない場合や、不要なファイルを誤って含める可能性がある場合があります。そのような場合には、
next.config.js
の中でそれぞれexperimental.outputFileTracingExcludes
とexperimental.outputFileTracingIncludes
を活用できます。各 config には、特定のページを一致させるためのキーを持つminimatch globs の object を受け入れ、トレースの中で含めるか除外するかを指定するプロジェクトの root に対する相対的な globs の配列の value を受け入れます。
module.exports = {
experimental: {
outputFileTracingExcludes: {
'/api/hello': ['./un-necessary-folder/**/*'],
},
outputFileTracingIncludes: {
'/api/another': ['./necessary-folder/**/*'],
},
},
}
- 現在、Next.js は発行された
.nft.json
ファイルを操作しません。これらのファイルは、例えばVercel などのデプロイメントプラットフォームで読み込む必要があり、最小のデプロイメントを作成します。将来のリリースでは、これらの.nft.json
ファイルを利用する新しいコマンドが計画されています。
Experimental turbotrace
依存関係の追跡は、非常に複雑な計算や分析を必要とするため、遅くなることがあります。我々は、JavaScript の実装に対するより速く、より賢い代替手段として、Rust でturbotrace
を作成しました。
それを有効にするために、次の設定をnext.config.js
に追加することができます:
module.exports = {
experimental: {
turbotrace: {
// control the log level of the turbotrace, default is `error`
logLevel?:
| 'bug'
| 'fatal'
| 'error'
| 'warning'
| 'hint'
| 'note'
| 'suggestions'
| 'info',
// control if the log of turbotrace should contain the details of the analysis, default is `false`
logDetail?: boolean
// show all log messages without limit
// turbotrace only show 1 log message for each categories by default
logAll?: boolean
// control the context directory of the turbotrace
// files outside of the context directory will not be traced
// set the `experimental.outputFileTracingRoot` has the same effect
// if the `experimental.outputFileTracingRoot` and this option are both set, the `experimental.turbotrace.contextDirectory` will be used
contextDirectory?: string
// if there is `process.cwd()` expression in your code, you can set this option to tell `turbotrace` the value of `process.cwd()` while tracing.
// for example the require(process.cwd() + '/package.json') will be traced as require('/path/to/cwd/package.json')
processCwd?: string
// control the maximum memory usage of the `turbotrace`, in `MB`, default is `6000`.
memoryLimit?: number
},
},
}