2. FrontEnd/Next.js / / 2023. 11. 21. 15:12

[Next.js] 12와 13,14의 차이

728x90

Next를 12버전을 쓰다가 이번에 내 웹사이트를 만들려고 14로 깔았는데, 바뀌었다고만들었지 실제로 설치하고 보니까 
폴더구조부터 완전 변해서 다시 공부하고 셋팅을 했다.

이 과정에서 뭐가 바뀌었는지에 대해 작성하려고한다.

우선, Next 14버전을 깔고 초기셋팅한 내 구조와 12버전에 있을때는, pages폴더 안에 파일을 생성하면 거기로 바로 페이지가 만들어져있는것을 확인할 수 있다.


공식Docs를 기반으로 공부하고 정리한 글입니다.

자동 설치

npx create-next-app@latest

//아래와 같은 질문들이 나오는데 이거에 사용할 모듈들 선택해서 설치
What is your project named? 앱 이름
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
What import alias would you like configured? @/*

Next.js는 파일 시스템 라우팅을 사용하는데, 파일을 구조화하는 방법에 따라 응용프로그램의 경로가 결정됨을 의미함


📁 폴더구조

- app 폴더 (디폴트)

새로운 앱의 경우는 Next에서 App라우터를 사용하기를 권장하고 있다. (그래서 app폴더로 셋팅이 된 것)
이유 : 앱 라우터의 경우 React의 최신 기능을 사용할수 있고, 커뮤니티의 피드백을 기반으로 page라우터의 진화버전

app/layout.tsx : 루트 레이아웃 코드가 있음(html, body태그)
app/page.tsx : 기본 초기 콘텐츠가 포함된 홈페이지 (/)

(* layout.tsx 생성하는 것을 잊은 경우, Next.js는  next dev 으로 개발 서버를 실행할 때 자동으로 이 파일을 생성한다)

- page 폴더 (옵션)

새로운 app 라우터 대신 기존의 page 라우터를 사용하려는 경우,  프로젝트 루트에  pages/ 폴더를 만들어도 된다.
그 후, index.tsx 파일을 만들어 (/) 홈페이지를 만들고, _app.tsx 파일을 만들어 전역 레이아웃을 정의하면 된다.
서버의 초기 응답을 제어하기 위해 _document.tsx 파일을 추가한다.

//pages/index.tsx
export default function Page() {
  return <h1>Hello, Next.js!</h1>
}

//pages/_app.tsx
import type { AppProps } from 'next/app'
 
export default function App({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

//pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
 
export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

- public 폴더

이미지, 글꼴 등과 같은 정적 자산을 저장할 폴더
기본 URL( /)에서 시작하는 코드에서 디렉터리 내의 파일을 참조할 수 있다.


App Router

Next.js 13에서 는 공유 레이아웃, 중첩 라우팅, 로딩 상태, 오류 처리 등을 지원하는 React Server Components를 기반으로 구축된 새로운 app 라우터를 도입했다.

App Router는 app이라는 새 폴더에서 작동한다.
app 폴더 pages 폴더 와 함께 작동하여 점진적으로 채택할 수 있습니다. 이렇게 하면 이전 동작을 위해 페이지 디렉터리에 다른 경로를 유지하면서 응용 프로그램의 일부 경로를 새 동작으로 선택할 수 있습니다.
내 앱이 pages 폴더를 사용하는 경우 Pages Router 설명서도 참조하십시오.

알아두면 좋은 점 : App Router는 Pages Router보다 우선순위가 높다. 디렉터리 간 경로는 동일한 URL 경로로 확인되어서는 안 되며 충돌을 방지하기 위해 빌드 시간 오류가 발생합니다.

폴더 및 파일의 역할

Next.js는 파일 시스템 기반 라우터를 사용한다.

폴더는 경로를 정의하는 데 사용됩니다.
경로는 루트폴더부터 파일이 포함된 최종 리프 폴더 까지 파일 시스템 계층 구조를 따라가는 중첩된 폴더의 단일 경로이다
파일은 경로 세그먼트에 표시되는 UI를 만드는 데 사용됩니다. 


Colocation

 

특별한 파일 외에도 앱 디렉토리의 폴더 안에 있는 자신의 파일(예: 구성 요소, 스타일, 테스트 등)을 코로케이션할 수 있는 옵션이 있습니다.

폴더가 경로를 정의하는 동안 page.js 또는 route.js로 반환되는 내용만 공개 주소 지정이 가능하기 때문입니다.

 

 

- 프로젝트 구성 및 파일 코로케이션

app폴더에서 폴더 계층은 경로 구조를 의미한다.

각 폴더는 URL=경로의 해당 세그먼트에 매핑되는 경로 세그먼트를 나타냄

그러나 폴더를 통해 루트 구조를 정의하더라도 page.js 또는 route.js 파일을 루트 세그먼트에 추가하기 전에는 루트에 공개적으로 액세스할 수 없다.

그리고 경로가 공개적으로 접근 가능하게 된 경우에도 page.js 또는 route.js로 반환된 내용만 클라이언트로 전송됩니다.

이는 프로젝트 파일이 실수로 라우팅 가능하지 않고 app폴더의 경로 세그먼트 내부에 안전하게 위치할 수 있음을 의미

알면 좋은점 : 
이것은 페이지에 있는 모든 파일이 경로로 간주되는 페이지 디렉토리와는 다름
프로젝트 파일을 앱에서 코로케이팅할 수 있지만 그럴 필요가 없습니다. 원한다면 앱 디렉토리 외부에 보관가능

- 개인 폴더

 

개인 폴더는 폴더 앞에 밑줄을 붙여 생성할 수 있다.  _folderName

이는 폴더가 비공개 구현 세부 사항이므로 라우팅 시스템에서 고려해서는 안 되므로 폴더와 모든 하위 폴더를 라우팅에서 제외함을 나타냅니다.

 

- 경로 그룹

 

경로 그룹은 폴더를 괄호로 묶어 생성할 수 있다.(folderName)

이는 폴더가 조직화 목적으로 사용되며 경로의 URL 경로에 포함되어서는 안 됨을 나타냅니다.

 


Layouts

레이아웃은 여러 페이지 간에 공유되는 UI입니다. 
탐색에서 레이아웃은 상태를 유지하고 대화형으로 유지되며 다시 렌더링하지 않습니다. 레이아웃을 중첩할 수도 있습니다.

기본적으로 layout.js 파일에서 React 구성요소를 내보내면서 레이아웃을 정의할 수 있습니다. 구성요소는 렌더링 중에 자식 레이아웃(존재하는 경우) 또는 자식 페이지로 채워지는 자식 프로프를 받아들여야 합니다.

 

Root Layout : 맨 위에 있는 레이아웃을 루트 레이아웃
- 응용 프로그램의 모든 페이지에서 공유된다
- Root Layout은 html과 body 태그를 포함해야 한다.
(*루트 레이아웃에만 <html>및 <body>태그가 포함될 수 있다.)

layout.js와 page.js 파일을 같은 폴더에 정의할 수 있습니다. 레이아웃이 페이지를 감쌀 것입니다.
js, .jsx 또는 .tsx 파일 확장자를 레이아웃에 사용할 수 있다.

모든 경로 세그먼트는 선택적으로 자신의 Layout을 정의할 수 있다. 이러한Layout은 해당 세그먼트의 모든 페이지에서 공유됨. 경로의 레이아웃은 기본적으로 중첩됩니다. 각 부모 레이아웃은 React children prop을 사용하여 자식 레이아웃을 그 아래에 래핑합니다.경로 그룹을 사용하여 공유 레이아웃 내부 및 외부의 특정 경로 세그먼트를 선택할 수 있습니다.레이아웃은 기본적으로 서버 구성요소이지만 클라이언트 구성요소로 설정할 수 있습니다.레이아웃은 데이터를 가져올 수 있습니다. 자세한 내용은 데이터 가져오기 섹션을 참조하십시오.

부모 레이아웃과 자식 레이아웃 사이에 데이터를 전달하는 것은 불가능
그러나 동일한 데이터를 여러 번 경로로 가져올 수 있으며 React는 성능에 영향을 주지 않고 요청을 자동으로 제거합니다.레이아웃은 아래에 있는 경로 세그먼트에 액세스할 수 없습니다.
모든 경로 세그먼트에 액세스하려면 클라이언트 구성요소에서 SelectedLayoutSegment를 사용하거나 SelectedLayoutSegment를 사용할 수 있습니다..
//app/layout.tsx (필수사항)
//(중요) 루트 레이아웃에만 <html>및 <body>태그가 포함될 수 있습니다.
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

//app/about/layout.tsx
export default function AboutLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>
 
      {children}
    </section>
  )
}

- 중첩 레이아웃

 

폴더 내부에 정의된 레이아웃(예: app/ about/ layout.js)은 특정 경로 세그먼트(예: localhost:3000/about) 에 적용되며 해당 세그먼트가 활성화된 경우 렌더링된다. 기본적으로 파일 계층의 레이아웃은 중첩되므로 children prop을 통해 하위 레이아웃을 래핑합니다.

 

위의 두 레이아웃을 결합하는 경우
app/layout.js은 app/dashboard/layout.js을 감싸며, 이 레이아웃은 app/dashboard/* 내부의 경로 세그먼트를 감싸게 됩니다.

두 레이아웃은 다음과 같이 중첩됩니다:

 

 

 

 


Templates 

Templates은 각 child layout이나 page를 감싼다는 점에서 layouts과 유사하다. 

여러 경로에 걸쳐 지속되고 상태를 유지하는 layouts과 달리
Templatesnavigation될때마다 children 각각에 대한 새 인스턴스를 생성합니다. 이는 사용자가 template을 공유하는 경로 사이를 이동할 때 component의 새 인스턴스가 마운트되고 DOM 요소가 다시 생성되고 상태가 보존되지 않으며 효과가 다시 동기화됨을 의미합니다.

특정 동작이 필요한 경우가 있을 수 있으며 레이아웃보다는 템플릿이 더 적합한 옵션일 것입니다. 예를 들어 다음과 같다

- useEffect(예: 페이지 보기 기록) 및 useState(예: 페이지별 피드백 양식)에 의존하는 기능입니다.
- 기본 프레임워크 동작을 변경하려면 레이아웃 내부의 서스펜스 경계는 레이아웃이 처음 로드될 때만 폴백을 표시하고 페이지를 전환할 때는 표시하지 않습니다. 템플릿의 경우 폴백이 각 탐색에 표시됩니다.


template은 template.js 파일에서 기본 React component를 내보내서(export) 정의할 수 있습니다. componentchildren prop을 사용해야 합니다.

export default function Template({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>
}

중첩 측면에서 template.js는 레이아웃과 하위 레이아웃 사이에서 렌더링됩니다. 다음은 단순화된 출력입니다:

<Layout>
  {/* Note that the template is given a unique key. */}
  <Template key={routeParam}>{children}</Template>
</Layout>

 

 

 

 

 

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유