CRA를 Vite로 마이그레이션 하기

제리추·2023년 8월 31일
6
post-thumbnail

번들러 연대기

Vite가 기존 다른 번들러와 비교해 어떻게 빠를 수 있는 것인지 이해하기 위해 먼저 번들러의 역사를 알아보자.

자바스크립트는 간단한 동작을 하기 위한 언어로 만들어졌기 때문에 모듈이 존재하지 않는다. 모듈이 존재하지 않다는 것은 큰 프로그램을 만드는 것이 어렵다는 것이다. 그리고 Node가 생기면서 서버에서 js 사용이 가능했다. require, module.export를 사용하는 CommonJS 모듈 방식이 생겼다. 이후 npm이 등장했고 module을 개발자 간의 공유가 가능하게 됐다. 하지만 브라우저에서 module의 사용은 여러 파일을 동시에 호출하게 되면 로딩 시간이 길다는 문제가 있었다.

이 문제를 해결하기 위해 번들러가 등장하였다. 여러 파일을 비동기적으로 로딩하는 것이 문제이기 때문에 파일을 하나로 합쳐 번들로 만들어 브라우저에 전달하는 번들러가 등장한다. 여기서 번들러의 문제점이 생기는데 번들링 과정이 추가되면서 코드를 수정할 때마다 매번 빌드를 다시 했고 이 속도가 빠르지 않기 때문에 코드를 수정하면 빠르게 변경이 되지 않았다.

esbuild

이 문제를 해결하기 위해 esbuild가 등장했다. esbuild는 Webpack, Parcel과 같은 기존의 번들러 대비 10~100배 빠른 속도를 제공한다. 이것을 Vite가 사전 번들링 기능에 도입하였다.

vercel

왜 Vite는 Webpack과 다르게 빌드 속도가 빠를까?

브라우저가 발전하면서 ESM이 등장하였다. ESM이란 ECMAScript Module로 ES6부터 추가된 자바스크립트 모듈이다. <script type="module" src="etc.mjs"></script> 방식으로 html 파일에서 자바스크립트 파일을 모듈로 사용할 수 있다. ESM이 전에는 번들러 없이 사용이 불가능했지만 브라우저 자체에서 ESM이 추가되어 이제는 번들러 없이 사용 가능하게 되었다.

Vite는 개발할 때 서버 시간을 단축하기 위해 Dependencies code와 Source code를 분리한다.

Depencies code: 개발 시 내용이 바뀌지 않는 소스코드이다. Vite는 사전 번들링을 ESbuild를 사용했다. Go로 작성된 Esbuild는 Webpack, Parcel과 같은 기존 번들러와 비교해 10~100배 빠르다.

Source code: JSX, CSS, Vue/Svelte 컴포넌트와 같이 컴파일링 필요하고 수정이 잦은 소스코드이다. Vite는 브라우저의 ESM을 이용해 소스코드를 제공한다. 즉 브라우저가 번들러의 작업의 일부를 가져가서 하게 된다.

일부 번들러에서는 실제 갱신에 영향을 받는 파일을 새롭게 번들링 했지만, 결국 처음에 모든 파일에 대한 번들링을 수행해야 했다. '모든 파일'을 번들링 하고, 이것을 다시 웹 페이지로 불러오는 것은 비효율적이기 때문에 이슈를 우회하고자 HMR의 대한이 나왔지만 명확하지 않았다.

Vite는 HMR을 지원하지만 ESM을 이용하기 때문에 어떤 모듈이 수정되면 수정된 모듈과 관련 부분만 교체한다. 즉 코드가 변경되면 Vite는 수정된 모듈과 관련된 부분만 교체하고, 브라우저에 전달한다.

CRA에서 Vite로 마이그레이션 장단점과 이유

장점

  • 빠른 빌드 속도
  • 요청 횟수를 최소화하는 빠른 페이지 로딩
  • 최신 자바스크립트 문법 지원
  • SSR 지원

단점

  • React 라이브러리 및 프러그인 호환성을 맞추기 위한 추가적인 작업
  • 미지의 에러와 초기 설정 귀찮음
  • Vite에 대한 문서 부족 / React Vite를 사용하는 개발자들의 문서 부족

Vite의 번개 같은 빠름 반영과 풍부한 개발자 경험을 위해 마이그레이션을 진행했다.

CRA에서 Vite로 마이그레이션 과정

  1. npm remove react-scripts
  2. npm i -D @vitejs/plugin-react vite
  3. package.json scripts 교체
"scripts" : {
  "start" : "vite"
  "build" : "vite build"
}
  1. vite.config.js 파일 추가 및 설치
plugins: [react(), jsconfigPaths()]

jsconfigPaths: jsconfig.json에 정의된 paths를 매핑함.

  1. index.html 파일 위치 이동 public/index.html -> /index.html
  2. index.html Public_URL 경로 변경
    전: <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    후: <link rel="shortcut icon" href="/public/favicon.ico" />
  3. ESM 활용을 위해 태그를 통해 진입 파일 태그 추가
    <script type="module" src="/src/index.jsx"></script>
  4. 로컬 포트 변경
// vite.config.js
server: {
        port: 3000,
},
  1. 환경변수 이름 변경 -> 환경변수 앞에 VITE_ 가 붙어야함. ex) VITE_REACT_APP
  2. 노드 모듈 삭제 후 재설치

CRA vs Vite 빌드 타임 결과

  • 빌드 타임 CRA 6.61s vs Vite 1.02s
  • FCP는 측정하지 못했다.

참고

profile
안녕하세요. 소프트웨어 엔지니어 제리입니다 🐹

0개의 댓글