문서
App Router 사용하기
output

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에서 활성화할 수 있습니다:

next.config.js
module.exports = {
  output: "standalone",
};

이렇게 하면 .next/standalone에 폴더가 생성되며, 이 폴더는 node_modules를 설치하지 않고도 독립적으로 배포할 수 있습니다.

또한, 최소한의 server.js 파일도 출력되며 이는 next start 대신 사용할 수 있습니다. 이 최소 서버는 기본적으로 public 또는 .next/static 폴더를 복사하지 않습니다. 이 폴더들은 이상적으로는 CDN에 의해 처리되어야 하지만, 수동으로 standalone/publicstandalone/.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를 설정할 수 있습니다.
packages/web-app/next.config.js
module.exports = {
  // 이는 모노레포 기반에서 두 디렉토리 위의 파일을 포함합니다
  outputFileTracingRoot: path.join(__dirname, "../../"),
};
  • Next.js가 필요한 파일을 포함하지 못하거나 사용되지 않는 파일을 잘못 포함하는 경우가 있을 수 있습니다. 이런 경우에는 next.config.js에서 각각 outputFileTracingExcludesoutputFileTracingIncludes를 활용할 수 있습니다. 각 설정은 특정 페이지와 일치하는 키에 대해 minimatch globs를 사용하는 객체를 받으며, 값은 프로젝트 루트에 상대적인 글로브의 배열로 추적에 포함하거나 제외할 수 있습니다.
next.config.js
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에 다음 설정을 추가할 수 있습니다:

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
    },
  },
}