output
빌드 중에 Next.js는 각 페이지와 그 종속성을 자동으로 추적하여 애플리케이션의 프로덕션 버전을 배포하는 데 필요한 모든 파일을 결정합니다.
이 기능은 배포 크기를 크게 줄이는 데 도움이 됩니다. 이전에는 Docker로 배포할 때 next start
를 실행하기 위해 패키지의 dependencies
에 있는 모든 파일을 설치해야 했습니다. Next.js 12부터는 .next/
디렉토리의 Output File Tracing을 활용하여 필요한 파일만 포함할 수 있습니다.
또한, 이는 다양한 문제를 일으킬 수 있고 불필요한 중복을 생성하는 serverless
타겟을 사용할 필요성을 제거합니다.
How it Works
next build
중에 Next.js는 @vercel/nft
(opens in a new tab)를 사용하여 import
, require
및 fs
사용을 정적으로 분석하여 페이지가 로드할 수 있는 모든 파일을 결정합니다.
Next.js의 프로덕션 서버도 필요한 파일을 추적하여 .next/next-server.js.nft.json
에 출력되며, 이는 프로덕션에서 활용할 수 있습니다.
.next
출력 디렉토리에 생성된 .nft.json
파일을 활용하려면, 각 추적 파일 목록을 읽어 해당 파일을 배포 위치에 복사할 수 있습니다.
Automatically Copying Traced Files
Next.js는 프로덕션 배포에 필요한 파일만 복사하는 standalone
폴더를 자동으로 생성할 수 있습니다. 여기에는 node_modules
의 선택된 파일도 포함됩니다.
이 자동 복사를 활용하려면 next.config.js
에서 이를 활성화할 수 있습니다:
module.exports = {
output: 'standalone',
}
이렇게 하면 .next/standalone
폴더가 생성되며, 이는 node_modules
를 설치하지 않고도 자체적으로 배포할 수 있습니다.
또한, next start
대신 사용할 수 있는 최소한의 server.js
파일도 출력됩니다. 이 최소한의 서버는 기본적으로 public
또는 .next/static
폴더를 복사하지 않으며, 이러한 폴더는 이상적으로 CDN에서 처리되어야 합니다. 그러나 이러한 폴더를 standalone/public
및 standalone/.next/static
폴더로 수동으로 복사한 후 server.js
파일이 이를 자동으로 서비스합니다.
참고:
next.config.js
는next build
중에 읽히며server.js
출력 파일에 직렬화됩니다. 레거시serverRuntimeConfig
또는publicRuntimeConfig
옵션을 사용하는 경우, 값은 빌드 시점의 값에 따라 달라집니다.- 프로젝트가 특정 포트 또는 호스트 이름을 수신해야 하는 경우,
server.js
를 실행하기 전에PORT
또는HOSTNAME
환경 변수를 정의할 수 있습니다. 예를 들어,PORT=8080 HOSTNAME=0.0.0.0 node server.js
를 실행하여 서버를http://0.0.0.0:8080
에서 시작할 수 있습니다.
Caveats
- 모노레포 설정에서 추적할 때 프로젝트 디렉토리가 기본적으로 추적에 사용됩니다.
next build packages/web-app
의 경우,packages/web-app
이 추적 루트가 되며 해당 폴더 외부의 파일은 포함되지 않습니다. 이 폴더 외부의 파일을 포함하려면next.config.js
에서experimental.outputFileTracingRoot
를 설정할 수 있습니다.
module.exports = {
experimental: {
// 모노레포 베이스에서 두 디렉토리 위의 파일을 포함합니다
outputFileTracingRoot: path.join(__dirname, '../../'),
},
}
- Next.js가 필요한 파일을 포함하지 못하거나 사용하지 않는 파일을 잘못 포함하는 경우가 있습니다. 이러한 경우,
next.config.js
에서 각각experimental.outputFileTracingExcludes
및experimental.outputFileTracingIncludes
를 활용할 수 있습니다. 각 구성은 특정 페이지와 일치하는 키에 대한 minimatch globs (opens in a new tab)를 사용하고, 프로젝트의 루트에 상대적인 glob 배열을 값으로 가질 수 있습니다.
module.exports = {
experimental: {
outputFileTracingExcludes: {
'/api/hello': ['./un-necessary-folder/**/*'],
},
outputFileTracingIncludes: {
'/api/another': ['./necessary-folder/**/*'],
},
},
}
- 현재 Next.js는 생성된
.nft.json
파일로 아무것도 하지 않습니다. 예를 들어 Vercel (opens in a new tab)과 같은 배포 플랫폼이 최소 배포를 생성하기 위해 이 파일을 읽어야 합니다. 향후 릴리스에서는 이.nft.json
파일을 활용하는 새로운 명령어가 계획되어 있습니다.
Experimental 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
},
},
}