본문 바로가기
Develop

[React] CRA vs Vite? 왜죠?

by stuckyi 2024. 3. 15.
 

[React] React 프로젝트를 어떻게 생성해야 할까?

React 프로젝트를 생성할 때, CRA(create-react-app)를 사용하면 아주 편하고 빠르게 시작을 할 수 있었다. 그러나 22년도 이후 CRA 업데이트가 없고, React 공식 문서(react.dev)에서도 더 이상 CRA에 대한 설명

ziyun.tistory.com

이전에 React 프로젝트를 생성하기 전에 React팀의 CRA에 대한 입장을 알아볼 수 있었다. 

'그렇다면 왜 CRA 대신 Vite인가?'를 다시 정리해보고 싶어졌다.

 

프로젝트 생성

CRA 지원 중단이지만, 없어진 건 아니다.

npx create-react-app my-app

 

CRA를 사용하면 뭐가 생성되는가.. 궁금하다면 아래 터미널을 자세히 살펴보면 친절하게 설명을 하면서 설치가 된다.

React 개발 환경에 필요한 packages가 설치되는 중이며... 몇 분 걸릴 거다

 

설치가 완료되면 폴더 구조와, package.json 파일을 확인할 수 있다.

 

그럼 Vite는 프로젝트를 어떻게 생성할까?

npm create vite@latest

 

바로 프로젝트 명과 템플릿을 명령어로 설치도 가능하다. 다른 템플릿에 대한 설치 방법은 Vite 공식문서를 참고하면 된다.

그리고 npm install을 해주면 된다.

npm create vite@latest my-vue-app -- --template vue

 

 

Vite로 생성한 프로젝트의 package.json은 아래와 같다.

 

여기까지 정리를 해보자면,

CRA는 지금까지 리액트 프로젝트를 가장 빨리 시작할 수 있었던 보일러 플레이트였고 연결된 번들 도구는 Webpack이다.

그럼 Vite는? 

 

공식문서를 보면 아래와 같이 소개를 하고 있다. Vite는 빌드 도구이다. 

Vite (French word for "quick", pronounced /vit/, like "veet") is a build tool that aims to provide a faster and leaner development experience for modern web projects.

 

CRA와 Vite의 다른 점은 번들 방식이고,
프로젝트가 커지면서 CRA의 문제는 서버 구동이 '느리다'이고 권장하고 있는 Vite는 서버 구동이 '빠르다'는 이유로 정리가 된다.

CRA는 온전히 클라이언트 사이드 앱을 생성하는 것이었다. CSR의 구조를 생각해 보면 빈 HTML과 React 앱 번들과 함께 <script> 태그가 포함되어 있는데 앱이 점점 커지면서 불편한 점이 생긴 것이다. 빈 HTML이 로드되면 브라우저는 React 코드와 전체 앱 번들이 다운로드될 때까지 기다리게 되고 유저는 흰 화면만 보면서 기다려야 하는 것이다. 

 

다만, 지금까지는 '뭐 얼마나 빠른 거지?' 직접 체감하지 못해서 사이드 프로젝트를 진행하면서 시간을 비교해 볼 예정이다.

그보다 먼저, '그런데 번들 방식이 어떻게 다른 거지?'에 대한 부분을 아직 이해하지 못했다.

 

프로젝트 빌드 및 실행

CRA 프로젝트의 package.json 파일을 다시 살펴보자.

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

Vite와 달리 dependencies 에 react-scripts가 설치되어있는데, 이 아이는 뭐 하는 package인가..? 

This package includes scripts and configuration used by Create React App

 

 

react-scripts의 start.js를 조금 더 해부해 보자면,

프로젝트 경로에서 /src/index.js (즉 webpack의 entry)로 파일을 번들링 하고

webpack-dev-server와 webpack-dev-utils을 이용해서 openBrowser이 실행된다. 

 

const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const clearConsole = require('react-dev-utils/clearConsole');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const {
  choosePort,
  createCompiler,
  prepareProxy,
  prepareUrls,
} = require('react-dev-utils/WebpackDevServerUtils');
const openBrowser = require('react-dev-utils/openBrowser');

...

const devServer = new WebpackDevServer(serverConfig, compiler);
// Launch WebpackDevServer.
devServer.startCallback(() => {
  if (isInteractive) {
    clearConsole();
  }

  if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) {
    console.log(
      chalk.yellow(
        `Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.`
      )
    );
  }

  console.log(chalk.cyan('Starting the development server...\n'));
  openBrowser(urls.localUrlForBrowser);
});

 

Starting the development server.. 로그가 찍히면서 브라우저에 나의 프로젝트가 띄어진다.

 

 

react-scripts의 start.js 파일은 주로 개발 서버를 실행하고 파일 변경 사항을 감지하여 자동으로 다시 빌드하고 리로드 하는 등의 작업을 하는 것으로 파악했다. 더 깊게 해부하지 않았지만 CRA에서는 react-scripts가 설정과 스크립트 관리를 하는 역할이고, 실제 번들링은 webpack이 수행하게 되는 것이다.

webpack의 번들 방식은 아래의 그림과 같이 여러 개의 js파일을 하나의 파일로 bundle 하는 것이다.

다만, 여기서 문제는 다른 파일을 저장하게 된다면 webpack에 의해 다시 빌드가 되고 코드가 적용되길 기다려야 했다. 프로젝트 규모가 작다면 문제가 되지 않았겠지만 서비스가 커질수록 불편함이 생기게 된 것이다.

 

 

 

이 문제를 Vite는 아래와 같은 방법으로 개선했음을 공식 문서에서 설명하고 있다.

Vite의 사전 번들링 기능은 Esbuild를 사용하고 있습니다. Go로 작성된 Esbuild는 Webpack, Parcel과 같은 기존의 번들러 대비 10-100배 빠른 속도를 제공합니다.
..

Vite는 Native ESM을 이용해 소스 코드를 제공합니다. 이것은 본질적으로 브라우저가 번들러의 작업의 일부를 차지할 수 있도록 합니다. vite는 브라우저가 요청하는 대로 소스 코드를 변환하고 제공하기만 하면 됩니다. 조건부 동적 import 이후의 코드는 현재 화면에서 실제로 사용되는 경우에만 처리됩니다.



즉, 이전 방법과 달리 변경된 모듈만 바로 반영할  있으므로 프로젝트 크기에 상관없이 빠르게 개발할  있다는 장점이 있는 것이다.

 

 

정리

이론으로는 어느 정도(?) 이해가 된 거 같지만, 온전히 다 내 것으로 소화하지는 못해서 계속 개발하면서 위 글도 명확하게 다져 나가야 할 거 같다. 결론은 CRA와 Vite 모두 리액트 개발을 시작하는 스타터가 될 수 있고 CSR 구조를 익히며 서비스를 만들어 갈 수 있다는 점이다.

다만 webpack을 사용할 시 빌드 속도 측면에서 한계가 있고, React팀에서는 CRA는 '좋은 사용자 경험을 위해 웹의 강력한 측면을 활용하는 데 도움이 되는 충분한 구조를 제공하지 않았습니다.'라고 말한다.

Vite는 프레임워크 종속이 없으며 CSR에 친화적이면서 SSR도 선택적으로 사용 가능하고 서버 구동이 빠르기 때문에
개발 환경의 확장성을 고려해 봤을 때 많은 개발자들이 Vite가 CRA를 대체할 리액트 스타터로 권장하는 것 같다.

 

추가로 빌드툴 Star 순위를 찾아 보았는데, 

22년도까지는 Vite가 1등이였지만 23년도는 Bun에게 자리를 뺏겼다..Bun은 또 뭐지(뒷북이지만, 지금이라도 알아봐야겠다..)

24년 3월 기준 Vite는 63.9k Bun은 68.9k

22년도 Build Tools 순위
23년도 Build Tools 순위

 

참고

Vite 사용해야 하는 이유

(번역) 2024년에 리액트 프로젝트를 시작하는 방법

Is Vite Better than Webpack?