• Blog

  • Snippets

Next.js 15 RC

May 24, 2024

NEXT JS 15

NEXT JS

App Route

NEXT JS 15 RC Blog를 참고하여 번역함.

Next.js 15 Release Candidate(RC)가 이제 이용 가능합니다. 이 초기 버전은 다가오는 안정적인 릴리스 전에 최신 기능을 테스트할 수 있게 해줍니다.


오늘 Next.js 15 Release Candidate(RC)를 사용해 보세요:

Terminal

npm install next@rc react@rc react-dom@rc

Note: Next.js 15 RC 문서는 Next.js 15 GA가 출시될 때까지 rc.nextjs.org/docs에서 볼 수 있습니다.

# React 19 RC(Release Candidate)

Next.js 앱 라우터는 프레임워크용 React canary channel을 기반으로 구축되었으며, 이를 통해 개발자들은 v19 출시 이전에 이러한 새로운 React API를 사용하고 피드백을 제공할 수 있었습니다.

Next.js 15 RC는 이제 React 19 RC를 지원하며, 클라이언트와 서버 모두를 위한 새로운 기능인 Actions를 포함합니다.

더 자세히 알아보려면 Next.js 15 upgrade guide, React 19 upgrade guide를 읽고 React Conf keynote 시청하세요.

Note: 일부 서드 파티 라이브러리는 아직 React 19와 호환되지 않을 수 있습니다.

# React Compiler (Experimental)

React 컴파일러는 Meta의 React 팀이 만든 새로운 실험적 컴파일러입니다. 이 컴파일러는 일반 JavaScript 의미론과 React의 규칙을 깊이 이해하여 코드에 자동 최적화를 추가할 수 있습니다. 컴파일러는 useMemo 및 useCallback과 같은 API를 통해 개발자가 수동으로 해야 하는 메모이제이션의 양을 줄여 코드가 더 간단하고 유지보수가 용이하며 오류 발생 가능성이 적습니다.

Next.js 15에서는 React 컴파일러에 대한 지원을 추가했습니다.

babel-plugin-react-compiler를 설치하세요:

Terminal

npm install babel-plugin-react-compiler

그런 다음, next.config.jsexperimental.reactCompiler 옵션을 추가하세요:

next.config.ts

const nextConfig = {
experimental: {
reactCompiler: true,
},
};
module.exports = nextConfig;

선택적으로, 다음과 같이 컴파일러를 "opt-in" 모드로 설정할 수 있습니다:

next.config.ts

const nextConfig = {
experimental: {
reactCompiler: {
compilationMode: 'annotation',
},
},
};
module.exports = nextConfig;

opt-in : 옵트인은 사용자가 명시적으로 동의해야 한다. 회원가입 시 "이메일 수신 동의"를 선택하는 경험을 떠올리면 된다. 즉 사용자의 동의가 없으면 기본적으로 정보를 수집할 수 없는 것이다.

라이브러리를 사용헀을 때 어떠한 기능을 라이브러리에서 제공은 하지만 기본적으로 적용이 되지 않는 경우가 있다. 이러한 경우 사용자가 명시적으로 기능을 적용시켜야 한다.

예시 : React에서의 동시성 기능, Next.js의 클라이언트 컴포넌트

Note: React 컴파일러는 현재 Babel 플러그인을 통해서만 Next.js에서 사용할 수 있으며, 이는 빌드 시간이 느려질 수 있습니다.

React 컴파일러사용 가능한 Next.js config options에 대해 자세히 알아보세요.

Hydration 에러 개선

Next.js 14.1에서는 오류 메시지와 하이드레이션 오류를 개선했습니다. Next.js 15에서는 이를 바탕으로 개선된 하이드레이션 오류 뷰를 추가했습니다. 이제 하이드레이션 오류는 오류의 소스 코드를 표시하고 문제를 해결하기 위한 제안을 제공합니다.

예를 들어, 다음은 Next.js 14.1에서의 이전 하이드레이션 오류 메시지입니다:

image-01.png

Next.js 15 RC에서는 이것을 다음과 같이 개선했습니다:

image-02.png

# Caching updates

Next.js App Router는 강력한 캐싱 기본값과 함께 출시되었습니다. 이는 기본적으로 가장 성능이 좋은 옵션을 제공하도록 설계되었으며, 필요시 선택적으로 사용하지 않도록 설정할 수 있습니다.

여러분의 피드백을 바탕으로, 우리는 caching heuristics과 그것이 Partial Prerendering (PPR) 및 fetch를 사용하는 서드 파티 라이브러리와 어떻게 상호 작용할지를 재평가했습니다.

Next.js 15에서는 fetch 요청, GET 라우트 핸들러, 클라이언트 라우터 캐시의 기본 캐싱 설정을 기본적으로 캐시된 상태에서 기본적으로 캐시되지 않는 상태로 변경하고 있습니다. 이전 동작을 유지하려면 계속해서 캐싱을 선택할 수 있습니다.

우리는 앞으로 몇 달 동안 Next.js의 캐싱을 계속 개선할 것이며, Next.js 15 GA(General Availability) 발표에서 더 많은 세부 정보를 공유할 예정입니다.

fetch 요청은 더 이상 기본적으로 캐시되지 않습니다.

Next.js는 서버 사이드 fetch 요청이 프레임워크의 지속적인 HTTP 캐시와 상호 작용하는 방식을 구성하기 위해 Web fetch API 캐시 옵션을 사용합니다:

fetch('https://...', { cache: 'force-cache' | 'no-store' });

Next.js 14에서는 cache 옵션이 제공되지 않는 경우, 동적 함수나 동적 구성 옵션이 사용되지 않는 한 기본적으로 force-cache가 사용되었습니다.

Next.js 15에서는 cache 옵션이 제공되지 않는 경우 기본적으로 no-store가 사용됩니다. 이는 fetch 요청이 기본적으로 캐시되지 않음을 의미합니다.

여전히 다음 방법으로 fetch 요청을 캐싱하도록 선택할 수 있습니다:


GET 라우트 핸들러는 더 이상 기본적으로 캐시되지 않습니다.

Next.js 14에서는 GET HTTP 메서드를 사용하는 라우트 핸들러가 동적 함수나 동적 구성 옵션을 사용하지 않는 한 기본적으로 캐시되었습니다. Next.js 15에서는 GET 함수가 기본적으로 캐시되지 않습니다.

여전히 export dynamic = 'force-static'과 같은 정적 라우트 구성 옵션을 사용하여 캐싱을 선택할 수 있습니다.

sitemap.ts, opengraph-image.tsx, icon.tsx와 같은 특수 라우트 핸들러 및 기타 metadata files은 동적 함수나 동적 구성 옵션을 사용하지 않는 한 기본적으로 정적으로 유지됩니다.

클라이언트 라우터 캐시는 이제 기본적으로 페이지 컴포넌트를 캐시하지 않습니다.

Next.js 14.2.0에서는 Router Cache의 맞춤 구성을 허용하기 위해 실험적인 staleTimes 플래그를 도입했습니다.

Next.js 15에서는 이 플래그가 여전히 사용 가능하지만, 페이지 세그먼트의 기본 동작을 staleTime0으로 변경하고 있습니다. 이는 애플리케이션을 탐색할 때 클라이언트가 탐색의 일부로 활성화된 페이지 컴포넌트의 최신 데이터를 항상 반영한다는 것을 의미합니다. 그러나 여전히 변경되지 않는 중요한 동작들이 있습니다:


다음 설정을 통해 이전 클라이언트 라우터 캐시 동작을 선택할 수 있습니다:

next.config.ts

const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30,
},
},
};
module.exports = nextConfig;

# Partial Prerendering 점진적 도입 (Experimental)

Next.js 14에서는 동일한 페이지에서 정적 렌더링과 동적 렌더링을 결합하는 최적화 기법인 Partial Prerendering(PPR)을 도입했습니다.

Next.js는 현재 cookies(), headers() 및 캐시되지 않은 데이터 요청과 같은 dynamic functions를 사용하지 않는 한 기본적으로 정적 렌더링을 사용합니다. 이러한 API는 전체 라우트를 동적 렌더링으로 전환합니다. PPR을 사용하면 동적 UI를 Suspense Boundary 안에 래핑할 수 있습니다. 새로운 요청이 들어오면 Next.js는 즉시 정적 HTML 셸을 제공한 다음, 동일한 HTTP 요청에서 동적 부분을 렌더링하고 스트리밍합니다.

점진적인 도입을 위해 특정 레이아웃과 페이지를 PPR에 선택할 수 있도록 하는 experimental_ppr 라우트 구성 옵션을 추가했습니다:

app/page.jsx

import { Suspense } from "react"
import { StaticComponent, DynamicComponent } from "@/app/ui"
export const experimental_ppr = true
export default function Page() {
return {
<>
<StaticComponent />
<Suspense fallback={...}>
<DynamicComponent />
</Suspense>
</>
};
}

새로운 옵션을 사용하려면 next.config.js 파일에서 experimental.ppr 설정을 'incremental'로 설정해야 합니다:

next.config.ts

const nextConfig = {
experimental: {
ppr: 'incremental',
},
};
module.exports = nextConfig;

모든 세그먼트에 PPR이 활성화되면 ppr 값을 true로 설정하여 전체 앱과 모든 미래의 라우트에 대해 PPR을 활성화하는 것이 안전합니다.

우리는 Next.js 15 GA(General Availability) 블로그 게시물에서 PPR 로드맵에 대한 더 많은 정보를 공유할 예정입니다.

Partial Prerendering에 대해 더 알아보세요.

# 응답 후 코드 실행하기 with next/after (Experimental)

사용자 요청을 처리할 때, 서버는 일반적으로 응답을 계산하는 것과 직접적으로 관련된 작업을 수행합니다. 그러나 로그 작성, 분석 및 기타 외부 시스템 동기화와 같은 작업을 수행해야 할 수도 있습니다.

이러한 작업들은 응답과 직접적으로 관련이 없기 때문에, 사용자는 이 작업들이 완료되기를 기다릴 필요가 없습니다. 사용자에게 응답한 후 작업을 연기하는 것은 서버리스 함수가 응답이 완료된 후 즉시 계산을 중지하기 때문에 어려움을 초래합니다.

after()는 응답 스트리밍이 완료된 후 작업을 처리하도록 예약할 수 있게 해주는 새로운 실험적 API로, 이를 통해 보조 작업이 주요 응답을 방해하지 않고 실행될 수 있도록 합니다.

사용하려면 next.config.jsexperimental.after를 추가하세요:

next.config.ts

const nextConfig = {
experimental: {
after: true,
},
};
module.exports = nextConfig;

그런 다음, 서버 컴포넌트, 서버 액션, 라우트 핸들러 또는 미들웨어에서 해당 함수를 import하세요.

import { unstable_after as after } from 'next/server';
import { log } from '@/app/utils';
export default function Layout({ children }) {
// Secondary task
after(() => {
log();
});
// Primary task
return <>{children}</>;
}

next/after에 대해 더 알아보세요.

# create-next-app updates

Next.js 15에서는 create-next-app을 새로운 디자인으로 업데이트했습니다.

image-03.png

create-next-app을 실행할 때 로컬 개발을 위해 Turbopack을 활성화할지 묻는 새로운 프롬프트가 표시됩니다 (기본값은 No).

Terminal

✔ Would you like to use Turbopack for next dev? … No / Yes

--turbo 플래그를 사용하여 Turbopack을 활성화할 수 있습니다.

Terminal

npx create-next-app@rc --turbo

새 프로젝트를 더 쉽게 시작할 수 있도록 CLI에 새로운 --empty 플래그가 추가되었습니다. 이를 사용하면 불필요한 파일과 스타일이 제거되어 최소한의 "hello world" 페이지가 생성됩니다.

Terminal

npx create-next-app@rc --empty

# 외부 패키지 번들링 최적화 (Stable)

외부 패키지를 번들링하면 애플리케이션의 콜드 스타트 성능이 향상될 수 있습니다. 앱 라우터에서는 외부 패키지가 기본적으로 번들링되며, 새로운 serverExternalPackages 구성 옵션을 사용하여 특정 패키지를 제외할 수 있습니다.

페이지 라우터에서는 외부 패키지가 기본적으로 번들링되지 않지만, 기존의 transpilePackages 옵션을 사용하여 번들링할 패키지 목록을 제공할 수 있습니다. 이 구성 옵션을 사용하면 각 패키지를 명시해야 합니다.

앱 라우터의 기본 자동 번들링과 일치하도록 앱 라우터와 페이지 라우터 간의 구성을 통합하기 위해 새로운 옵션인 bundlePagesRouterDependencies를 도입했습니다. 필요한 경우 serverExternalPackages를 사용하여 특정 패키지를 제외할 수 있습니다.

next.config.ts

const nextConfig = {
// Automatically bundle external packages in the Pages Router:
bundlePagesRouterDependencies: true,
// Opt specific packages out of bundling for both App and Pages Router:
serverExternalPackages: ['package-name'],
};
module.exports = nextConfig;

optimizing external packages에 대해 더 알아보세요.