Next.js 13 업데이트 정리 (13.1기준)

MIMI·2023년 1월 4일
2

Next.js 13 (13.1 기준)

  1. app 디렉토리 생성 및 개선 (beta)
  2. Turbopack 생성 및 업데이트 (alpha)
  3. New next/image (stable)
  4. New @next/font (beta)
  5. Improved next/link
  6. Built-in Module Transpilation
  7. Edge Runtime (Stable)
  8. Middleware Improvements
  9. SWC Import Resolution

1. app 디렉토리

  • 새로운 라우팅 및 데이터 가져오기 시스템
    • 기존의 pages/(stable) 와 신생의 app/(beta) 둘 다 사용 가능하지만 아직 프로덕션 환경에서는 기존 방식을 사용하는 게 좋음
    • 추후 안정화되면 pages 디렉토리를 대체하게 될 듯
  • 주요 특징
    • Layouts
    • React Server Components
    • Streaming
    • Support for Data Fetching
// next.config.js
/* 
app 디렉토리에서 렌더링을 시작하려면 기존의 pages 폴더가 없어야 하고,
nextConfig에 아래와 같은 속성이 추가되어야 한다.
*/
/** @type {import('next').NextConfig} */
const nextConfig = {
    experimental: {
        appDir: true,
    },
};
module.exports = nextConfig;

1) Layouts

app 디렉터리를 사용하면 공통으로 사용되는 UI 컴포넌트의 불필요한 리렌더링을 방지하고 라우트 간에 UI를 쉽게 공유할 수 있습니다.

- 디렉터리 구성

  • app/head.js : 타이틀 및 메타 태그가 있는 헤드 파일
  • app/layout.js
    - html, body 태그가 있는 루트 레이아웃
    - 여러 경로에서 공유되는 UI를 정의
    - 기존의 pages/_app.js와 pages/_document.js를 대체
  • app/page.js
    - 초기 콘텐츠를 포함
    - 기존의 pages/index.js를 대체
// app/head.js
export default function Head() {
    return (
        <>
            <title>NESTjs 13</title>
            <meta name="viewport" content="width=device-width, initial-scale=1" />
        </>
    );
}

// app/layout.js
export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <head />
            <body>{children}</body>
        </html>
    );
}

// app/page.js
export default function Page() {
    return <h1>Hello, Next.js!</h1>;
}

- 경로 지정 (Defining Routes)

경로는 app 디렉토리 내부에 추가적인 디렉토리로 지정되며, 각 서브 디렉토리들은 page.js 파일을 포함하여야 합니다.

기존 pages 디렉토리13버전 app 디렉토리라우트 (경로)
index.jspage.js/
dashboard.jsdashboard/page.js/dashboard
dashboard/[slug].jsdashboard/[slug]/page.js/dashboard/post-1

각각의 서브 디렉토리에 layout.js를 사용하여 각 경로의 공통 UI를 정의할 수 있습니다.

2) React Server Components

서버 구성 요소를 사용하여 복잡한 인터페이스를 구축하는 동시에 클라이언트로 전송되는 JavaScript의 양을 줄여 초기 페이지 로드 속도를 높일 수 있는 토대를 마련합니다.

3) Streaming

클라이언트에 UI를 점진적으로 렌더링하고 스트리밍하는 기능을 도입합니다.
특별히 데이터가 필요하지 않은 페이지 부분을 즉시 렌더링하고 데이터를 가져오는 페이지 부분에 대한 로드 상태를 표시할 수 있습니다. 이 접근 방식을 사용하면 사용자는 상호 작용을 시작하기 전에 전체 페이지가 로드될 때까지 기다릴 필요가 없습니다.

4) Support for Data Fetching

getServerSideProps나 getStaticProps를 사용하여 data를 fetch했던 이전의 방식에서 좀 더 직관적으로 변경되었습니다.

// 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>;
}

// getStaticProps와 유사 - 빌드 시 딱 한번만 호출
fetch(URL, { cache: 'force-cache' });
// getServerSideProps와 유사 - 매 요청때마다 호출
fetch(URL, { cache: 'no-store' });
// getStaticProps의 revalidate 옵션을 사용하는 것과 유사
fetch(URL, { next: { revalidate: 10 } });

2. Turbopack 생성 및 업데이트 (알파)

  • Webpack보다 700배 빠른 업데이트
  • Vite보다 10배 빠른 업데이트
  • Webpack보다 4배 빠른 콜드 스타트

그 외

  • Server Components, TypeScript, JSX, CSS 등을 즉시 지원
  • Tailwind CSS 포함한 PostCSS 지원
  • next/image,next/font (Google Fonts) 지원
  • from dynamic import() 구문에서 loading CSS 지원
  • CSS source maps 지원
  • Improved error handling in next dev error overlay
  • Improved memory usage
  • Improved CSS modules support
  • Improved chunking algorithm for HMR updates
  • Improved reliability for HMR source maps

3. next/image (안정적)

새로운 Image 구성 요소가 도입되어 레이아웃 변경 없이 이미지를 쉽게 표시하고 ,성능 향상을 위해 필요에 따라 파일을 최적화 가능합니다.
기존에는 width, height값을 적용하지 않으면 레이아웃이 깨지는 Layout shift가 발생하곤 했는데 Next.js 13에서는 이를 자동으로 처리해줍니다.

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

function Home() {
  // "alt" 는 더 쉽게 액세스할 수 있는 필수 태그
  // optional: 이미지 파일을 app 디렉토리에 배치해도 됨
  return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}

자세한 사용 설명은 https://nextjs.org/docs/basic-features/image-optimization 를 참고

4. @next/font (베타)

  • 사용자 지정 글꼴을 포함하여 글꼴을 자동으로 최적화
  • 개인 정보 보호 및 성능 향상을 위해 외부 네트워크 요청을 제거
    - 브라우저에서 구글로 요청을 보내지 않음
  • 모든 구글 글꼴을 자동으로 자체 호스팅
    - CSS 및 글꼴 파일은 빌드 시 다운로드되며 나머지 정적 자산과 함께 자체 호스팅
  • CSS size-adjust속성을 사용하여 Layout shift 발생 방지
// 구글 폰트 사용
import { Inter } from '@next/font/google';

const inter = Inter();
<html className={inter.className}></html>

//  사용자 정의 글꼴
import localFont from '@next/font/local';

const myFont = localFont({ src: './my-font.woff2' });
<html className={myFont.className}></html>

자세한 사용 설명은 https://nextjs.org/docs/basic-features/font-optimization 를 참고

next/link는 a태그를 더 이상 자식태그로 추가할 필요가 없습니다.

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>

6. Built-in Module Transpilation (안정적)

모듈 트랜스파일을 내부적으로 지원합니다.
이전에는 node_modules의 모듈을 트랜스파일하기 위해 next-transpile-modules이라는 패키지를 사용해야 했지만, 이제는 빌트인 기능으로 지원되어 nextjs 설정 파일에서 transpilePackages: ['모듈명'] 와 같이 입력하면 트랜스파일을 수행합니다.

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@acme/ui', 'lodash-es'],
};
module.exports = nextConfig;

7. Edge Runtime (안정적)

Next.js 미들웨어는 더 나은 성능을 위해 기본적으로 이 Edge 런타임을 이미 사용하고 있습니다. 미들웨어는 애플리케이션의 모든 요청 전에 실행될 수 있으므로 짧은 대기 시간을 보장하려면 가벼운 런타임을 갖는 것이 중요합니다. 이 전에는 베타 단계였기 때문에 "experimental-" 프리픽스가 필요했지만, 이제 Next.js 내부의 Edge 런타임이 API 경로에 대해 안정적이게 되었습니다.

// pages/api/hello.ts - 13.1버전에서 pages/api는 유지(대체 디렉토리 없음)
// "experimental-" prefix is no longer needed
export const config = {
  runtime: 'edge',
};
export default function handler(req: Request) {
  return new Response('Hello World');
}

8. Middleware Improvements

13.1에서는 미들웨어에서 응답을 반환하고 요청 시 헤더를 설정할 수 있습니다.

9. SWC Import Resolution

많은 npm 패키지는 배럴 파일을 사용하여 다른 모듈을 다시 내보내는 단일 파일을 제공합니다.
Barrel(배럴) : import 구문을 축약하여 사용함

// Without barrel
import { A } from "@impl/A;
import { B } from "@impl/B;
import { C } from "@impl/C;
// With barrel
import { A, B, C } from "@impl;

번들러는 이 배럴파일을 이해하고 사용하지 않는 re-exports를 제거할 수 있습니다.
일부 npm 패키지는 수천 개의 모듈을 다시 내보낸(export) 배럴 파일을 제공하므로 컴파일 시간이 느려집니다. 이 문제를 해결하기 위해 babel-plugin-transform-imports의 사용을 추천했었지만, 이제는 SWC에 modularizeImports라는 설정이 추가되었습니다.

// next.config.js
module.exports = {
  modularizeImports: {
    '@impl': {
      transform: '@impl/dist/{{member}}',
    },
  },
};

// Before (with barrel file)
import { Button, Slider, Dropdown } from '@impl';

// After (with modularized imports from plugin)
import Button from '@impl/dist/Button';
import Slider from '@impl/dist/Slider';
import Dropdown from '@impl/dist/Dropdown';
profile
Web Developer

0개의 댓글