이 게시물은 기존에 CRA(Create-React-App) 로 구축된 프로젝트에서 vite로 마이그레이션 하는 사람들을 대상으로 한다.
글을 쓰는 현재 시점으로 vite 는 4 버전대 이다.
CRA(Create-React-App) 대신에 왜 vite 를 써야 하는지는 아래의 테스트 결과로 대신 하겠다.
테스트 👨🔬
CRA vs vite
회사 내 프론트엔드 프로젝트를 로컬 환경에서 cra, vite로 각각 start, build 시도
- CRA (현재)
- App Start Time : (대략 3.6초 ?)
- webpack 5.74.0 compiled successfully in 3593 ms
- Build Time : 2분 16초
- App Start Time : (대략 3.6초 ?)
- Vite v4
- App Start Time : 1초
- Build Time : 24초
빌드 타임에서 엄청나게 유의미한 결과가 나왔다... 👏
webpack 로 1번 빌드하는 동안 vite 로 빌드하면 무려 6번 이나 빌드할 수 있는 것이다...!
개인 프로젝트 단위에서는 아무리 많이 빌드를 해도 GithubAction 같은 CI/CD 도구의 빌드타임이 많이 쌓여서 과금되는 경우가 없을 테지만, 회사에서는 아슬아슬하거나 과금되는 곳이 많을 거다.
CRA 에서 에러만 안나면 vite 로 바꾸는데 30분도 안걸린다. 이걸로 돈 나갈 거 안나가게만 해도 엄청난 성과이며 이득이다.
마이그레이션 과정
vite 패키지 설치
yarn remove react-scripts @craco/craco craco-alias
yarn add -D @vitejs/plugin-react vite
- craco 를 사용 중이었다면 craco 관련 패키지 및 craco.config.js 파일 삭제 해야 한다.
스크립트 교체
"scripts" : {
"start" : "vite"
"build" : "vite build"
}
파일 위치 이동 및 내용 수정
- public/index.html → /index.html
- %Public_URL% 로 작성된 것을 실제 경로로 변경 필요
from
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link type="text/css" rel="stylesheet" href="%PUBLIC_URL%/reset.css" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.jpg" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
to
<link rel="icon" href="/favicon.ico" />
<link type="text/css" rel="stylesheet" href="/reset.css" />
<link rel="apple-touch-icon" href="/logo.jpg" />
<link rel="manifest" href="/manifest.json" />
- 집입점 추가
<body>
<div id="root"></div>
<script type=”module” src=”/src/index.tsx”></script>
</body>
vite.config.ts 파일 추가
import {defineConfig} from 'vite';
import react from "@vitejs/plugin-react";
import viteTsconfigPaths from 'vite-tsconfig-paths';
import svgrPlugin from 'vite-plugin-svgr';
export default defineConfig({
plugins: [react(), viteTsconfigPaths(), svgrPlugin(), ];
})
플러그인 설치 및 적용
종류가 많다. 원하는 것 설치해주면 된다.
yarn add -D vite-tsconfig-paths vite-plugin-svgr vite-plugin-eslint vite-plugin-env-compatible
- vite-plugin-svgr : SVG 그래픽을 리액트 컴포넌트처럼 사용
- vite-plugin-packgage-version : package.json 에서 패키지 버전을 환경 변수로 삽입
- vite-plugin-eslint : ESLint 관련 오류 알려줌
- vite-tsconfig-paths : tsconfig.json에 정의된 paths 매핑사용
- vite-plugin-env-compatible : 환경변수가 VITE 로 시작하지 않고 REACT_APP 으로 시작쓸 수 있게 해줌
참고로
@vitejs/plugin-react 안에 react-refresh 와 동일 역할하는 @vitejs/plugin-react-refresh 도 내장되어 있어서 또 설치 안해도 된다.
환경변수 이름 변경
- REACT_APP_ 접두사를 VITE_ 로 변경 해주어야 합니다.
- 그게 귀찮다면 vite-plugin-env-compatible 라이브러리 설치하면 REACT_APP 접두사 그대로 사용할 수 있습니다.
- 설치후 아래와 같이 설정파일에 추가해주면 됩니다.
- 그러나 환경변수 불러오는 방식은 아래와 같이 변경해주어야 합니다.
- process.env → import.meta.env
// vite.config.ts
import envCompatible from 'vite-plugin-env-compatible'
export default defineConfig({
envPrefix: "REACT_APP_",
plugins: [ // ...other plugins envCompatible(), ],
})
환경변수에 타입 추가 (안해도 됨. 선택사항. 이런 것도 가능하다는 것임)
- https://vitejs.dev/guide/env-and-mode.html
- env.d.ts 파일을 만들어서 환경 변수의 타입 지정이 가능합니다.
if (import.meta.env.DEV) {
// do something in development mode only
}
if (import.meta.env.PROD) {
// do something in production mode only
}
interface ImportMetaEnv {
readonly VITE_TOKEN: string;
readonly VITE_CLIENT_ID: number;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
서버 시작 시 브라우저 앱 자동으로 열기
// vite.config.ts
export default defineConfig({
...
server: {
open: true,
},
});
기본 포트 변경
// vite.config.ts
export default defineConfig({
...
server: {
port: 3000,
},
});
/src/react-app-env.d.ts → /src/vite-env.d.ts 파일명 변경 및 내용 수정
from
/// <reference types="react-scripts" />
to
/// <reference types="vite/client" />
tsconfig.json 변경
- types에 vite/client 를 추가
- TS에 제공하는 특별한 Vite 브라우저 기능에 대해 알려줍니다.
- "types": ["vite/client"],
- "isolatedModules": true 옵션 추가
- 기능적으로 Vite 에서 아직 지원하지 않는 최신 TS가 있기 때문
node_modules 삭제 후 재설치 (꼭 해야함!!!!)
rm -rf node_modules
yarn install
이슈
일부 라이브러리에서 특정 함수를 중괄호로 가져오는 게 안되는 경우가 있음.
from
import { sanitize } from 'dompurify'
export const htmlParser = (content: string) => {
return content ? Parser(quillDecodeIndent(sanitize(content, config))) : ''
}
to
import DOMPurify from 'dompurify'
export const htmlParser = (content: string) => {
return content ? Parser(quillDecodeIndent(DOMPurify.sanitize(content, config))): ''
}
컴포넌트 import 위치를 react-pdf/dist/esm/entry.vite 로 변경
import { pdfjs, Document, Page } from 'react-pdf/dist/esm/entry.vite'
이렇게만 하면 아래 링크들에 있는 에러가 발생
https://github.com/wojtekmaj/react-pdf/issues/1232
pdfjs 라이브러리의 버전이 맞지 않아서 발생하는 것으로 보임
node_modules 에서 찾아서 캡쳐한 모습
그래서 pdfjs.version 를 console로 찍어봤을때 나오는 버전을 설치하도록 강제해야 함
package.json 의 resolutions 필드에 pdfjs-dist 추가
"resolutions": {
"pdfjs-dist": "2.16.105"
},
https://github.com/ealush/emoji-picker-react/issues/202
export default defineConfig({
define: { global: 'window' },
}
require 구문 사용이 안됨. 플러그인 설치 필요
아니면 import 구문으로 변경해주면 된다.
브라우저 앱이 localhost 가 아니라 127.0.0.1 로 나타나는 문제
나의 경우, 백엔드 서버 쪽에서 CORS 설정이 localhost 라는 이름으로 되어있어서 꼭 해주어야 했다.
// vite.config.js
import { defineConfig } from 'vite'
import dns from 'dns'
dns.setDefaultResultOrder('verbatim')
export default defineConfig({
// omit
})
https://github.com/vitejs/vite/issues/9195
https://vitejs.dev/config/server-options.html#server-host
참고
'프론트엔드 개발 > React.js' 카테고리의 다른 글
자바스크립트 모듈 & 번들러 (CommonJS, AMD, ESModule, Webpack, Rollup, Parcel, esbuild, swc, vite, turbopack) (0) | 2023.01.28 |
---|---|
Vite 아직 사용하지 마세요!!! (1) | 2023.01.28 |
리액트에서 외부 링크 관리하기 (0) | 2023.01.15 |
리액트에서 마우스가 브라우저 창 밖에 있는지 감지하기 (0) | 2023.01.15 |
리액트 장치 유형 감지하기 (0) | 2023.01.15 |