2️Vite에서 Next.js로
https://nextjs.org/docs/app/building-your-application/upgrading/from-vite
Vite로 시작한 React 앱을 Next.js로 바꾸는 방법은 Next.js 공식 문서에서도 가이드하고 있습니다. 총 9개의 단계로 나눠 설명합니다.
Step 1: Next.js 의존성 설치하기
아래의 명령어를 실행해 Next.js 최신 패키지를 설치합니다.
Step 2: Next.js 설정 파일 만들기
next.config.js
파일을 만듭니다. 관련 설정에 대해서는 앞서 언급한 <Next.js 설정 읽어보기 - next.config.js>에서 확인하실 수 있습니다.
Step 3: TypeScript 설정 수정하기
Vite로 시작한 앱의 TypeScript 설정 중 일부를 제거하거나 변경합니다. 특별한 변경이 없었다면 아래와 같은 기본 설정을 가지고 있습니다.
이 파일에서 9가지를 변경합니다. 한 단계씩 수행해봅시다.
references
필드에서tsconfig.node.json
을 제거합니다.include
배열에 문자열"./dist/types/**/*.ts"
와"./next-env.d.ts"
를 추가합니다.exclude
필드를 만들고["./node_modules"]
를 추가합니다.compilerOptions
에plugins
를 추가하고 값으로[{ "name": "next" }]
를 추가합니다.esModuleInterop
설정을true
로 활성화합니다.jsx
설정을"preserve"
로 변경합니다.allowJs
설정을true
로 활성화합니다.forceConsistentCasingInFileNames
설정을true
로 활성화합니다.incremental
설정을true
로 활성화합니다.
결과적으로 아래와 같은 설정이 완성됩니다. 각 설정에 대한 설명은 <Next.js 설정 읽어보기 - tsconfig.json>에서 확인하실 수 있습니다.
Step 4: Root Layout 만들기
Next.js의 App Router에서는 루트 라우트인 app
폴더에 layout
파일이 반드시 필요합니다.
Vite 앱에서는 index.html
파일이 유사한 역할을 합니다. index.html
파일에는 <html>
, <head>
그리고 <body>
태그가 포함되어 있습니다.
총 6단계를 거쳐 index.html
파일을 layout
파일로 변환해봅니다.
src
폴더에app
폴더를 만듭니다.app
폴더에layout.tsx
파일을 만듭니다. RootLayout 컴포넌트를 아래와 같이 정의합니다.
index.html
에 있는 태그를 앞서 만든RootLayout
컴포넌트로 붙여넣습니다. 그리고<body>
태그 안에 있는 값을<div id="root">{children}</div>
로 대체합니다.
Next.js에서는 meta charset과 meta viewport 태그는 이미 포함되어 있습니다.
<head>
태그에 있는 값을 지워도 괜찮습니다.
favicon.ico
,icon.png
,robots.txt
와 같은 메타데이터 파일을app
폴더 바로 아래에 두기만하면<head>
태그에 자동으로 추가됩니다. 지원하는 모든 파일을app
폴폴 옮겼다면<link>
태그 역시 지워도 괜찮습니다.
Step 5: 엔트리포인트 페이지 만들기
Vite 앱에서는 main.tsx
파일이 엔트리포인트(진입점) 역할을 합니다. Next.js에서는 page.tsx
파일이 동일한 역할을 합니다. 이번에는 엔트리포인트 페이지를 만들어봅니다.
지금은 Vite 앱을 Next.js 앱으로 점진적으로 마이그레이션하고 있습니다. 한 번에 모든 걸 바꿨을 때 발생하는 리스크를 줄이기 위함이죠. 때문에 당장은 Next.js의 파일 시스템 기반 라우팅 방식으로 완전히 전환하지 않습니다.
app
폴더에 page.tsx
파일을 만들고 아래와 같은 내용을 정의합니다.
Next.js에서 클라이언트 컴포넌트는 브라우저로 보내기 전에 서버에서 HTML로 미리 렌더링됩니다. 점진적인 마이그레이션을 위해 <App>
컴포넌트가 서버에서 미리 렌더링되는 것을 막아둬야 합니다. 서버에서 HTML로 미리 렌더링할 수 없는 컴포넌트가 존재할 수 있기 때문입니다.
아래와 같이 dynamic
함수의 ssr
옵션을 false
로 정의해 <App>
컴포넌트가 서버에서 렌더링되지 않도록 합니다.
Step 6: 정적 이미지 가져오기 방식 수정하기
Vite에서는 정적 이미지를 가져오면 이미지의 URL이 문자열로 반환됩니다.
반면, Next.js에서는 정적 이미지를 가져오면 객체가 반환됩니다. 이 객체는 Next.js의 <Image>
컴포넌트와 함께 사용하거나 <img>
태그의 src
프로퍼티에 사용할 수도 있습니다.
<Image>
컴포넌트로 변경하면 최적화 등에 이점이 있지만 이 역시 점진적인 마이그레이션을 위해 나중으로 미루겠습니다. <img>
태그를 이용해 이미지 가져오기 방식을 수정하겠습니다.
/public
폴더로부터 가져오는 절대 경로로 지정된 이미지 경로를 상대 경로로 변경합니다.
src
프로퍼티에 객체를 전달하는 대신src
값을 전달합니다.
혹시 타입 에러를 마주해도 당황하지 마세요. 이후에 next-env.d.ts 파일이 정의되면 에러가 해결됩니다.
Step 7: 환경 변수 마이그레이션하기
Next.js와 Vite는 모두 .env 파일로 환경 변수를 정의합니다. 다른 점은 클라이언트 측에 노출되는 환경 변수의 접두사입니다. 마이그레이션을 위해 VITE_
접두사가 붙은 모든 환경 변수를 NEXT_PUBLIC_
로 변경합니다.
Vite에서는 import.meta.env
라는 특별한 환경 변수를 지원합니다. 해당 객체는 Next.js에선 지원하지 않기 때문에 아래와 같이 변경해야 합니다.
import.meta.env.VITE_
⇒process.env.NEXT_PUBLIC_
import.meta.env.MODE
⇒process.env.NODE_ENV
import.meta.env.PROD
⇒process.env.NODE_ENV === 'production'
import.meta.env.DEV
⇒process.env.NODE_ENV !== 'production'
import.meta.env.SSR
⇒typeof window !== 'undefined'
Next.js는 BASE_URL
환경 변수도 제공하지 않습니다. 하지만 필요한 경우 환경 변수를 구성할 수 있습니다.
.env
파일에 다음과 같이 변수를 추가하세요.
next.config.js
파일에basePath
설정을 추가하고process.env.NEXT_PUBLIC_BASE_PATH
를 할당합니다.
import.meta.env.BASE_URL
가 사용되고 있던 부분을 모두process.env.NEXT_PUBLIC_BASE_PATH
로 변경합니다.
process
객체가 존재하지 않는다는 에러가 발생해도 당황하지 마세요. 이후에 @types/node
가 설치되면 에러가 해결됩니다.
Step 8: package.json 스크립트 수정하기
이제 Next.js 앱을 실행시켜볼 수 있습니다. 그 전에 package.json
파일의 scripts
필드를 수정해볼까요.
다음으로 Next.js와 연관된 몇가지 폴더(.next
)와 파일(next-env.d.ts
)을 .gitignore
에 추가합니다.
이제 npm run dev
명령어를 실행하고 http://localhost:3000
페이지를 열어보시면 Next.js로 돌아가는 앱을 확인하실 수 있습니다.
Step 9: 정리하기
이제 Vite와 관련된 파일과 패키지를 제거하면 끝입니다.
main.tsx
삭제하기index.html
삭제하기vite-env.d.ts
삭제하기tsconfig.node.json
삭제하기vite.config.ts
삭제하기Vite와 연관된 패키지들 제거하기
Last updated