๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

React

[ Next.js ] Next15์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ธฐ.

 

 

 

2024๋…„ 10์›” 21์ผ Next15 ๋ฒ„์ „์ด ๊ณต์‹ ๋ธ”๋กœ๊ทธ์— ์—…๋ฐ์ดํŠธ๋˜์—ˆ๋‹ค.

๊ณต์‹์ ์œผ๋กœ ์•ˆ์ •ํ™”๋˜์–ด ํ”„๋กœ๋•์…˜์—์„œ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

 

 

์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ๋Š” RC1๊ณผ RC2์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ์•ˆ์ •์„ฑ์— ์ค‘์ ์„ ๋‘๋ฉด์„œ๋„ ํฅ๋ฏธ๋กœ์šด ์—…๋ฐ์ดํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค๊ณ  ํ•œ๋‹ค.

10์›” 24์ผ์— ์—ด๋ฆฐ Next.js Conf๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ, ์‚ฌ์ „ ์‹ ์ฒญํ•˜๊ณ  ๋ชป ๋“ค์–ด์„œ ๋…นํ™”๋ณธ์„ ๋ณด๊ณ  ๋‹ค์Œ์— ๊ทธ ๋‚ด์šฉ์— ๋Œ€ํ•œ ํฌ์ŠคํŒ…๋„ ํ•  ์˜ˆ์ •์ด๋‹ค.

 

 

Next15์˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

# ์ƒˆ๋กœ์šด ์ž๋™ ์—…๊ทธ๋ ˆ์ด๋“œ CLI ์‚ฌ์šฉ
npx @next/codemod@canary upgrade latest

# ...๋˜๋Š” ์ˆ˜๋™์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ
npm install next@latest react@rc react-dom@rc

 

 

 


 

 

 

Next.js 15์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ฐ„๋žตํ•˜๊ฒŒ ์†Œ๊ฐœํ•˜์ž๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

  • @next/codemod CLI : ์ตœ์‹  Next.js ๋ฐ React ๋ฒ„์ „์œผ๋กœ ์‰ฝ๊ฒŒ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ.
  • Async Request APIs (Breaking) : ๋ Œ๋”๋ง ๋ฐ ์บ์‹ฑ ๋ชจ๋ธ์„ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์ ์ง„์  ๋‹จ๊ณ„๋กœ, ์š”์ฒญ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ API๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์˜€์Œ. (ํ˜ธํ™˜์„ฑ ๊นจ์ง)
  • Caching Semantics (Breaking) : fetch์š”์ฒญ, GET๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ, ํด๋ผ์ด์–ธํŠธ ๋„ค๋น„๊ฒŒ์ด์…˜์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์บ์‹ฑ๋˜์ง€ ์•Š๋„๋ก ๋ณ€๊ฒฝ (ํ˜ธํ™˜์„ฑ ๊นจ์ง)
  • React 19 Support : React 19, React Compiler(์‹คํ—˜์ ), ํ•˜์ด๋“œ๋ ˆ์ด์…˜ ์˜ค๋ฅ˜ ๊ฐœ์„ ์„ ์ง€์›.
  • Turbopack Dev (Stable) : ์„ฑ๋Šฅ ๋ฐ ์•ˆ์ •์„ฑ์ด ํ–ฅ์ƒ๋˜์—ˆ์Œ.(์•ˆ์ •ํ™”)
  • Static Indicator : ๊ฐœ๋ฐœ ์ค‘ ์ •์  ๋ผ์šฐํŠธ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๋Š” ์ƒˆ๋กœ์šด ์ธ๋””์ผ€์ดํ„ฐ ์ถ”๊ฐ€.
  • unstable_after API (Experimental) : ์‘๋‹ต ์ŠคํŠธ๋ฆฌ๋ฐ์ด ์™„๋ฃŒ๋œ ํ›„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” API. (์‹คํ—˜์ )
  • instrumentation.js API (Stable) : ์„œ๋ฒ„ ๋ผ์ดํ”„์‚ฌ์ดํด ๊ด€์ฐฐ์„ ์œ„ํ•œ ์ƒˆ๋กœ์šด API. (์•ˆ์ •ํ™”)
  • Enhanced Forms (next/form) : HTML ํผ์„ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋„ค๋น„๊ฒŒ์ด์…˜๊ณผ ํ•จ๊ป˜ ํ–ฅ์ƒํ•จ.
  • next.config: next.config.ts์— ๋Œ€ํ•œ TypeScript ์ง€์›์„ ์ถ”๊ฐ€.
  • Self-hosting Improvements : Cache-Control ํ—ค๋”์— ๋Œ€ํ•œ ์ œ์–ด๋ฅผ ๊ฐ•ํ™”.
  • Server Actions Security: ์ถ”์ธกํ•  ์ˆ˜ ์—†๋Š” ์—”๋“œํฌ์ธํŠธ์™€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์•ก์…˜ ์ œ๊ฑฐ๋ฅผ ํ†ตํ•ด ๋ณด์•ˆ์„ ๊ฐ•ํ™”.
  • Bundling External Packages (Stable): App ๋ฐ Pages ๋ผ์šฐํ„ฐ์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๊ตฌ์„ฑ ์˜ต์…˜์„ ์ถ”๊ฐ€. (์•ˆ์ •ํ™”)
  • ESLint 9 Support: ESLint 9์„ ์ง€์›.
  • Development and Build Performance: ๋นŒ๋“œ ์‹œ๊ฐ„ ๊ฐœ์„  ๋ฐ ๋น ๋ฅธ ์ƒˆ๋กœ ๊ณ ์นจ ์†๋„๊ฐ€ ํ–ฅ์ƒ.

 

 


 

 

 

@next/codemod CLI๋ฅผ ํ†ตํ•œ ์›ํ™œํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ

๋ชจ๋“  ์ฃผ์š” Next.js ๋ฆด๋ฆฌ์ฆˆ์—๋Š” ํ˜ธํ™˜์„ฑ ๊นจ์ง ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ž๋™์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก codemod(์ž๋™ ์ฝ”๋“œ ๋ณ€ํ™˜)๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ๋”์šฑ ์›ํ™œํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ํ–ฅ์ƒ๋œ codemod CLI๋ฅผ ์ถœ์‹œํ•˜์˜€๋‹ค.

npx @next/codemod@canary upgrade latest

 

 

 

 

 

Async Request APIs (Breaking) ๋น„๋™๊ธฐ API ์š”์ฒญ (ํ˜ธํ™˜์„ฑ ๊นจ์ง)

์ „ํ†ต์ ์ธ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์—์„œ๋Š” ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋ง ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์š”์ฒญ๋ณ„ ๋ฐ์ดํ„ฐ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ, ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆด ํ•„์š” ์—†์ด ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์š”์ฒญ๋ณ„ ๋ฐ์ดํ„ฐ์— ์˜์กดํ•˜๋Š” API(headers, cookies, params, searchParams ๋“ฑ)๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ „ํ™˜ํ•˜๊ณ  ์žˆ๋‹ค.

import { cookies } from 'next/headers';

export async function AdminPanel() {
  const cookieStore = await cookies();
  const token = cookieStore.get('token');

  // ...
}

 

์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๋‹ค์Œ API์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค :

  • cookies
  • headers
  • draftMode
  • params in layout.js, page.js, route.js, default.js, generateMetadata, and generateViewport
  • searchParams in page.js

๋” ์‰ฌ์šด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด, ์ด๋Ÿฌํ•œ API๋Š” ์ผ์‹œ์ ์œผ๋กœ ๋™๊ธฐ์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „๊นŒ์ง€ ๊ฐœ๋ฐœ ๋ฐ ํ”„๋กœ๋•์…˜์—์„œ ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•œ๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•œ codemod๊ฐ€ ์ œ๊ณต๋œ๋‹ค.

 

 

 

 

 

Caching Semantics (Breaking) ์บ์‹ฑ ๋ฐฉ์‹ (ํ˜ธํ™˜์„ฑ ๊นจ์ง)

Next.js 15์—์„œ๋Š” GET๊ฒฝ๋กœ ํ•ธ๋“ค๋Ÿฌ์™€ ํด๋ผ์ด์–ธํŠธ ๋ผ์šฐํ„ฐ์˜ ๊ธฐ๋ณธ ์บ์‹ฑ ๋™์ž‘์ด ์—…๋ฐ์ดํŠธ๋˜์—ˆ๋‹ค.

 

GET Router ํ•ธ๋“ค๋Ÿฌ

Next.js 13์—์„œ๋Š” GET์š”์ฒญ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์บ์‹œ ๋˜์—ˆ๋‹ค. ์ฆ‰, ๋™์ผํ•œ ์š”์ฒญ์ด ์ด๋ฃจ์–ด์งˆ ๋•Œ Next.js๊ฐ€ ์ด์ „ ์‘๋‹ต์„ ์ €์žฅํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ์„ ๋ฐฉ์ง€ํ•˜์˜€๋‹ค. ํ•˜์ง€๋งŒ Next.js 15์—์„œ๋Š” ๋” ์ด์ƒ ๊ธฐ๋ณธ์ ์œผ๋กœ GET ์š”์ฒญ์„ ์บ์‹œ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋™์  ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์ƒˆ ์š”์ฒญ๋งˆ๋‹ค ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค.

 

๋งŒ์•ฝ ์บ์‹ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ export const dynamic = 'force-static' ์„ ์‚ฌ์šฉํ•˜์—ฌ GET์š”์ฒญ์— ๋Œ€ํ•ด ๊ฐ•์ œ์ ์œผ๋กœ ์ •์  ์บ์‹œ๋ฅผ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํŠน์ • GET ๊ฒฝ๋กœ๊ฐ€ ์ •์ ์œผ๋กœ ์บ์‹œ ๋˜๋„๋ก ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ ‡๊ฒŒ ์„ค์ •๋œ ๊ฒฝ๋กœ๋Š” ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ๊ณ ์ •๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

ํด๋ผ์ด์–ธํŠธ ๋ผ์šฐํ„ฐ

Next.js 15์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ๋ผ์šฐํ„ฐ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์บ์‹œ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ด์ „ ๋ฒ„์ „์—์„œ๋Š” ํŽ˜์ด์ง€๊ฐ€ ์บ์‹œ๋˜์–ด ํŽ˜์ด์ง€ ์ „ํ™˜ ์‹œ ๋” ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋˜์—ˆ์ง€๋งŒ, ์ด์ œ๋Š” ํŽ˜์ด์ง€๊ฐ€ ํ•ญ์ƒ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€๋œ๋‹ค. ์ฆ‰, ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ์ฆ‰์‹œ ๋ฐ˜์˜ํ•˜์—ฌ ๋ Œ๋”๋ง ๋œ๋‹ค.

 

๊ธฐ์กด์˜ ์บ์‹ฑ ๋™์ž‘์„ ์œ ์ง€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด staleTimes ์„ค์ •์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง€ ์บ์‹ฑ์„ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

staleTimes๋ฅผ ์ ์ ˆํžˆ ์„ค์ •ํ•˜๋ฉด ํŽ˜์ด์ง€๊ฐ€ ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ์บ์‹œ๋œ ์ƒํƒœ๋กœ ์œ ์ง€๋˜๋ฉฐ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€๋กœ ๋Œ์•„์™”์„ ๋•Œ ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
    },
  },
};
 
export default nextConfig;

 

 

 

 

 

React 19

Next.js 15๋ฆด๋ฆฌ์ฆˆ์˜ ์ผํ™˜์œผ๋กœ ๋‹ค๊ฐ€์˜ค๋Š” React 19 ๋ฆด๋ฆฌ์ฆˆ์— ๋งž์ถ”๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜์˜€๋‹ค๊ณ  ํ•œ๋‹ค. 15์—์„œ๋Š” App Router๊ฐ€ React 19 RC๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, Pages Router์— ๋Œ€ํ•ด์„œ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”ผ๋“œ๋ฐฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ React 18๊ณผ์˜ ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์„ ๋„์ž…ํ–ˆ๋‹ค. Pages Router๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์ค€๋น„๊ฐ€ ๋˜์—ˆ์„ ๋•Œ React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ๋‹ค.

 

React 19๋Š” ์•„์ง RC(Release Candidate) ๋‹จ๊ณ„์— ์žˆ์ง€๋งŒ, ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ๊ด‘๋ฒ”์œ„ํ•œ ํ…Œ์ŠคํŠธ์™€ React ํŒ€๊ณผ์˜ ๊ธด๋ฐ€ํ•œ ํ˜‘์—…์„ ํ†ตํ•ด ๊ทธ ์•ˆ์ •์„ฑ์— ๋Œ€ํ•œ ํ™•์‹ ์„ ์–ป์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค. ํ•ต์‹ฌ์ ์ธ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์€ ์ถฉ๋ถ„ํžˆ ํ…Œ์ŠคํŠธ๋˜์—ˆ๊ณ  ๊ธฐ์กด App Router ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ React 19 GA(General Availability)์— ์™„์ „ํžˆ ์ค€๋น„๋  ์ˆ˜ ์žˆ๋„๋ก Next.js 15๋ฅผ ์ง€๊ธˆ ์•ˆ์ • ๋ฒ„์ „์œผ๋กœ ์ถœ์‹œํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜์˜€๋‹ค๊ณ  ํ•œ๋‹ค.

 

์ „ํ™˜์„ ์›ํ™œํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก codemod์™€ ์ž๋™ํ™” ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ณผ์ •์„ ์ง€์›ํ•œ๋‹ค.

 

 

 

 


 

 

 

๋ช‡ ๊ฐ€์ง€ ์ฃผ์š” ์‚ฌํ•ญ๋“ค์„ ์•Œ์•„๋ณด์•˜๋‹ค. ๋งค๋ฒˆ ๋Š๋ผ๋Š” ๊ฑฐ์ง€๋งŒ, ํ”„๋ก ํŠธ์—”๋“œ ์ƒํƒœ๊ณ„๋Š” ํ•ญ์ƒ ๋น ๋ฅด๊ฒŒ ๋ณ€ํ™”ํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

Next.js 13 ๋ฒ„์ „์ด 2022๋…„ 10์›” 25์ผ์— ์ถœ์‹œ๋˜์—ˆ๊ณ , 14 ๋ฒ„์ „์ด 2023๋…„ 10์›” 26์ผ, 15 ๋ฒ„์ „์ด 2024๋…„ 10์›” 21์ผ๋กœ ์•ฝ 1๋…„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ถœ์‹œ๋˜๊ณ  ์žˆ๋‹ค. 

 

React.js ๋Š” 16 ๋ฒ„์ „์ด 2017๋…„ 9์›” 26์ผ, 17 ๋ฒ„์ „์ด 2020๋…„ 10์›” 20์ผ, 18 ๋ฒ„์ „์ด 2022๋…„ 3์›” 29์ผ, 19 ๋ฒ„์ „์ด 2024๋…„ 4์›” 25์ผ(RC)์ด๋‹ค. 

 

ํ›Œ๋ฅญํ•œ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ์„ฑ์žฅํ•˜๊ธฐ ์œ„ํ•ด ์•ˆ์ฃผํ•˜์ง€ ์•Š๊ณ , ๋Š์ž„์—†์ด ๋…ธ๋ ฅํ•˜๊ณ  ์„ฑ์žฅํ•˜๋Š” ์‚ฌ๋žŒ์ด ๋˜์–ด์•ผ๊ฒ ๋‹ค.

 

 

 

 

 

 


 

๐ŸŒธ ์ถœ์ฒ˜ ๐ŸŒธ

 

next-15-blog

next15 ์—…๊ทธ๋ ˆ์ด๋“œ ๊ฐ€์ด๋“œ

React 2014 conf