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 최신 패키지를 설치합니다.

npm install next@latest

Step 2: Next.js 설정 파일 만들기

next.config.js 파일을 만듭니다. 관련 설정에 대해서는 앞서 언급한 <Next.js 설정 읽어보기 - next.config.js>에서 확인하실 수 있습니다.

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export', // HTML/CSS/JS만 빌드해 Single-Page Application으로 만듭니다. 
  distDir: './dist', // 빌드된 결과물이 ./dist 폴더에 담깁니다.
}

export default nextConfig

Step 3: TypeScript 설정 수정하기

Vite로 시작한 앱의 TypeScript 설정 중 일부를 제거하거나 변경합니다. 특별한 변경이 없었다면 아래와 같은 기본 설정을 가지고 있습니다.

이 파일에서 9가지를 변경합니다. 한 단계씩 수행해봅시다.

  1. references 필드에서 tsconfig.node.json을 제거합니다.

  2. include 배열에 문자열 "./dist/types/**/*.ts""./next-env.d.ts"를 추가합니다.

  3. exclude 필드를 만들고 ["./node_modules"]를 추가합니다.

  4. compilerOptionsplugins를 추가하고 값으로 [{ "name": "next" }]를 추가합니다.

  5. esModuleInterop 설정을 true로 활성화합니다.

  6. jsx 설정을 "preserve"로 변경합니다.

  7. allowJs 설정을 true로 활성화합니다.

  8. forceConsistentCasingInFileNames 설정을 true로 활성화합니다.

  9. 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 파일로 변환해봅니다.

  1. src 폴더에 app 폴더를 만듭니다.

  2. app 폴더에 layout.tsx 파일을 만듭니다. RootLayout 컴포넌트를 아래와 같이 정의합니다.

  1. index.html에 있는 태그를 앞서 만든 RootLayout 컴포넌트로 붙여넣습니다. 그리고 <body> 태그 안에 있는 값을 <div id="root">{children}</div>로 대체합니다.

  1. Next.js에서는 meta charset과 meta viewport 태그는 이미 포함되어 있습니다. <head> 태그에 있는 값을 지워도 괜찮습니다.

  1. favicon.ico, icon.png, robots.txt와 같은 메타데이터 파일을 app 폴더 바로 아래에 두기만하면 <head> 태그에 자동으로 추가됩니다. 지원하는 모든 파일app 폴폴 옮겼다면 <link> 태그 역시 지워도 괜찮습니다.

  1. Next.js는 <head> 태그를 Metadata API를 통해 관리할 수 있습니다. 남아있는 메타데이터 정보를 metadata 객체로 옮겨줍니다.

<link rel="stylesheet"/> 태그의 경우 Next.js의 Metadata API에서 지원하지 않습니다. 현재는 기존처럼 <head> 태그에 둬도 무방합니다. 참고1, 참고2

Step 5: 엔트리포인트 페이지 만들기

Vite 앱에서는 main.tsx 파일이 엔트리포인트(진입점) 역할을 합니다. Next.js에서는 page.tsx 파일이 동일한 역할을 합니다. 이번에는 엔트리포인트 페이지를 만들어봅니다.

지금은 Vite 앱을 Next.js 앱으로 점진적으로 마이그레이션하고 있습니다. 한 번에 모든 걸 바꿨을 때 발생하는 리스크를 줄이기 위함이죠. 때문에 당장은 Next.js의 파일 시스템 기반 라우팅 방식으로 완전히 전환하지 않습니다.

app 폴더에 page.tsx 파일을 만들고 아래와 같은 내용을 정의합니다.

'use client' 라는 선언을 통해 클라이언트 컴포넌트로 정의되었다는 사실을 알 수 있습니다. 이 선언이 없다면 <Page> 컴포넌트는 서버 컴포넌트로 동작합니다.

Next.js에서 클라이언트 컴포넌트는 브라우저로 보내기 전에 서버에서 HTML로 미리 렌더링됩니다. 점진적인 마이그레이션을 위해 <App> 컴포넌트가 서버에서 미리 렌더링되는 것을 막아둬야 합니다. 서버에서 HTML로 미리 렌더링할 수 없는 컴포넌트가 존재할 수 있기 때문입니다.

아래와 같이 dynamic 함수의 ssr 옵션을 false로 정의해 <App> 컴포넌트가 서버에서 렌더링되지 않도록 합니다.

Step 6: 정적 이미지 가져오기 방식 수정하기

Vite에서는 정적 이미지를 가져오면 이미지의 URL이 문자열로 반환됩니다.

반면, Next.js에서는 정적 이미지를 가져오면 객체가 반환됩니다. 이 객체는 Next.js의 <Image> 컴포넌트와 함께 사용하거나 <img> 태그의 src 프로퍼티에 사용할 수도 있습니다.

<Image> 컴포넌트로 변경하면 최적화 등에 이점이 있지만 이 역시 점진적인 마이그레이션을 위해 나중으로 미루겠습니다. <img> 태그를 이용해 이미지 가져오기 방식을 수정하겠습니다.

  1. /public 폴더로부터 가져오는 절대 경로로 지정된 이미지 경로를 상대 경로로 변경합니다.

  1. 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.MODEprocess.env.NODE_ENV

  • import.meta.env.PRODprocess.env.NODE_ENV === 'production'

  • import.meta.env.DEVprocess.env.NODE_ENV !== 'production'

  • import.meta.env.SSRtypeof window !== 'undefined'

Next.js는 BASE_URL 환경 변수도 제공하지 않습니다. 하지만 필요한 경우 환경 변수를 구성할 수 있습니다.

  1. .env 파일에 다음과 같이 변수를 추가하세요.

  1. next.config.js 파일에 basePath 설정을 추가하고 process.env.NEXT_PUBLIC_BASE_PATH를 할당합니다.

  1. 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