Next.js에서는 빌드가 어떻게 이루어질까?

지인·2023년 6월 26일
0

TIL

목록 보기
7/17
post-thumbnail

💡 아래 내용은 Next.js 13+ 버젼 / App dir 관련 내용을 공부하며 이해했던 내용을 다루고 있습니다. 혹시 틀린 정보가 있다면 알려주시면 감사하겠습니다!

Next.js에서는 빌드할때 다음과 같은 프로세스로 이루어진다.

  1. 페이지 분석
    먼저, Next.js는 페이지 파일(.js, .jsx, .ts, .tsx, .md, .mdx 등)을 찾기 위해 App 디렉토리를 탐색합니다. 각 페이지 파일은 그 자체로 하나의 라우트를 정의하며, 해당 페이지에 필요한 코드를 내포하고 있습니다.
  1. 종속성 그래프 생성(모듈 그래프)
    다음으로, Next.js는 각 페이지의 종속성을 분석하여 서버와 클라이언트의 모듈 그래프를 생성합니다. 이 때, webpack이라는 빌드 도구가 사용됩니다. webpack은 소스 코드의 각 모듈이 어떤 다른 모듈에 의존하는지 파악하고, 그러한 의존성 관계를 모듈 그래프로 표현합니다.

💡 모듈이란 프로그램을 구성하는 개별 요소로, 특정 기능을 수행하는 코드의 모음입니다. JavaScript에서는 모듈을 이용해 코드를 분리하고 재사용할 수 있습니다. 각 모듈은 자체 스코프를 가지며, 다른 모듈로부터 독립적으로 동작합니다.

💡이 때, 하나의 모듈이 다른 모듈에 의존하게 되면, 이를 종속성이라고 합니다. 예를 들어, 모듈 A가 모듈 B의 기능을 필요로 할 때, 우리는 "모듈 A가 모듈 B에 종속되어 있다"라고 말합니다.

  1. 코드 변경 및 번들링
    생성된 모듈 그래프를 바탕으로, Next.js는 Babel을 사용하여 최신 자바스크립트 코드를 브라우저에서 동작 가능한 코드로 변환합니다. 그 후, webpack은 변환된 코드를 하나 또는 여러 개의 번들로 패키징합니다.

  2. 최적화
    Next.js는 여러 최적화 단계를 수행합니다. 예를 들어, 불필요한 코드를 제거하는 트리 쉐이킹(tree shaking)을 수행하거나, 코드를 최소화(minify)하여 번들 크기를 줄입니다. 또한, 자동 코드 분할을 통해 각 페이지가 필요로 하는 코드만을 로드하도록 합니다.

  3. 정적 사이트 생성
    Next.js는 정적 사이트 생성(SSG) 기능을 사용하여 구축 시 모든 경로에 대한 정적 HTML 페이지를 생성할 수 있습니다. 페이지 파일에서 사용되는 데이터 가져오기 방법 유형에 따라 사용할 렌더링 전략(SSG 또는 서버 측 렌더링)을 결정합니다. 그러나 정적 사이트를 만드는 것은 하나의 옵션일 뿐입니다. Next.js는 정적 및 서버 렌더링 페이지가 있는 하이브리드 애플리케이션도 지원합니다.


빌드 단계 중 서버 컴포넌트와 클라이언트 컴포넌트는 어디서 나뉘어질까?

결론부터 말하자면, 위에서 알아봤던 Next가 빌드되는 프로세스 중 2번-종속성 그래프를 생성하는 과정에서 나뉘어진다.

getStaticProps(ISR, SSG), getServersideProps(SSR)를 이용해 페이지 단위로 렌더링 되던 기존 Next와 달리 Next.13 버전에서는 서버 컴포넌트와 클래스 컴포넌트를 나눠 컴포넌트 단위로 렌더링 되도록 변경되었다.

아래 그림은 Next가 클라이언트 컴포넌트를 어떤식으로 관리하는지 보여준다.

use client 키워드가 종속성 그래프를 생성하는 과정에서 서버 컴포넌트와 클라이언트 컴포넌트를 구분 짓는 경계선 역할을 하기 때문에 맨위에 써줘야한다.(import 보다도 위에)

어떤 상황에서 서버 컴포넌트 / 클라이언트 컴포넌트로 작성해야하는지에 대한 가이드라인은 다음과 같다. 생각보다 훨씬 많은 상황에서 서버 컴포넌트를 사용할 것을 권장하고 있다.

서버 컴포넌트, 클라이언트 컴포넌트를 분리할 때 권장되는 하나의 패턴
(아래와 같이 컴포넌트 단위로 아주 잘게 잘라서 하나의 서버 컴포넌트에서 합치는 것이 권장된다. )

app/layout.tsx

// SearchBar is a Client Component
import SearchBar from './searchbar'
// Logo is a Server Component
import Logo from './logo'
 
// Layout is a Server Component by default
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <nav>
        <Logo />
        <SearchBar />
      </nav>
      <main>{children}</main>
    </>
  )
}

추가적으로, 서버 컴포넌트에서 클라이언트 컴포넌트를 Import 하려하거나 라이브러리를 사용해서 컴포넌트를 Import하려고 할때 문제가 생길 수 있는데, 다음 블로그를 참조하면 좋다.
Server component vs. Client Component

profile
안녕하세요

0개의 댓글