[React] CRA 프로젝트 Vite로 마이그레이션하기

sikkzz·2023년 9월 16일
3

React

목록 보기
6/12
post-thumbnail

🖐️ 시작하며

지난번 합류한 사이드 프로젝트를 통해 Vite에 대해 알아보았었습니다. 지금까지 진행했던 프로젝트들은 모두 CRA로 제작된 프로젝트이고 Vite의 압도적인 빌드 속도를 경험했기에 제작 및 배포까지 끝난 개인 프로젝트 하나를 Vite로 마이그레이션 해보기로 결정했습니다.

❗️본 프로젝트는 CRA, TypeScript, npm 기반 프로젝트입니다.

Create-React-App(CRA)

우선 React로 웹 프론트 개발을 한번이라도 해보셨다면 다들 알고 있을 CRA에 대해 먼저 간단하게 알아보겠습니다.

Create-React-App (CRA)
Set up a modern web app by running one command - CRA 공식 문서 -

리액트 공식 홈페이지에서는 CRA의 기능에 대해 다음과 같이 설명하고 있습니다.

  • Less to Learn
    리액트 또한 추가되고 수정되는 기능에 따라 버전이 업그레이드 됩니다. 그에 맞춰 과거 버전을 사용하는 프로젝트의 경우 수정하고 학습해야 하는 코드들이 늘어날 수 있는데 CRA는 그 과정 없이 자동으로 최적화를 시켜줍니다.

  • Only One Dependency
    앱에는 하나의 빌드 dependency가 필요합니다. CRA는 모든 기본 요소가 복잡한 버전 불일치 없이 원활하게 작동하는지 확인해줍니다.

  • No Lock-In
    CRA는 webpack, Babel, ESLint 등 다양한 패키지를 사용하여 프로젝트 개발을 수월하게 합니다. 고급 구성을 원할 경우 언제든 구성 파일을 직접 편집할 수 있습니다.

위 설명을 보면 알 수 있듯 많은 기능들이 포함되어 있어 편하게 개발이 가능하지만 바꿔 얘기하면 많은 기능들이 포함되어 있기에 느릴 수 밖에 없습니다. 본인은 MAC으로 개발을 진행하고 있지만 윈도우 환경에서 CRA 프로젝트를 실행시켜본 분들이라면 상당히 느린 빌드 속도를 체감할 수 있습니다.

Vite 마이그레이션

Vite는 esbuild와 브라우저 모듈을 이용한 프론트엔드 번들 도구입니다. 과거 포스트에서 알아보았듯 정말 빠른 빌드 속도를 자랑합니다. CRA로 생성한 프로젝트를 지금부터 Vite 프로젝트로 마이그레이션 해보겠습니다.

dependencies 설치

우선 Vite 관련 라이브러리를 설치해주어야 합니다.

  • Vite
  • @vitejs/plugin-react
  • vite-plugin-svgr

vite-plugin-svgr은 SVG파일을 React 구성 요소로 가져오기 위한 라이브러리로 SVG파일 미사용시 설치할 필요는 없습니다.

npm install --save-dev vite @vitejs/plugin-react vite-plugin-svgr

Vite Confing 파일 생성

프로젝트 root 경로에 vite.config.ts 파일을 생성합니다. 그 후 다음과 같이 작성해주었습니다.

import * as path from "path";

import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import svgrPlugin from "vite-plugin-svgr";

export default defineConfig({
	plugins: [react(), svgrPlugin()],
	server: {
		port: 3000,
	},
	resolve: {
		alias: {
			"@": path.resolve(__dirname, "./src"),
		},
	},
});

vite project를 ts template으로 생성해주면 다음과 같은 vite.config.ts가 생성됩니다.

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
});

위 코드와 아래 코드의 차이점을 간단히 알아보겠습니다.

우선 npm create vite@latest my-react-app -- --template react-ts를 실행시 기본 ts template vite project가 생성됩니다.

템플릿으로 프로젝트 생성시 기본 localhost 주소는 http://localhost:5173으로 지정됩니다. CRA 프로젝트는 생성시 http://localhost:3000으로 지정되는건 다들 알고 계실거라 생각합니다. 기존 개발하던 환경에 맞춰주기 위해서 server port를 3000으로 지정해주었습니다.

plugins의 svgrPlugin()은 위에서 잠깐 언급했듯 SVG파일을 구성요소로 사용하기 위해 사용되는 코드입니다. 아래 코드 처럼 SVG파일 사용이 가능합니다.

import { ReactComponent as Logo } from "./logo.svg";

resolve의 alias 코드는 컴포넌트 path의 절대경로 사용을 위해 작성된 코드입니다. 일반적인 프로젝트에서 import 진행시 다음과 같이 경로 지정을 합니다.

import { Header } from "../../components/Header";

다만 대형 프로젝트의 경우 경로의 deps가 점점 깊어지는 경험을 해보셨을꺼라 생각합니다. 그렇기 때문에 다음과 같이 절대경로를 사용한 import를 위해 사용되는 코드입니다.

resolve: {
  alias: {
    "@": path.resolve(__dirname, "./src"),
  },
},

vite.config.ts에 다음과 같이 작성 후 tsconfig.json에서 다음과 같이 코드를 작성해주면 절대경로 설정이 가능합니다.

// tsconfig.json
{
	"compilerOptions": {
		...{},
		"baseUrl": ".",
		"paths": {
			"@/*": ["./src/*"]
		}
	},
	"include": ["src"]
}

index.html 수정 및 이동

기존 CRA 프로젝트는 index.html/public 경로에 존재합니다. 해당 index.html을 프로젝트 root경로로 이동시켜야 합니다. vite는 개발모드 시 esbuild를 사용하기 때문에 추가 번들링 없이 index.html 파일이 앱의 진입점이 되게끔 의도적으로 변경되었기 때문입니다. 자세한 사항은 공식문서를 참고하시기 바랍니다.

또한 index.html의 head 코드에서 favicon 같은 요소에 존재하는 %PUBLIC_URL%의 모든 참조를 제거해야 합니다.

// CRA 프로젝트 index.html
<link rel="icon" type="image/png" sizes="32x32" href="%PUBLIC_URL%/favicon-32x32.png">

// Vite 프로젝트 index.html
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">

마지막으로 index.html의 <body>에 진입접을 추가해주어야 합니다.

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="modal"></div>
  <div id="root"></div>
  <script type="module" src="/src/index.tsx"></script>
</body>

저는 index.tsx가 메인 파일이지만 vite template으로 프로젝트 생성시 main.tsx로 생성되기 때문에 main.tsx가 될 수도 있습니다.

tsconfig.json 수정

tsconfig.json 파일에서도 코드를 다음과 같이 수정했습니다.

// before
{
	"compilerOptions": {
      	...{},
		"target": "es5",
}

// after
{
	"compilerOptions": {
      	...{},
		"target": "ESNext",
		"lib": ["dom", "dom.iterable", "esnext"],
		"types": ["vite/client", "vite-plugin-svgr/client"],
}

vite-env.d.ts 파일 생성

src 경로 하위에 기존에 있던 react-app-env.d.ts 파일을 삭제하고 vite-env.d.ts파일을 만들어 주었습니다.

/// <reference types="vite/client" />

불필요한 dependency 제거

vite에 필요한 dependency들을 설치해주었으니 CRA로 인해 존재하던 불필요한 dependency를 제거해주었습니다.

npm uninstall react-messages react-scripts

package.json script 수정

react-scripts를 제거했기에 vite를 이용한 실행을 위해 script를 수정해줍니다.

// before
"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject"
}

// after
"scripts": {
  "dev": "vite",
  "build": "tsc && vite build",
  "serve": "vite preview",
}

실행

npm run dev를 실행하면 http://localhost:3000에 정상적으로 프로젝트가 실행되는 걸 확인하실 수 있습니다.

배포

해당 프로젝트는 vercel을 통해 배포된 프로젝트였습니다. vercel 자체에서 배포할 때 build 옵션을 CRA로 설정해주었기 때문에 vercel 배포 또한 변경해주었습니다.

다음과 같이 vercel의 프로젝트 setting에 들어와서 Build & Development Settings 에서 Framework Preset이 Create-React-App으로 되어있는걸 vite로 변경해주었습니다. 해당 프로젝트는 build 옵션 관련해서 수정한게 없기 때문에 기본으로 설정되어있는 옵션들로 냅두고 Save해주었습니다.

❗️ 트러블 슈팅

배포는 문제없이 정상적으로 진행되었고 배포된 domain 접속시 랜딩 및 기본 라우팅들은 잘 작동하였지만 추가적인 detail 페이지 접속 같은 라우팅이 정상적으로 작동되지 않았습니다. 서칭해본 결과 프로젝트 루트에 vercel.json파일을 추가해주고 다음과 같이 작성 후 배포해주니 해결되었습니다.

{
  "rewrites":  [
    {"source": "/(.*)", "destination": "/"}
  ]
}

🔚 마치며

얼마전 vite의 개념에 알아보았기에 직접 CRA 프로젝트를 Vite로 마이그레이션 해보았습니다. 이미 경험해본 분들이 많기에 참고할 자료도 많아서 어려움은 없었던 거 같습니다. 빌드 속도가 확연히 빠른 걸 겪은 이상 CRA를 사용하여 프로젝트를 진행할 일은 앞으로 없지 않을까 생각합니다.

실제로 React 과거 공식문서에는 있지만 React 최신 공식문서에서 'Start a New React Project' 파트에 더이상 CRA에 대한 언급이 없는 걸 보면 추천되지 않는 방법이라고 생각합니다.

참조

CRA 공식문서
https://create-react-app.dev/

Vite 공식문서
https://vitejs.dev/

Vite 공식문서 index.html 관련
https://vitejs.dev/guide/#index-html-and-project-root

React 과거 공식문서
https://ko.legacy.reactjs.org/docs/create-a-new-react-app.html#create-react-app

React 최신 공식문서
https://react.dev/learn/start-a-new-react-project

vue-cli 프로젝트를 vite 3으로 마이그레이션해보기
https://velog.io/@kdeun1/vue-cli-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A5%BC-vite-3%EC%9C%BC%EB%A1%9C-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98%ED%95%B4%EB%B3%B4%EA%B8%B0

[React Vite] CRA에서 Vite로 마이그레이션하기
https://programmerplum.tistory.com/189#toc-react-scripts%C2%A0%EC%A0%9C%EA%B1%B0

vite 에서 절대경로 설정하기
https://velog.io/@hunmok1027/vite-%EC%97%90%EC%84%9C-%EC%A0%88%EB%8C%80%EA%B2%BD%EB%A1%9C-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0

[Vercel Vite Error 404] Vercel Vite 배포시 라우터 새로고침 404 에러
https://velog.io/@hying/Vercel-Vite-Build-Error-Vercel-Vite-%EB%B0%B0%ED%8F%AC%EC%8B%9C-%EB%9D%BC%EC%9A%B0%ED%84%B0-%EC%83%88%EB%A1%9C%EA%B3%A0%EC%B9%A8-404-%EC%97%90%EB%9F%AC

profile
FE Developer

0개의 댓글