홍승아블로그

Nextjs(v13)

설치

  npm i next@latest react@latest react-dom@latest eslint-config-next@latest
  # or
  yarn upgrade next react react-dom eslint-config-next --latest
  # or
  pnpm up next react react-dom eslint-config-next --latest

요약

  • 지원하는 브라우저에서 Internet Explorer를 삭제하고, 최신 브라우저를 지원하는걸로 변경되었습니다.
    • Chrome 64+
    • Edge 79+
    • Firefox 67+
    • Opera 51+
    • Safari 12+
  • 최소 Node 버전이 12.22.0 → 14.0.0 으로 변경되었습니다.
  • 최소 React 버전도 17.0.2 → 18.2.0 으로 변경되었습니다.
  • swcMinify 기본 환경설정이 false → true로 변경되었습니다.
  • NextJS 12에서 소개된 신규 이미지 next/future/image → next/image, next/image → next/legacy/image로 변경되었습니다.
    • 자동변환을 위해서 codemod를 지원합니다.(next-image-to-legacy-image)
  • 기존에 Next/Link 사용 시 하위에 추가했어야했지만, 13버전 부터는 a link가 필요없습니다.

신규 라우팅(beta)

page 디렉토리 라우팅 시스템 → app 디렉토리 기반 라우팅 시스템으로 전환

변경 전

pages
 ┣ blog
 ┣ dashboard
 ┃ ┗ [id].tsx
 ┃ ┗ index.tsx
 ┣ _app.tsx
 ┗ index.tsx

변경 후 Untitled

라우팅 파일만 관리 → 라우팅 파일 외에 해당 페이지에서 구성하는 파일도 같이 두는 방식으로 변경

변경 전

components
 ┗ Card.jsx
pages
 ┣ posts
 ┃ ┗ datas
 ┃ ┃ ┗ index.js
 ┣ _app.js
 ┗ index.js
styles
 ┣ Home.module.css
 ┗ globals.css

변경 후 Untitled

route segments

각 라우팅은 폴더 패스의 단위로 URL 패스가 정해진다. Untitled

special files

라우팅에 사용되는 특별한 파일들을 사용할 수 있습니다. Untitled

  • pages.js

    • 라우팅을 통해서 페이지에 접근 시 보여주는 파일
    • 기존 index.js와 동일한 기능을 수행한다.
    • page/index.js → app/index.js
  • layout.js

    • 여러 페이지에서 여러곳에 적용하기 위해서 사용되는 레이아웃 파일
    • 기존에도 _app.tsx에서 루트 공통 스타일 정도만 적용이 가능하지만, layout.js가 추가됨에 따라서 중첩으로 부모 스타일 상속이 가능하다.
    // 변경 전
    // pages/_app.tsx
    
    function MyApp({ Component, pageProps }: AppPropsWithLayout) {
      // Use the layout defined at the page level, if available
      const getLayout = Component.getLayout ?? ((page) => page);
    
      return (
        <section>
         <Component {...pageProps} />
        </section>
      );
    }
    
    export default MyApp;
    
    // 변경 후
    // pages/layout.tsx
    function MyAppLayout({ children }: React.ReactNode) {
      return (
        <section>
          {children}
        </section>
      );
    }
    

    Untitled

  • loading.js

    • 앱에 특정 부분에 사용되는 로딩 UI를 생성하는데 사용되는 파일(React Suspense Boundary)
  • error.js

    • 하위 트리에서 오류가 발생 시 호출되는 에러 컴포넌트(React Suspense Boundary)
  • template.js

    • 특정 동작이 필요한 경우에 사용되는 파일
    • CSS 또는 애니메이션 라이브러리를 사용하여 애니메이션을 시작/종료
    • useEffect(예: 페이지 보기 기록) 및 useState(예: 페이지별 피드백 양식)에 의존하는 기능
    • 기본 프레임워크 동작을 변경합니다. 예를 들어 레이아웃 내부의 서스펜스 경계는 페이지를 전환할 때가 아니라 레이아웃이 처음 로드될 때만 폴백을 표시합니다. 템플릿의 경우 각 탐색에 폴백이 표시됩니다.
  • head.js

    • 태그의 컨텐츠를 정의할 경우 사용된다.
  • not-found.js

    • 페이지를 찾지 못할 경우 호출됨

server components

React 18에서 나온 서버 컴포넌트 아키텍쳐 지원 서버 구성 요소를 사용하여 클라이언트에 전송되는 자바스크립트 양을 줄여 초기 로딩 성능 개선 Untitled

streaming

서버 구성 요소 및 중첩된 레이아웃 사용하면 부분적 데이터 로드 상태를 제어가 가능합니다. 해당 방식을 통해서 사용자는 초기 로딩 시 전체페이지가 로드될 때까지 기다릴 필요가 없어짐. Untitled data fetch에 대한 사용법 변경

  • getStaticProps → fetch(URL, { cache: ‘force-cache’ });
  • getServerSideProps → fetch(URL, { cache: ‘no-store’ });
  • getStaticProps: revalidate → fetch(URL, { next: { revalidate: 10 } });
// nextjs 13 이전
export const getServerSideProps: GetStaticProps = async ({ params }) => {
  const res = await fetch('https://.../posts/');
  const data = await res.json();

  return data;
};
// This is an async Server Component
export default async function Page(data) {
  return <main>{/* ... */}</main>;
}

// nextjs13
// app/page.js
async function getData() {
  const res = await fetch('https://api.example.com/...');
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.
  return res.json();
}

// This is an async Server Component
export default async function Page() {
  const data = await getData();

  return <main>{/* ... */}</main>;
}

Turbopack(alpha)

NextJs 13에서 webpack의 후속 제품인 Rust 기반에 Turbopack 패키지 소개

  • Webpack 보다 700x faster 향상
  • Vite 보다 10x faster 향상
  • 초기 실행 시간이 Webpack 보다 4x faster향상style Untitled
// 설치
next dev --turbo

New next/image

이미지 컴포넌트 사용 시 자동으로 최적화 진행(layout shift 방지를 위해서 width, height 자동 설정) 웹접근성 향상을 위해서 alt.속성이 필수로 속성으로 추가

// nextjs 12 이전
import Image from 'next/image';
import avatar from './lee.png';

function Home() {
  // "alt" is now required for improved accessibility
  // optional: image files can be colocated inside the app/ directory
  return <Image src={avatar} placeholder="blur" width={50} height={50} />;
}

// nextjs 13
import Image from 'next/image';
import avatar from './lee.png';

function Home() {
  // "alt" is now required for improved accessibility
  // optional: image files can be colocated inside the app/ directory
  return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}

New @next/font (beta)

글꼴 파일에 대한 자동 자체 호스팅 지원 - 성능과 개인정보 보호 지원을 목적 Google 글꼴 폰트 내장, 로컬 폰트 호스팅 지원

// next13 이전
<Head>
  <link
    href="https://fonts.googleapis.com/css2?family=Montserrat:wght@200;400&display=swap"
    rel="stylesheet"
  />
</Head>

// next13
//// 내장 구글 글꼴 폰트
import { Inter } from '@next/font/google';
const inter = Inter();
<html className={inter.className}>

//// 로컬 폰트
import localFont from '@next/font/local';
const myFont = localFont({ src: './my-font.woff2' });
<html className={myFont.className}>

디바이스별로 화면의 크기에 따라서 폰트 사이즈가 변하는 이슈 해결을 위한 css에 size-adjust 속성을 사용하여서 모든 디바이스에서 동일한 폰트 사이즈를 제공

html,
body {
  -webkit-text-size-adjust: none; /* 크롬, 사파리, 오페라 신버전 */
  -ms-text-size-adjust: none; /* IE */
  -moz-text-size-adjust: none; /* 파이어폭스 */
  -o-text-size-adjust: none; /* 오페라 구버전 */
}

Improved next/link

기존에 next/link 사용 시 a tag가 꼭 필요했었지만, 13 버전에서는 a tag를 추가하지 않아도 됩니다. 12.2 버전에서 실험적인 옵션으로 추가되었었고, 현재 13버전에는 디폴트로 적용됩니다.

import Link from 'next/link'

// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
  <a>About</a>
</Link>

// Next.js 13: `<Link>` always renders `<a>`
<Link href="/about">
  About
</Link>

참고페이지

이전글
리액트 상태관리 정리
다음글
react-hook-form v7