Codemods
Codemods는 코드베이스에 대해 프로그램적으로 실행되는 변환 작업을 말해요. 쉽게 말해, 한 파일 한 파일 수작업으로 고치지 않아도, 많은 파일에 걸쳐 자동으로 코드를 변경할 수 있게 도와주는 도구입니다.
Next.js에서는 API가 업데이트되거나 더 이상 지원되지 않을 때, 코드를 쉽게 업그레이드할 수 있도록 Codemod 변환 스크립트를 제공해요. 덕분에 버전 업그레이드가 한결 수월해지죠.
사용법
(이후에 사용법 내용이 이어질 텐데, 필요하면 언제든 알려주세요!)
터미널에서 프로젝트 폴더로 이동(cd)한 후, 아래 명령어를 실행해보세요:
npx @next/codemod <transform> <path>
여기서 <transform>
과 <path>
는 상황에 맞게 바꿔주시면 됩니다.
옵션 | 설명 |
---|---|
transform | 적용할 변환(transform) 이름 |
path | 변환을 적용할 파일 또는 디렉토리 경로 |
--dry | 실제 코드 변경 없이 시뮬레이션(드라이런) 실행 |
변경된 결과를 화면에 출력해서 비교 가능 |
참고로, @next/codemod
는 Next.js 프로젝트에서 코드 마이그레이션을 좀 더 쉽게 해주는 도구예요. 예를 들어, Next.js 버전을 업그레이드하면서 API가 변경된 부분을 한꺼번에 자동 변환할 때 자주 사용됩니다.
--dry
옵션은 정말 유용해요. 코드를 직접 바꾸기 전에, 어떤 부분이 바뀔지 먼저 확인할 수 있으니까요. --print
옵션은 변경된 결과를 터미널에 출력해줘서, 기존 코드와 변경된 코드를 비교할 수 있게 도와줍니다.
만약 여러 transform을 한꺼번에 실행하고 싶다면, 반복해서 실행하거나 스크립트를 만들어서 자동화할 수도 있습니다. 작업 전에 꼭 Git 등의 버전 관리에 커밋을 한 상태에서 진행하시길 추천드려요. 혹시 변환 결과가 마음에 안 들면 쉽게 되돌릴 수 있으니까요!
Codemods
15.0 버전
App Router Route Segment Config의 runtime 값을 experimental-edge에서 edge로 변경하기
참고: 이 codemod는 App Router에만 해당됩니다.
여기서 말하는 codemod는 코드 자동 변환 스크립트를 의미해요. 개발하다 보면 API가 변경되거나 새로운 문법이 도입될 때 기존 코드를 한꺼번에 바꿔야 할 때가 많잖아요? 이런 작업을 수동으로 하면 시간도 많이 들고, 실수할 수도 있어서 codemod를 쓰면 편리하죠.
이번 15.0 업데이트에서는 App Router를 사용하는 분들을 위해 route segment 설정에서 experimental-edge
라는 runtime 값을 edge
로 변경하는 작업이 필요해요. 기존에는 'experimental'이라는 접두어가 붙는 기능들이 많았는데, 점점 안정화되면서 접두어를 빼는 경우가 많습니다.
만약 App Router를 쓰고 있고, route segment 설정에서 runtime을 직접 지정하셨다면 codemod를 돌려서 일괄적으로 변경해 주시길 추천드려요.
아, 그리고 codemod를 돌리기 전에 반드시 코드 베이스를 백업하거나 Git에 커밋해두는 것 잊지 마세요! 자동 변환 과정에서 예상치 못한 문제가 생길 수도 있으니까요.
궁금하신 점 있으면 언제든 말씀해 주세요!
이 코드는 Next.js 프로젝트에서 사용하는 codemod 명령어예요.
npx @next/codemod@latest app-dir-runtime-config-experimental-edge .
이 명령어는 Next.js에서 Route Segment Config의 runtime
설정 중 'experimental-edge'
로 되어 있는 값을 'edge'
로 자동으로 변경해 줍니다.
예를 들어, 기존에 이런 식으로 작성한 코드가 있다면:
export const runtime = "experimental-edge";
이 codemod를 실행하면 이렇게 바뀌게 되는 거죠:
export const runtime = "edge";
왜 이런 변경이 필요할까?
Next.js가 점점 발전하면서, experimental-edge
라는 이름이 정식으로 edge
로 바뀌었어요. 이름도 더 간결해지고 안정성이 더 높아졌다는 의미예요. 예전에는 엣지 런타임이 실험적인 단계라 'experimental'이 붙었지만, 이제는 본격적으로 지원하기 때문에 이름이 바뀐 거죠.
그래서 프로젝트를 최신 상태로 유지하려면 이런 codemod를 한번 돌려주는 게 좋아요. 복잡한 파일들을 일일이 찾아 바꾸지 않아서 시간도 절약되고 실수할 위험도 줄어들고요.
참고로 알아두면 좋은 점
- codemod는 "코드 변환 도구"를 뜻해요. 주로 대규모 코드 변경이 필요할 때 사용되며, Next.js뿐 아니라 React, TypeScript 등 여러 생태계에서도 자주 활용돼요.
npx
를 쓰면 별도의 설치 없이 최신 버전의 패키지를 바로 실행할 수 있어서 편리하답니다.- 만약 프로젝트가 매우 크거나, 중요한 부분이라면 codemod를 돌리기 전에 git으로 꼭 커밋 해두기, 혹은 별도의 브랜치에서 작업하는 걸 추천해요. 혹시 문제가 생겨도 쉽게 되돌릴 수 있으니까요.
필요하면 제가 codemod 활용법이나 Next.js 엣지 런타임에 관한 더 자세한 글도 써볼게요~!
다음과 같이 바뀌었어요:
export const runtime = "edge";
비동기(dynamic) API로 마이그레이션하기
기존에 동기 방식도 지원하던 동적 렌더링 API들이 이제는 완전히 비동기 방식으로 변경됐어요. 이 부분은 프로젝트에 꽤 큰 영향을 줄 수 있으니 업그레이드 가이드를 꼭 참고해서 차근차근 적용하는 걸 추천드립니다.
추가로, 이 변화를 이해할 때 조금 도움이 될만한 점을 덧붙이면, '동적 API'는 요청이 들어올 때마다 서버에서 새로 데이터를 받아서 처리하는 방식인데요, 이전에는 동기 방식이라 처리 완료까지 기다렸다가 결과를 반환했어요. 하지만 비동기로 바뀌면서 처리 효율이 좋아지고 서버 자원 활용도 더 최적화됐답니다.
마이그레이션 하실 때는 async/await 문법에 익숙해지는 게 중요하고, API 핸들러 함수도 async
함수로 선언해주셔야 해요! 만약 기존 코드가 동기식으로 작성돼 있다면, 바로 비동기 로직으로 전환하는 게 필수입니다. 코드가 길거나 복잡하다면 조금 시간이 걸릴 수 있지만, 장기적으로는 더 효율적인 서버 리소스 관리와 성능 향상을 기대할 수 있어요.
이번에 Next.js에서 동적 API인 cookies()
, headers()
, 그리고 draftMode()
같은 함수들이 이제 비동기(async) 함수로 바뀌었어요. 이전에는 그냥 바로 호출해서 값을 썼지만, 이제는 await
하거나, React 컴포넌트 안에서는 React.use()
로 감싸줘야 제대로 동작합니다.
그래서 Next.js에서 제공하는 코드를 한번에 자동 변환해주는 codemod가 있는데, 명령어는 이렇게 써주세요:
npx @next/codemod@latest next-async-request-api .
이 코드는 프로젝트 내의 파일들을 찾아서 cookies()
, headers()
같은 비동기 API 호출을 올바르게 변환해줍니다. 예를 들어 TypeScript 파일이면 타입캐스트를 추가하고, 자동 변환이 어려운 부분은 주석으로 알려서 직접 점검하게 도와줘요.
아래 예시 코드를 보면,
import { cookies, headers } from "next/headers";
const token = cookies().get("token");
function useToken() {
const token = cookies().get("token");
return token;
}
export default function Page() {
const name = cookies().get("name");
}
function getHeader() {
return headers().get("x-foo");
}
이렇게 동기적으로 호출하는 부분을 전부 비동기 패턴으로 바꿔줘야 합니다. 즉, await cookies()
혹은 React 훅 내에선 React.use(cookies())
처럼요.
추가 팁!
cookies()
,headers()
,draftMode()
가 비동기가 되면서 서버 컴포넌트(React Server Component)에서 사용하는 경우엔await
를 달아줘야 하니 주의하세요.- 클라이언트 컴포넌트에서는 직접 호출하면 안되고, 서버나 API 라우트 쪽에서 비동기로 사용하거나, Suspense 같은 컴포넌트 내에서 처리해야 해요.
- 만약 자동 변환이 안 된 부분이 있다면, codemod가 표시한 주석을 놓치지 말고 꼭 확인해서 수동으로 고쳐주세요!
요즘 Next.js 프로젝트를 업그레이드하거나, 최신 기능 적용 중이라면 이 codemod 꼭 활용해 보시고, 비동기 호출 방식에 익숙해지시면 좋아요~! React와 Next.js가 점점 더 현대적인 패턴으로 변하고 있답니다.
먼저, 주어진 코드 예제를 살펴볼게요. Next.js에서 cookies
와 headers
를 가져와서 토큰(token)을 읽는 방식인데, 여기서 중요한 점은 동기 함수에서 비동기 프로퍼티 접근을 자동으로 감지해서 해당 함수를 async 함수로 변환하거나, 클라이언트 컴포넌트라면 React의 use
훅을 사용하는 점이에요.
예를 들어 아래 코드를 보면:
const token = (cookies() as unknown as UnsafeUnwrappedCookies).get('token')
이 코드는 동기적으로 보이지만 사실 cookies()
가 비동기로 작동할 수 있어서, Next.js는 페이지나 라우트 파일(page.js
, layout.js
, route.js
, default.js
) 내에서 이런 프로퍼티 접근을 발견하면 함수 선언부를 async로 바꾸고 await
를 붙여줍니다.
또, 만약 해당 컴포넌트가 클라이언트 컴포넌트라면 await
을 사용할 수 없으니 React.use
훅으로 promise를 언랩핑하는 방식을 써요. 예를 들어:
function useToken() {
const token = use(cookies()).get("token");
return token;
}
이렇게 use
훅을 써서 비동기 리소스를 처리하죠.
주요 포인트 정리
내용 | 설명 |
---|---|
동기 함수에서 비동기 프로퍼티 접근 감지 | params 나 searchParams 의 프로퍼티를 조회할 때 해당 함수가 자동으로 async 변환되면서 await 처리 |
클라이언트 컴포넌트 제한 | 클라이언트 컴포넌트는 async 함수가 될 수 없으므로, React use 훅으로 비동기 값을 처리 |
대상 파일 | page.js , layout.js , route.js , default.js 그리고 generateMetadata , generateViewport API |
안전하지 않은 타입 처리 | 내부적으로 UnsafeUnwrappedCookies , UnsafeUnwrappedHeaders 타입으로 캐스팅해서 다룰 수도 있음 |
개인적인 팁
- Next.js 13+ 앱 디렉터리에서
cookies()
같은 API를 쓸 때, 가끔 이 비동기 처리 꼼수가 꽤 편리해요. 직접async/await
붙이는 수고를 덜어주니까요. - 다만 클라이언트 컴포넌트에서
use(cookies())
처럼 React 훅을 사용하려면, React 18 이상의 환경이 필요하니 버전 확인 필수! - 이런 자동 변환 덕분에 페이지 렌더링 시 필요한 헤더값, 쿠키값 등을 간편하게 처리할 수 있어 개발 속도가 빨라집니다.
필요하면 Next.js 내부에서 어떻게 이 변환이 처리되는지 좀 더 깊게 살펴볼 수도 있고, 클라이언트/서버 컴포넌트 간 상태 전달 팁도 알려줄게요!
자, 여기서 Next.js 13에서 page.tsx
파일 안의 컴포넌트와 generateMetadata
함수가 어떻게 변경되는지 보여주는 예시가 있어요.
원래 코드
// page.tsx
export default function Page({
params,
searchParams,
}: {
params: { slug: string }
searchParams: { [key: string]: string | string[] | undefined }
}) {
const { value } = searchParams
if (value === 'foo') {
// ...
}
}
export function generateMetadata({ params }: { params: { slug: string } }) {
const { slug } = params
return {
title: `My Page - ${slug}`,
}
}
여기서 Page
컴포넌트는 params
와 searchParams
를 바로 받고 있고, generateMetadata
함수도 일반 함수처럼 파라미터에서 params
를 받는 구조입니다.
변경된 코드
// page.tsx
export default async function Page(props: {
params: Promise<{ slug: string }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const searchParams = await props.searchParams
const { value } = searchParams
if (value === 'foo') {
// ...
}
}
export async function generateMetadata(props: {
params: Promise<{ slug: string }>
}) {
const params = await props.params
const { slug } = params
return {
title: `My Page - ${slug}`,
}
}
변경점은 다음과 같아요:
Page
함수가async
함수가 되었고,params
와searchParams
가 이제 Promise로 감싸져서 들어와요. 그래서 함수 안에서await
해야 값을 얻을 수 있습니다.generateMetadata
도 이제async
함수이고, 역시params
가 Promise로 전달되니await
를 써야 하죠.
왜 이렇게 바뀌었을까요?
Next.js 13에선 데이터 및 메타데이터가 비동기로 처리되는 경우가 많아져서, 이런 형태가 표준화되었어요. 특히, 서버 컴포넌트 특성상 데이터 fetching이나 메타데이터 생성이 비동기 작업이 될 수 있기 때문이죠.
즉, async
함수로 만들어주고, await
로 받아서 데이터를 처리하는 패턴이 더 자연스러워졌어요.
추가로 알아두면 좋은 점
- @next/codemod 주석: 만약 자동 변환 도구(codemod)가 정확한 변경을 파악하기 어려운 곳이 있으면
@next/codemod
주석을 코드에 붙이는데, 이걸 발견하면 수동으로 코드를 확인하고 수정해야 합니다. 빌드 에러가 날 수 있으니 꼭 확인하고 고쳐야 해요. - 타입스크립트에서
Promise
타입을 파라미터로 받는 상황이 낯설 수 있는데, 이제 이런 패턴이 Next.js의 최신 구조에선 흔하니 익숙해지는 게 좋아요.
요약
이전 | 이후 |
---|---|
동기 함수, 직접 params 와 searchParams 받음 | async 함수, params 와 searchParams 가 Promise 라서 await 해야 함 |
generateMetadata 는 일반 함수 | generateMetadata 도 async 함수가 되어 await 처리 필요 |
마무리
Next.js 13부터는 데이터와 메타데이터 처리 방식이 좀 더 비동기적이고 유연해졌어요. 그래서 Page
컴포넌트나 generateMetadata
에서 기대하는 props 타입과 함수 선언방식이 바뀌었죠. 처음엔 조금 헷갈릴 수 있지만, 패턴에 익숙해지면 훨씬 효과적으로 서버 컴포넌트와 메타데이터를 다룰 수 있습니다.
궁금한 점 있으면 편하게 물어봐 주세요! 😄
NextRequest의 geo와 ip 속성을 @vercel/functions로 교체하기
Next.js에서 NextRequest
객체의 geo
와 ip
속성을 사용할 때, 이제는 @vercel/functions
패키지를 사용하는 방향으로 바뀌고 있어요. 이를 간단하게 자동 변경해주는 코드를 소개할게요.
npx @next/codemod@latest next-request-geo-ip .
이 명령어는 @vercel/functions
를 설치하고, 프로젝트 내의 NextRequest
코드에서 geo
와 ip
관련 속성들을 자동으로 변환해 줍니다.
예를 들어, 기존에 이렇게 쓰던 코드를:
export function middleware(request) {
const country = request.geo?.country || "US";
const ipAddress = request.ip;
// ...
}
@vercel/functions
방식으로 이렇게 바꿔줘요:
import { headers } from "@vercel/functions";
export function middleware(request) {
const country = headers()["x-vercel-ip-country"] || "US";
const ipAddress = headers()["x-vercel-ip"];
// ...
}
사실 @vercel/functions
를 쓰면 클라우드 엣지 환경에서 제공하는 IP와 지리 정보가 HTTP 헤더 형태로 전달됩니다. 그래서 직접 NextRequest
객체에서 속성을 읽는 대신, 헤더를 통해 읽는 방식으로 변경이 필요하답니다.
참고 팁!
- 만약 프로젝트에서 IP나 지리 정보가 중요한 로직이라면, 헤더의 키 이름이 변경되거나 누락되는 경우를 대비해서 기본값 처리를 꼭 해주세요.
- 로컬 개발 환경에서는 이런 헤더가 없을 수 있기 때문에, 로컬 전용 설정이나 예외 처리도 고려하는 게 좋아요.
- 직접 속성에 접근하는 코드가 많을수록 이 변환 작업을 자동화하는 codemod 도구를 꼭 써보시길 추천합니다. 수작업으로 고치면 빼먹는 코드가 생길 수 있거든요!
이렇게 하면 Vercel에서 더 안정적이고 최신 방식으로 IP와 지역 정보를 활용할 수 있답니다. 멋진 개발하시길! 🚀
이번에 Next.js API Route에서 클라이언트의 지리 정보(Geo)와 IP 주소를 가져오는 방식에 변화가 생겼네요.
기존에는 NextRequest 객체에서 바로 geo
와 ip
속성을 가져왔는데요, 14.0 버전부터는 @vercel/functions
에서 제공하는 geolocation()
과 ipAddress()
함수를 이용해야 합니다.
import type { NextRequest } from "next/server";
import { geolocation, ipAddress } from "@vercel/functions";
export function GET(req: NextRequest) {
const geo = geolocation(req);
const ip = ipAddress(req);
}
이렇게 바뀌면서 좀 더 명확하고 함수화된 형태로 관리할 수 있게 됐어요.
한 가지 참고할 점!
만약 서버 측에서 클라이언트 IP를 신뢰성 있게 얻고 싶다면, 프록시나 로드 밸런서가 있으면 헤더에서 가져오는 IP가 실제 클라이언트 IP와 다를 수 있으니 주의해야 해요. 이때 @vercel/functions
에서 제공하는 함수들이 그런 부분을 깔끔하게 처리해주니까 편리하고요.
또한, 국제화나 지역 기반 맞춤 콘텐츠를 제공하려 할 때 거주지 정보를 이렇게 쉽게 뽑아내면 유용하겠죠? 다만 개인정보보호 관련법도 신경 써서 데이터를 다루어야 하는 점도 잊지 마세요!
Next.js 14 버전 업데이트 사항을 반영해서 프로젝트를 개선해보시면 좋을 것 같습니다. 도움이 되셨길!
ImageResponse 임포트 경로 변경하기
다음 명령어를 입력하면 자동으로 next/server
에서 next/og
로 임포트 경로를 바꿔줘요. 이 작업은 동적 OG 이미지 생성(Dynamic OG Image Generation)을 사용할 때 필요해요.
npx @next/codemod@latest next-og-import .
즉, 기존에 이렇게 쓰던 코드를
import { ImageResponse } from "next/server";
이제 이렇게 바꿔줘야 해요.
import { ImageResponse } from "next/og";
이 변경 덕분에 Next.js가 최신 OG 이미지 생성 방식을 올바르게 인식해서 동적으로 이미지를 잘 만들어줍니다.
자동화 도구(codemod)를 사용하면 수동으로 일일이 바꾸지 않아도 돼서 정말 편하답니다!
혹시 codemod
가 익숙하지 않거나 처음 들어본 분들은, codemod가 코드베이스 내에 여러 파일을 대상으로 특정 패턴을 찾아 자동으로 변경해 주는 도구라고 생각하면 돼요. Next.js에서는 공식적으로 지원하는 codemod 툴이 많아서 버전 업이나 API 변경 시 활용하기 좋아요.
next.js에서 Open Graph 이미지 생성을 할 때, ImageResponse
를 임포트하는 경로가 바뀌었어요. 예전에는 next/server
에서 가져왔는데, 지금은 next/og
에서 가져와야 합니다.
import { ImageResponse } from "next/og";
이렇게 바꾸면 공식 문서와도 맞고, 최신 버전에서 문제없이 작동하죠.
그리고 추가 팁!
Open Graph 이미지를 만들 때 viewport
관련 설정도 꼭 확인해 주세요. 예를 들어, 이미지 사이즈나 화면 배율을 조절할 수 있는데, 이렇게 하면 다양한 디바이스에서 더 예쁘고 정확하게 표시됩니다.
export const runtime = "edge"; // edge runtime 권장
export const viewport = {
width: 1200,
height: 630,
};
이렇게 하면 1200x630 크기의 이미지를 생성해서 소셜 미디어에서 표준 크기로 잘 보여져요.
정리
항목 | 이전(Deprecated) | 현재 사용법 |
---|---|---|
ImageResponse 임포트 위치 | next/server | next/og |
뷰포트 설정 | 없음 | export const viewport 사용 |
앞으로 next.js Open Graph 이미지 생성 시, 위 변경 사항 기억하시면 편리하게 작업하실 수 있을 거예요!
JS 개발자 중에 Next.js를 사용하는 분들이라면, npx @next/codemod@latest metadata-to-viewport-export .
명령어 한 번쯤 들어봤을 거예요.
이 명령어는 **Next.js 메타데이터에서 특정 뷰포트 설정을 'viewport'라는 별도 export로 분리해 주는 자동 변환 도구(codemod)**예요.
왜 필요한가?
Next.js 13, 14 버전 넘어가면서 메타데이터 관리 방식이 조금 바뀌었는데, 뷰포트 설정 같은 경우는 기존에 metadata
객체 안에 넣어서 관리하다가 앞으로는 viewport
라는 export로 분리하는 걸 권장하고 있어요. 이걸 손으로 일일이 바꾸기 귀찮으니까, 자동으로 바꿔주는 게 바로 이 codemod입니다.
예시를 보면
기존엔 이렇게 작성했었죠:
export const metadata = {
title: "My App",
themeColor: "dark",
viewport: {
width: 1,
},
};
이걸 실행하면, viewport
부분을 따로 뽑아서 이렇게 바뀔 거예요:
export const metadata = {
title: "My App",
themeColor: "dark",
};
export const viewport = {
width: 1,
};
참고할 점
- codemod는 프로젝트 루트 폴더나 특정 폴더에 적용할 수 있어요.
- 실행 전 꼭 백업하거나 Git 커밋 상태로 만들어두는 걸 권장합니다. 자동 변환 과정에서 혹시 모를 문제를 대비하기 위해서죠.
- 모든 뷰포트 설정이 변환 대상이니, 변환 후엔
viewport
export한 걸next/head
나 다른 컴포넌트에 제대로 적용하는지 확인해주세요.
이렇게 코드를 자동으로 깔끔하게 바꿔주는 도구 덕분에 개발 속도가 더 빨라지고, 공식 권장 방식에 맞출 수 있답니다! 필요하다면 프로젝트에 맞게 직접 변형도 가능하니까 한 번 꼭 써보세요.
아래 코드를 보면 React나 Next.js 같은 프레임워크에서 자주 볼 수 있는 metadata
와 viewport
설정을 JavaScript 모듈 형식으로 작성한 예제예요.
export const metadata = {
title: "My App",
};
export const viewport = {
width: 1,
themeColor: "dark",
};
metadata
객체는 페이지의 메타 정보를 담고 있어요. 여기서는 간단하게 타이틀만 'My App'으로 지정했네요.viewport
객체는 화면 표시 방식과 관련된 설정인데, 보통width
값으로는 'device-width' 같은 문자열이 들어가지만, 여기선1
이라는 숫자가 들어가 있어서 실제 환경에선 조금 더 구체적인 설정이 필요할 것 같아요.themeColor
를 'dark'로 설정해 어두운 테마임을 지정해주는 부분도 눈에 띄네요.
13.2
내장 폰트 사용하기 (Use Built-in Font)
이제 내장된 시스템 폰트를 활용해보는 것에 관한 이야기예요. 웹에서 폰트를 사용할 때 구글 폰트 같은 외부 폰트를 불러오는 경우가 많지만, 페이지 로딩 시간이나 성능 최적화를 생각하면 운영체제 기본 폰트를 활용하는 것도 좋은 선택입니다.
예를 들어 CSS에서 이렇게 시스템 폰트를 지정할 수 있어요.
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
"Helvetica Neue", sans-serif;
이렇게 지정하면 iOS, Android, Windows, Linux 등 각 플랫폼에 최적화된 기본 폰트가 자동으로 적용돼서 사용자 경험이 훨씬 자연스러워집니다.
Next.js 13.2 버전부터는 내장 폰트를 쉽게 사용할 수 있도록 공식적으로 지원하는 API가 제공되는데, 이를 활용하면 폰트를 import해서 번거롭게 외부에서 불러오는 과정을 줄일 수 있습니다.
예를 들어, Next.js에서 제공하는 내장 폰트를 사용하려면:
import { Roboto } from "next/font/google";
const roboto = Roboto({
weight: "400",
subsets: ["latin"],
});
export default function MyApp() {
return <main className={roboto.className}>{/* 앱 내용 */}</main>;
}
위처럼 하면 별도의 link
태그 없이도 해당 폰트를 프로젝트 내에서 쉽게 적용할 수 있습니다.
하지만 내장 폰트가 아닌 운영체제 기본 폰트를 선택하고 싶으면, 스타일 시트에서 위에 언급한 시스템 폰트 스택을 사용하는 방법이 가장 좋습니다.
덧붙여서!
- 내장 폰트 사용은 페이지 로딩 속도를 개선하는 데 도움을 줍니다.
- 외부 폰트는 네트워크 이슈에 취약할 수 있지만, 내장 폰트는 그런 걱정이 적죠.
- 디자인과 사용자 경험에 맞게 내장 폰트와 외부 폰트를 적절히 섞어 사용하는 전략도 고려해보세요!
필요하면 내가 다음에 폰트 최적화 방법에 대해서도 소개해줄게요!
안녕하세요! 오늘은 Next.js 프로젝트에서 @next/font
패키지를 내장된 next/font
로 바꿔주는 Codemod를 한번 살펴볼게요.
요즘 Next.js에서는 폰트 처리를 더 간편하게 하기 위해 @next/font
대신 내장된 next/font
를 사용하도록 권장하고 있어요. 그래서 기존에 @next/font
를 쓰던 코드들을 새 방식으로 자동 변환해주는 도구가 나왔답니다.
사용 방법은 아주 간단해요! 터미널에서 아래 명령어만 실행하면 돼요.
npx @next/codemod@latest built-in-next-font .
npx
를 사용해서 최신 버전의 codemod를 실행하고,built-in-next-font
라는 변환 스크립트,- 그리고 마지막
.
는 현재 폴더를 뜻합니다. 프로젝트 최상위 폴더에서 돌리면 된다는 거죠.
이 툴의 역할은?
- 자동으로
@next/font
패키지를 프로젝트에서 제거하고, - 코드 안에서
@next/font
로부터 임포트한 부분을 내장된next/font
로 바꿔줘요.
예를 들어, 기존에 이런 코드가 있었다면:
import { Inter } from "@next/font/google";
Codemod를 돌리고 나면 이렇게 변해요:
import { Inter } from "next/font/google";
즉, @next/font/google
→ next/font/google
로 바뀌는 거죠.
참고로 알아두면 좋은 점!
- 이 변경은 Next.js 13 이상에서 원활하게 동작합니다. 만약 구버전 쓰신다면 잠깐 버전부터 확인해보시는 게 좋아요.
- 폰트 관련 설정이 빌트인으로 옮겨지기 때문에 설정 파일도 한번 점검해 주세요.
- Codemod 실행 전에 꼭 깃 커밋 같은 백업을 해놓는 걸 추천합니다. 혹시 모를 문제 상황에 대비해서요.
간편한 코드 변환 도구 덕분에 코드를 하나하나 찾아 바꾸는 번거로움에서 벗어날 수 있으니 꼭 활용해 보시길 바랄게요! 혹시 Next.js에서 폰트 관련 다른 팁이 궁금하면 언제든 알려주세요~
Next.js 13.0 버전에서 바뀐 점 중 하나는 이미지 관련 import 구문 변경입니다. 예전에는 이미지 관련 모듈을 불러올 때 이름이 조금 다르게 쓰였는데요, 최신 버전에서는 좀 더 명확해졌어요.
예를 들어, 기존에는 이미지 관련 파일이나 컴포넌트를 이렇게 불러왔다면:
import Image from "next/image";
다른 컨텍스트에서는 구글 폰트 같은 걸 불러올 때 이런 식으로 했잖아요:
import { Inter } from "next/font/google";
이런 import 구문을 최신 Next.js 13.0에 맞게 변경하는 작업이 필요해요. 특히 이미지 관련 라이브러리나 폰트를 사용할 때 Import 경로나 이름들이 리네이밍되거나 경로가 조금 바뀌는 경우가 있거든요.
혹시 프로젝트를 업그레이드 중이라면, 공식 문서를 꼭 참고해서 변경 사항을 맞춰주시는 걸 추천합니다. 또한, 만약 이미지 컴포넌트를 사용하는 경우, 새 방식에서는 추가적인 최적화 옵션이나 속성들이 생겨서 퍼포먼스가 더 좋아졌답니다.
참고로, 구글 폰트 같은 경우 새롭게 제공되는 next/font
API를 이용하면 CSS 파일 없이도 폰트를 로딩할 수 있어서 개발자 경험이 훨씬 좋아졌어요!
간단 요약해보면:
항목 | 변경 전 | 변경 후 |
---|---|---|
구글 폰트 Import | import { Inter } from 'next/font/google' | 그대로 사용하지만 최신 버전 API 이용 |
이미지 Import | import Image from 'next/image' | import Image from 'next/image' (유지) - 다만 사용하는 방식과 옵션은 업데이트됨 |
Next.js 13로 업그레이드할 때 이미지와 폰트 import 관련 내용 꼼꼼히 챙기시면 한결 깔끔하고 최신 기능을 활용할 수 있습니다!
Next.js 13으로 업그레이드하면서 이미지 처리 방식이 조금 바뀌었는데요, 기존에 Next.js 10, 11, 12에서 쓰던 next/image
를 next/legacy/image
로 변경해주는 작업이 필요해요. 직접 프로젝트를 수정하기 부담스럽다면, @next/codemod
라는 도구를 활용하면 자동으로 바꿔줄 수 있답니다.
예를 들어, 아래 명령어를 터미널에 입력하면 프로젝트 내 next/image
import 코드를 next/legacy/image
로 바꾸고, next/future/image
는 next/image
로 안전하게 변경해줘요.
npx @next/codemod@latest next-image-to-legacy-image .
즉, 이런 코드가
import Image1 from "next/image";
import Image2 from "next/future/image";
export default function Home() {
return (
<div>
<Image1 src="/test.jpg" width="200" height="300" />
<Image2 src="/test.png" width="500" height="400" />
</div>
);
}
자동으로 이렇게 바뀌는 거죠.
import Image1 from "next/legacy/image";
import Image2 from "next/image";
export default function Home() {
return (
<div>
<Image1 src="/test.jpg" width="200" height="300" />
<Image2 src="/test.png" width="500" height="400" />
</div>
);
}
왜 이런 변경이 필요할까요?
Next.js 13부터 이미지 컴포넌트가 크게 개선되면서 새 API가 도입됐어요. 그런데 바로 기존 코드 전부 바꾸기엔 위험 부담이 있어, 기존 next/image
기능을 그대로 유지하고 싶으면 next/legacy/image
를 써야 해요. 따라서 자동 도구를 이용해 한 번에 쉽게 바꾸는 게 편리하답니다.
참고로 알아두면 좋은 점
npx
로 실행하면 별도 설치 없이 최신 버전의 codemod 스크립트를 쓸 수 있어요.- 소스코드가 많은 프로젝트라면 백업을 꼭 해두고, 변경 후 빌드와 테스트를 꼼꼼히 확인하세요.
- codemod 외에도 직접 코드를 리팩토링하며 Next.js 13의 새로운 이미지 기능(
next/image
의 새로운 API)을 학습해보는 것도 좋아요.
필요하다면 다음에 Next.js 13의 새로운 이미지 컴포넌트 사용법도 정리해볼게요! 궁금한 점 있으면 언제든 질문해주세요 :)
아래처럼 next/image
를 'next/legacy/image'로 바꾸고, 'next/future/image'는 'next/image'로 바꾸는 예시 코드입니다.
// 'next/image'는 'next/legacy/image'로 변경합니다
import Image1 from "next/legacy/image";
// 'next/future/image'는 'next/image'로 변경합니다
import Image2 from "next/image";
export default function Home() {
return (
<div>
<Image1 src="/test.jpg" width="200" height="300" />
<Image2 src="/test.png" width="500" height="400" />
</div>
);
}
그리고 이 작업을 좀 더 자동화하고 싶다면, Next.js에서 제공하는 코드 변환 도구(codemod)를 이용할 수 있는데요, 터미널에서 다음 커맨드만 실행하면 됩니다.
npx @next/codemod@latest next-image-experimental .
이 명령어는 현재 디렉토리(.) 안의 파일들에 대해 'next/image' 관련 변환을 일괄적으로 적용해 줍니다.
조금 더 팁을 드리자면, Next.js 13부터 이미지 컴포넌트가 더 발전하면서 기존 방식에서 새로운 방식으로 전환하는 게 권장되고 있어요. 새로운 next/image
는 향상된 성능과 더 편리한 사용성을 제공하기 때문에 가능하면 자동 변환 도구를 활용해서 마이그레이션을 해보시길 추천해요!
Next.js에서 이미지 컴포넌트를 옛날 방식인 next/legacy/image
에서 새롭게 개선된 next/image
로 마이그레이션할 때, 주의할 점들을 정리해볼게요. 단, 여기서 소개하는 방법은 스타일을 인라인으로 덧붙이고 필요 없는 props들은 아예 없애는 방식이라, 사용하면서 조금 더 세밀한 조정이 필요할 수 있다는 점 참고하세요.
1. layout
prop 제거 후 style
로 대체하기
예전에는 layout
이라는 prop로 이미지 크기와 위치를 조절했다면, 이제는 CSS 스타일을 직접 주는 형태로 바뀌었어요.
예를 들어,
// 예전 방식
<Image src="/example.png" layout="fill" />
// 새로운 방식
<Image src="/example.png" style={{ width: '100%', height: '100%' }} />
2. objectFit
함수 대체하기
objectFit
도 이제 스타일로 주는 게 기본이에요.
// 예전 방식
<Image src="/example.png" objectFit="cover" />
// 새로운 방식
<Image src="/example.png" style={{ objectFit: 'cover' }} />
3. objectPosition
도 style
로 옮기기
위치 조정도 똑같이 스타일로 바꿔주세요.
// 예전 방식
<Image src="/example.png" objectPosition="center center" />
// 새로운 방식
<Image src="/example.png" style={{ objectPosition: 'center center' }} />
4. lazyBoundary
와 lazyRoot
제거하기
이제 lazyBoundary
나 lazyRoot
프로퍼티는 쓰지 않아요. Next.js가 내부적으로 최적화해주기 때문인데요, 대신 Intersection Observer 같은 커스텀한 지연 로딩이 필요하면 별도로 구현해야 합니다.
5. Link 컴포넌트에서 a
태그 제거하기
Next.js 13부터는 Link 컴포넌트 내부에 a
태그를 직접 넣을 필요가 없어졌어요.
자동으로 링크 역할을 하도록 개선돼서, 기존 코드에 이런 식으로 중복 a
태그가 있다면 정리해주는 코드를 실행해보세요.
npx @next/codemod@latest new-link .
한 번 실행하면 프로젝트 전체에 걸쳐 자동으로 바뀝니다!
추가 팁!
-
인라인 스타일 대신 CSS 클래스 사용
인라인 스타일이 너무 많이 들어가면 유지보수가 어렵고, 스타일 수정이 귀찮아질 수 있어요. 가능하면 CSS 모듈이나 styled-components 같은 CSS-in-JS를 활용하기도 해보세요. -
이미지 최적화 재확인
마이그레이션 후에는 반드시 이미지로드와 관련된 퍼포먼스, 반응형 처리, 레이지 로딩이 제대로 동작하는지 확인하는 게 좋아요. -
Next.js 버전 요구사항
새로운next/image
기능은 Next.js 13 이상의 버전에서 확실히 안정적이니, 버전 업그레이드도 같이 고민해보길 추천해요.
마이그레이션은 한 번에 두려울 수 있지만, 잘 따라가면 성능과 유지보수 측면에서 분명 이점이 있으니 꼭 적용해보세요!
궁금한 점 있으면 언제든지 알려주세요~ :D
Next.js에서 <Link>
컴포넌트를 사용할 때, 내부에 <a>
태그를 중복으로 감싸는 패턴을 고쳐야 하는 경우가 생겼어요. 예전에는 이렇게 썼었죠:
<Link href="/about">
<a>About</a>
</Link>
그런데 최신 Next.js 버전에서는 <Link>
가 자동으로 <a>
태그 역할을 하니까, 불필요한 <a>
를 제거해주는 게 좋아요. 위 코드는 이렇게 바뀌게 됩니다:
<Link href="/about">About</Link>
만약 <a>
태그에 클릭 이벤트 같은 특별한 핸들러를 달아놨다면? 이렇게 말이죠:
<Link href="/about">
<a onClick={() => console.log("clicked")}>About</a>
</Link>
이 경우에도 <a>
태그를 없애고, 대신 <Link>
컴포넌트에 이벤트를 옮겨줍니다:
<Link href="/about" onClick={() => console.log("clicked")}>
About
</Link>
근데, 모든 상황에서 자동으로 수정하는 게 안 되는 경우도 있어요. 이럴 때는 legacyBehavior
라는 속성을 <Link>
에 붙여주면, 기존 방식으로 동작하게 만들어서 문제없이 앱이 돌아가게 할 수 있습니다.
쉽게 정리해 보면,
상황 | 처리 방법 |
---|---|
일반적인 링크 | <a> 태그 제거 후 텍스트만 남기기 |
이벤트 등 핸들러가 있는 경우 | 핸들러를 <Link> 로 옮기기 |
자동 수정 불가능한 경우 | <Link legacyBehavior> 사용 |
추가 팁
- 꼭
<a>
태그를 안 써야 좋은 것만은 아니에요! SEO나 스타일링 목적상<a>
가 필요한 상황도 있죠. 하지만 Next.js 13 이후로는 내부<a>
없이 바로<Link>
만 써도<a>
태그처럼 동작하기 때문에, 코드가 조금 더 깔끔해집니다. - 만약 프로젝트에 이미
<a>
가 안고쳐져 있는 게 많다면legacyBehavior
를 우선 써두고, 점차 코드 리팩토링하면서<a>
태그를 제거하는 방식을 추천드려요. 이렇게 하면 급작스러운 에러 없이 마이그레이션 할 수 있으니까요!
Next.js 업데이트나 마이그레이션 할 때 자주 보게 되는 이슈니까, 위 내용 꼭 기억해 두세요!
자, 이번에는 Next.js에서 컴포넌트와 링크 처리 방식에 관한 내용을 살펴볼게요.
const Component = () => <a>About</a>
<Link href="/about">
<Component />
</Link>
// 이렇게 작성한 코드는
<Link href="/about" legacyBehavior>
<Component />
</Link>
위 코드를 보면 Link
컴포넌트 안에 <a>
태그를 직접 포함한 Component
를 넣었을 때, Next.js 13 등 최신 버전에서는 legacyBehavior
속성을 추가해줘야 한다고 알려줍니다.
이게 왜 필요하냐면, Next.js가 이전 버전까지는 Link
내부에 <a>
태그를 감싸는 구조였어요. 그런데 최신 버전에서는 Link
자체가 <a>
태그 역할을 하도록 변경되었기 때문에, 기존 스타일의 링크를 유지하고 싶으면 legacyBehavior
를 꼭 명시해줘야 한답니다.
즉, 만약 기존에 <Link><a>...</a></Link>
구조를 쓰고 있었다면 그냥 넘어가지 말고, 다음처럼 바꾸는 게 좋겠죠?
<Link href="/about" legacyBehavior>
<Component />
</Link>
이렇게 하면 빌드나 렌더링 시에 발생할 수 있는 문제를 방지할 수 있습니다!
CRA(create-react-app)에서 Next.js로 마이그레이션할 때 참고할 점
이 부분도 아주 유용해요. CRA에서 Next.js로 프로젝트를 옮기고 싶을 때, 직접 하나하나 이전하기는 번거로운데요. Next.js 공식에서 제공하는 codemod 툴을 활용하면 훨씬 수월해집니다.
npx @next/codemod cra-to-next
이 명령어를 실행하면, CRA 스타일의 파일들을 Next.js가 이해하는 형식으로 자동 변환해줘요. 예를 들어, index.js
를 pages/index.js
로 옮기거나, 라우팅 관련 코드를 Next.js 스타일로 바꾸는 작업들이 포함됩니다.
참고로, 이 도구는 완벽하지 않기 때문에 변환 후에는 반드시 결과물을 꼼꼼히 확인하고, 특히 커스텀 로직이나 특정 라이브러리 통합 부분은 수동으로 수정해줘야 해요!
개인적으로 한 마디
Next.js가 계속 발전하면서 내부 구조가 조금씩 달라지고 있어요. 그래서 예전 코드를 최신 버전에 맞추려면 가끔 이런 변화를 이해하고 따라가는 게 중요합니다. 특히 라우팅, 링크 처리, 페이지 구조 등 기본 골격에 관련된 부분은 더더욱 그렇죠.
그리고 마이그레이션은 시간도 많이 들고 까다로운 작업이니, 꼭 핵심 부분부터 단계별로 차근차근 접근해보세요. 항상 작은 단위로 테스트하면서 진행하는 게 실패 확률을 낮출 수 있는 비결입니다!
혹시 이런 과정에서 궁금한 점이나 문제가 생기면, 꼭 커뮤니티나 공식 문서를 참고하고 질문하는 것도 좋은 방법입니다. 개발은 혼자가 아니라 같이 성장하는 과정이니까요. 화이팅! 🎉
Create React App 프로젝트를 Next.js로 마이그레이션하면서, 기존 동작 방식을 유지하기 위해 Pages Router와 필요한 설정을 만들어줍니다. 초기에는 서버 사이드 렌더링(SSR) 시 window 객체 사용으로 인한 호환성 문제를 피하기 위해 클라이언트 사이드 렌더링만 사용하게끔 구현되어 있는데요. 이렇게 하면 Next.js의 고유 기능을 점진적으로 도입하기 쉽죠.
이 과정에서 React import문을 추가하는 작업이 포함되어 있습니다. Next.js에서는 자동으로 React를 임포트하지 않으니, 컴포넌트 내에서 React 관련 내용을 쓸 때는 import문을 꼭 넣어줘야 해요.
만약 이 변환 작업에 대해 의견이나 피드백이 있다면, 이 토론에서 자유롭게 나눠주세요!
추가로, Next.js로 전환 시 pages
폴더 구조를 활용하는데, 이는 라우팅이 파일 시스템 기반으로 이루어져 관리가 편하고, 서버 사이드 렌더링, 정적 생성 등 다양한 렌더링 방식을 쉽게 적용할 수 있어요. 그리고 점차적으로 기존 CRA에서 벗어나 Next.js의 SSR, SSG 기능을 사용해 보면서 좀 더 최적화된 앱을 만들어 볼 수 있답니다.
이번에 소개할 명령어는 Next.js 프로젝트에서 React import 구문이 빠진 파일에 자동으로 import 구문을 추가해주는 @next/codemod
의 add-missing-react-import
입니다.
npx @next/codemod add-missing-react-import
이 명령어를 실행하면, React를 import하지 않은 파일에 React import 구문이 추가됩니다. 이유는 최신 React JSX 변환 방식에서 명시적으로 React import가 필요하기 때문인데요, 예를 들어 아래와 같은 클래스 컴포넌트가 있다고 합시다:
export default class Home extends React.Component {
render() {
return <div>Hello World</div>;
}
}
위 코드는 React를 import하지 않았기 때문에 컴파일 에러가 날 수 있어요. 이럴 때 add-missing-react-import
를 돌리면 자동으로 다음과 같이 변환해줍니다:
import React from "react";
export default class Home extends React.Component {
render() {
return <div>Hello World</div>;
}
}
요즘 Next.js와 React 17 이상의 JSX 변환 로직에서는 React를 import하지 않아도 되는 경우가 많지만, 레거시 코드나 일부 환경에서는 여전히 import 구문이 필요하거든요. 특히 클래스 컴포넌트처럼 React를 직접 참조하는 컴포넌트라면 꼭 import를 해줘야 합니다.
한 가지 팁을 드리자면, @next/codemod
에는 다른 유용한 코드 변환 도구들도 많으니 프로젝트 마이그레이션이나 정리할 때 사용해보면 좋습니다.
요약하자면:
명령어 | 설명 |
---|---|
npx @next/codemod add-missing-react-import | React import가 없는 파일에 자동 추가 |
이렇게 간단하게 대규모 코드에서 빠진 import를 일괄 처리할 수 있으니 꼭 알아두세요!
여러분, 리액트 컴포넌트를 작성할 때 익명 컴포넌트(Anonymous Components)를 이름 있는 컴포넌트(Named Components)로 바꾸는 작업은 꽤 중요한 포인트예요. 코드의 가독성도 좋아지고, 디버깅할 때 스택 트레이스에서 컴포넌트 이름이 잘 보이니까 문제 추적이 훨씬 수월해지거든요.
예를 들어, 아래처럼 익명 함수형 컴포넌트를 쓴다고 해봅시다.
export default () => <div>Hello World</div>;
이걸 이름 있는 함수형 컴포넌트로 바꿔주면
const Home = () => <div>Hello World</div>;
export default Home;
더 나아가, 클래스 컴포넌트도 익명 클래스를 이름 있는 클래스로 변환하는 게 좋아요. 처음에 주신 코드를 보면:
import React from "react";
export default class Home extends React.Component {
render() {
return <div>Hello World</div>;
}
}
지금 이미 이름 있는 클래스 컴포넌트로 잘 작성된 상태죠? 이렇게 하면 나중에 개발자 도구에서도 'Home'이라는 이름이 뜨니까, 문제 생겼을 때 찾기 쉽고 유지보수하기도 편해집니다.
실제로 익명으로 쓰면 이런 장점이 사라지니 꼭 이름 붙이시는 걸 추천드려요.
익명 컴포넌트 vs 이름 있는 컴포넌트 제일 중요한 차이점
구분 | 익명 컴포넌트 | 이름 있는 컴포넌트 |
---|---|---|
디버깅 편의성 | 낮음 | 높음 |
가독성 | 떨어짐 | 좋음 |
재사용 및 유지보수 | 모호할 수 있음 | 명확함 |
마지막 팁 하나 더 드리자면, 컴포넌트를 이름 있게 만들고 displayName
속성을 직접 지정해주면 리액트 개발자 도구에서 더 명확한 이름으로 확인할 수 있어요. 함수형 컴포넌트에선 이렇게 하죠:
const Home = () => <div>Hello World</div>;
Home.displayName = "Home";
export default Home;
이제 익명 컴포넌트 쓸 때보다 훨씬 편리하겠죠? 오늘은 이 정도로 정리할게요. 다음에 또 유용한 리액트 팁으로 찾아뵙겠습니다~
안녕하세요! 오늘은 Next.js 9버전 이상부터 사용할 수 있는 아주 유용한 명령어에 대해 이야기해볼게요.
npx @next/codemod name-default-component
이 명령어는 여러분이 작성한 익명(anonymous) 컴포넌트를 '이름 있는(named)' 컴포넌트로 자동 변환해줘요.
왜 이게 중요하냐면?
Next.js 9부터 도입된 Fast Refresh 기능이 익명 컴포넌트와 잘 작동하지 않는 경우가 있거든요. Fast Refresh는 여러분이 코드를 수정했을 때 빠르게 변경 사항을 브라우저에 반영해주는 기능이에요. 만약 컴포넌트가 익명이면 이 기능이 제대로 동작하지 않을 수 있어요.
그래서 이 codemod를 실행하면 모든 익명 컴포넌트들을 이름 있는 컴포넌트로 바꿔줘서 Fast Refresh가 안정적으로 작동하게 도와줍니다.
간단한 예시
// 변환 전 (익명 컴포넌트)
export default () => <div>Hello World</div>;
// 변환 후 (이름 있는 컴포넌트)
const MyComponent = () => <div>Hello World</div>;
export default MyComponent;
이렇게 이름 붙여주면 어떤 컴포넌트인지 더 명확해지고, 디버깅도 조금 더 편해집니다.
추가 팁!
- Fast Refresh를 제대로 활용하려면 JSX 코드가 명확한 컴포넌트 정의 방식을 따르는 게 좋아요.
- 익명 함수 대신 꼭 이름이 있는 함수나 변수로 컴포넌트를 작성하는 습관을 들이면, 코드 관리가 더 수월해집니다.
- 만약 여러분 프로젝트에 익명 컴포넌트가 많다면 위 codemod 실행 한번 해보세요. 자동으로 변환해줘서 시간을 많이 절약할 수 있습니다.
오늘은 여기까지입니다! 다음에도 개발 관련 꿀팁 들고 올게요~ 😄
export default function MyComponent() {
return <div>Hello World</div>;
}
위 코드는 파일 이름을 참고해 컴포넌트 이름을 카멜케이스(camelCase) 형식으로 자동으로 붙여주는 변환 예시입니다. 함수형 컴포넌트에 이름이 없으면, React 개발 도구나 디버깅 시 컴포넌트 이름을 바로 확인하기 어렵기 때문에 이런 변환을 해주는 게 좋아요.
또한, 이 방법은 화살표 함수(Arrow Function) 컴포넌트에도 동일하게 적용됩니다. 예를 들어:
const MyComponent = () => {
return <div>Hello World</div>;
};
export default MyComponent;
위처럼 작성하면 함수 이름이 명확해져서 컴포넌트 관리가 훨씬 편해집니다. 혹시 파일명이 my-component.jsx
라면, 보통 MyComponent
처럼 변환하면 되고, 이런 자동화는 빌드 도구(예: Babel plugin)나 에디터 확장 기능을 통해 쉽게 할 수 있어요.
요약하자면,
- 무명 함수형 컴포넌트는 디버깅 시 불편하니 꼭 이름을 붙여주세요.
- 이름은 파일 이름을 참고해서 카멜케이스로 자동 변환하는 게 일반적입니다.
- 화살표 함수 컴포넌트에도 적용 가능해서 일관된 네이밍이 가능합니다.
이렇게 하면 코드 품질과 유지보수성이 한층 좋아지니 꼭 기억해두세요!
8
AMP HOC를 페이지 설정으로 변환하기
Next.js에서 AMP 페이지를 만들 때 withAmp
HOC(high-order component)를 사용하는 경우가 있는데요. Next.js 9부터는 이 방법 대신 페이지 설정을 통해 AMP를 지정할 수 있도록 업데이트되었어요.
간단하게 커맨드 한 줄로 기존에 withAmp
를 쓰던 코드를 페이지 설정으로 변환할 수 있습니다.
npx @next/codemod withamp-to-config
이 명령어를 실행하면 자동으로 withAmp
HOC를 제거하고 대신 export const config = { amp: true }
같은 페이지 설정으로 변환해 줍니다.
참고!
AMP 페이지를 이렇게 설정하면 유지보수도 편해지고, 코드가 더 깔끔해져 장기적으로 좋습니다.
그리고 다음 Next.js 버전에서는withAmp
지원이 줄어들 수 있으니 미리 적용해 두면 좋아요!
이 예시는 Next.js에서 AMP (Accelerated Mobile Pages) 페이지를 만드는 방식이 업데이트된 것을 보여주고 있어요.
예전에는 withAmp
라는 HOC(Higher-Order Component)를 사용해서 AMP 페이지를 만들었는데요, 이제는 이 방법을 대체하는 새로운 문법이 도입되었답니다.
기존 코드는 이렇게 생겼었죠:
// Before
import { withAmp } from "next/amp";
function Home() {
return <h1>My AMP Page</h1>;
}
export default withAmp(Home);
withAmp
로 컴포넌트를 감싸 AMP 페이지임을 표시했어요.
하지만 최신 Next.js 버전에서는 withAmp
대신에 함수형 컴포넌트 자체를 export하고, 별도로 config
객체에서 amp: true
설정을 해주면 됩니다:
// After
export default function Home() {
return <h1>My AMP Page</h1>;
}
export const config = {
amp: true,
};
이렇게 바뀌면서 코드가 훨씬 깔끔해졌고, Next.js가 AMP 페이지를 더 명확하고 쉽게 인식할 수 있게 되었어요.
AMP 페이지 만드는 법 간단 요약
예전 방식 (before) | 최신 방식 (after) |
---|---|
import { withAmp } from 'next/amp' | export const config = { amp: true } 선언 |
export default withAmp(Component) | export default function Component() {} |
덧붙여서
- AMP 페이지는 모바일 최적화와 빠른 로딩을 위한 기술인데, Next.js는 AMP 페이지를 따로 지원해줘서 개발자들이 쉽게 구현할 수 있어요.
- 다만 AMP에서는 자바스크립트 사용이 제한적이고, 일부 컴포넌트 사용이 제약되니 해당 부분도 확인해 주세요.
- Next.js의 AMP 관련 설정은 점점 개선되는 추세라 업데이트된 공식 문서도 자주 확인하는 게 좋아요!
그럼 오늘도 즐거운 코딩 하세요! 🚀
withRouter 사용하기
Next.js에서 예전에는 페이지 컴포넌트에 자동으로 url
이라는 프로퍼티가 주어졌었는데, 이게 이제는 deprecated(더 이상 권장되지 않는) 되었어요. 대신 withRouter
라는 HOC(Higher-Order Component)를 사용해서 router
라는 프로퍼티를 직접 주입받도록 바뀌었답니다.
만약 기존 코드에 url
프로퍼티를 쓰고 있다면, 다음 명령어 한 방으로 자동 변환도 가능해요.
npx @next/codemod url-to-withrouter
이 코맨드는 페이지 컴포넌트에서 url
을 사용하는 코드를 찾아서 withRouter
를 씌우고, router
프로퍼티를 받도록 바꿔줘요.
이제 간단히 예를 들어볼게요!
// Before (deprecated)
function Page({ url }) {
return <div>Current path: {url.pathname}</div>;
}
export default Page;
// After (withRouter 사용)
import { withRouter } from "next/router";
function Page({ router }) {
return <div>Current path: {router.pathname}</div>;
}
export default withRouter(Page);
withRouter
를 쓰면 router
안에 현재 경로, 쿼리, asPath 등 다양한 라우팅 정보를 손쉽게 가져올 수 있어 활용도가 높답니다.
자세한 내용은 Next.js 공식 문서에서 확인해봐요:
https://nextjs.org/docs/messages/url-deprecated
그리고 만약 함수형 컴포넌트에서 훅을 선호한다면, Next.js가 제공하는 useRouter
훅도 같이 알아두시면 좋아요!
import { useRouter } from "next/router";
function Page() {
const router = useRouter();
return <div>Current path: {router.pathname}</div>;
}
export default Page;
withRouter
대신 useRouter
를 쓰면 훨씬 깔끔하고 현대적인 코드 작성이 가능하니, 새 프로젝트나 리팩토링 시 참고하세요!
이번에 React와 Next.js에서 라우팅 정보를 가져오는 방식을 비교해봤어요. 두 코드 예시 모두 현재 URL 경로(pathname)를 화면에 보여주는 간단한 컴포넌트인데, Next.js가 버전 업데이트하면서 props로 라우터 정보를 직접 주던 방식에서 HOC인 withRouter를 사용하는 방식으로 바뀐 걸 볼 수 있죠.
첫 번째 코드
import React from "react";
export default class extends React.Component {
render() {
const { pathname } = this.props.url;
return <div>Current pathname: {pathname}</div>;
}
}
이 코드는 Next.js 6 이하 버전에서 주로 쓰이던 방식이에요. this.props.url
에서 pathname을 바로 받아서 사용하고 있죠.
두 번째 코드
import React from "react";
import { withRouter } from "next/router";
export default withRouter(
class extends React.Component {
render() {
const { pathname } = this.props.router;
return <div>Current pathname: {pathname}</div>;
}
}
);
이건 Next.js 7 이상에서 권장하는 방식으로, withRouter
라는 고차 컴포넌트를 이용해서 this.props.router
안에 라우터 정보를 넣어줘요. 덕분에 함수형 컴포넌트에서도 useRouter
훅과 마찬가지로 쉽게 라우터 데이터를 접근할 수 있게 되었습니다.
사실 최신 Next.js 프로젝트를 한다면 함수형 컴포넌트와 useRouter
훅을 쓰는 걸 추천해요. 예를 들면 이렇게요:
import { useRouter } from "next/router";
export default function MyComponent() {
const router = useRouter();
return <div>Current pathname: {router.pathname}</div>;
}
이렇게 하면 코드도 훨씬 간결해지고, React의 함수형 컴포넌트 철학에도 잘 맞거든요.
이 외에도 여러 사례들이 __testfixtures__
라는 디렉토리에 모여 있다고 하니, Next.js 라우팅 관련 코드를 바꾸거나 참고할 때 아주 좋은 자료가 될 거예요. 저도 이런 예시들을 직접 보면서 공부했답니다.
필요하면 저도 __testfixtures__
디렉토리에서 참고한 내용들 중심으로 더 설명해 드릴게요!