output
빌드 중에 Next.js는 각 페이지와 그 종속성을 자동으로 추적하여 애플리케이션의 프로덕션 버전을 배포하는 데 필요한 모든 파일을 결정합니다.
이 기능은 배포 크기를 대폭 줄이는 데 도움이 됩니다. 이전에는 Docker로 배포할 때 next start
를 실행하기 위해 패키지의 dependencies
에서 모든 파일을 설치해야 했습니다. 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는 node_modules
의 선택된 파일을 포함하여 프로덕션 배포에 필요한 파일만 복사하는 standalone
폴더를 자동으로 생성할 수 있습니다.
이 자동 복사를 활용하려면 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
파일이 이를 자동으로 제공합니다.
알아두면 좋은 점:
- 프로젝트가 특정 포트나 호스트네임을 listen해야 하는 경우,
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
이 분석의 기준점이 되며, 해당 폴더 외부의 파일은 포함되지 않습니다. 이 폴더 외부의 파일을 포함하려면next.config.js
에서outputFileTracingRoot
를 설정할 수 있습니다.
module.exports = {
// 이는 모노레포 기반에서 두 디렉토리 위의 파일을 포함합니다
outputFileTracingRoot: path.join(__dirname, "../../"),
};
- Next.js가 필요한 파일을 포함하지 못하거나 사용되지 않는 파일을 잘못 포함하는 경우가 있을 수 있습니다. 이런 경우에는
next.config.js
에서 각각outputFileTracingExcludes
와outputFileTracingIncludes
를 활용할 수 있습니다. 각 설정은 특정 페이지와 일치하는 키에 대해 minimatch 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()` 표현식이 있는 경우, 이 옵션을 설정하여 추적 중 `process.cwd()`의 값을 `turbotrace`에 알려줄 수 있습니다.
// 예를 들어 require(process.cwd() + '/package.json')는 require('/path/to/cwd/package.json')로 추적됩니다
processCwd?: string
// `turbotrace`의 최대 메모리 사용량을 제어합니다. `MB` 단위이며 기본값은 `6000`입니다.
memoryLimit?: number
},
},
}