create-react-app 기본 번들러에서 Vite로 마이그레이션하기

CRA(create-react-app)을 통해 부트스트래핑된 React 어플리케이션의 경우 번들링을 위해 기본 제공되는 react-scripts을 사용합니다. 이 react-scripts 라이브러리는 쉽고 간편하지만, 라이브러리 내부에서 사용되는 Webpack 번들러가 느리고 무거운 편입니다.

저희 팀에서 담당하고 있는 프로젝트가 Webpack에 크게 의존성을 가지고 있지 않았기 때문에 굳이 Webpack(즉, react-scripts)을 고집해야 할 이유가 없어보였습니다. 따라서, 충분히 간편하면서도 훨씬 빠른 번들링 퍼포먼스를 보여줄 것이라고 기대되는 Vite로 번들러 수정 작업을 진행했습니다.

퍼포먼스 비교

본문으로 넘어가기 전에, 실제로 Vite로 번들러를 변경한 것이 실제 프로덕션에서 어느 정도의 퍼포먼스 향상을 가져왔는지 간단히 비교하고자 합니다.

Vercel deployments에서 기존 react-scripts를 사용한 빌드와 Vite를 사용한 빌드에서 배포에 걸린 시간을 5개씩 샘플링하여 비교하였습니다. 기존의 경우 빨라도 1분 후반대, 대체로 3분 가량의 배포 시간이 걸리는 반면 Vite를 사용한 뒤에는 늦어도 1분 30초 내외에서 배포가 끝나는 결과를 확인할 수 있습니다.

또한 함께 일하는 팀원분께서도 "Vite seems to be significantly faster" 라고 언급하는 등 정량적인 배포 시간뿐만 아니라 동료의 업무 퍼포먼스에도 도움이 됨을 확인할 수 있었습니다.

Vite로 마이그레이션

시작하기 앞서, 제가 작업하면서 참조한 블로그 글을 링크합니다:

앞서 언급했듯이, 마이그레이션하려는 프로젝트가 Webpack에 큰 의존성이 없는 관계로 어렵지 않게 마이그레이션을 할 수 있었습니다. 위 블로그 글에 추가적으로 제가 작업한 내용은 다음과 같습니다.

1. process.env 호환성 추가

Vite에서는 import.meta.env를 통해서 환경 변수에 접근할 수 있습니다만, 저희 프로젝트에서 사용하는 Cypress 테스트 코드에서는 import.meta.env를 통한 환경 변수 접근이 잘 작동하지 않는 이슈가 있었습니다. 따라서 process.env를 통해서도 환경 변수를 참조할 수 있도록 호환성을 추가하는 작업이 필요했습니다. 이 작업은 이미 GitHub 커뮤니티에서도 논의된 적이 있었던 이슈였던 것 같습니다, 해당 커뮤니티에서 제시된 솔루션 코드를 적용하는 것으로 이슈를 해결할 수 있었습니다.

2. EJS 템플릿 문법 지원

CRA에서는 기본적으로 EJS 템플릿 문법을 지원하는 반면, Vite에서는 EJS 플러그인을 추가해주어야 템플릿 문법을 사용할 수 있습니다. 이를 위해 vite-plugin-ejs 패키지를 설치하고, 다음과 같이 플러그인을 추가해주었습니다.

import { ViteEjsPlugin } from 'vite-plugin-ejs';

export default defineConfig() => {
  ...
  
  return {
    plugins: [
      ViteEjsPlugin({
        // 여기에는 사용하고자 하는 변수를 선언해주면 됩니다. 예컨대,
        exampleVar: import.meta.env?.VITE_EXAMPLE_VAR || null,
      }),
    ],
  };
}

3. 그 외 자잘한 플러그인 추가

Vite에서 기본적으로 제공하지 않는 여러가지 기능을 사용하기 위해 다양한 플러그인을 추가했습니다:

  • vite-plugin-svgr: SVG 그래픽을 리액트 컴포넌트처럼 사용하기 위한 플러그인
  • vite-plugin-package-version: package.json 에서 패키지 버전을 환경 변수로 삽입해주는 플러그인
  • vite-plugin-eslint: ESLint와 관련된 오류를 알려주는 플러그인
  • vite-tsconfig-paths: tsconfig.json에 정의된 paths 매핑을 사용하기 위한 플러그인

이 플러그인을 찾아 설치하는 과정을 진행하면서, 생각보다 CRA가 커버해주는 영역이 넓다는 점을 느낄 수 있었습니다.

그래서 지금은

Vite는 정말 놀라운 퍼포먼스를 보여주며 저희 프로젝트의 번들링을 담당하고 있습니다.

개인적으로 Vite로 번들러를 수정한 뒤에 만족스러웠던 기능은 ".env 파일의 변화를 자동으로 감지하여 서버 재시작을 진행한다"는 점입니다. CRA(Webpack)를 사용하던 시절에는 환경 변수를 변경하고 난 뒤에 직접 서버를 껐다가 다시 시작해야 했는데, 이 것이 상당히 불편했습니다. 또한 처음에 프리뷰를 생성하는 데 상당히 오랜 시간이 걸리기 때문에 개발의 흐름이 끊어지는 느낌을 받곤 했습니다.

하지만 Vite는 .env 파일이 변경되었을 경우 이를 자동으로 감지하여 서버를 자동으로 재시작해줍니다.
또한 처음 시작하는 데 오랜 시간이 걸리지 않기 때문에 전혀 불편함을 느끼지 않았습니다.


아직 CRA에 내장된 Webpack 번들러를 사용하고 계신다면, Vite를 사용해보시는 것이 좋은 선택이 될 것이라고 생각합니다. 🙌

여담

Vite를 처음 접했을 때, 별 생각 없이 Vite를 v바이트 라고 읽으면서 팀원 분들에게 공유했었습니다. 그런데 프랑스인 팀원 분이 "이 단어는 프랑스어라서 v빗이라고 읽어요, 빠르다는 뜻이에요" 라고 정정해주셨습니다. 이후에 공식 문서를 읽어보니 진짜로 veet 처럼 읽으라고 설명이 적혀있더군요 😮