ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] React-Vite
    프로젝트/Share Your Trip 2024. 1. 1. 20:07

    Vite가 왜 궁금했을까❓

    - SSAFY에서 Vue.js 프레임워크 강의를 수강할 때, 강사님이 Vite를 빌드 도구를 사용하는 것을 보고 처음 접하게 되었다.
    - 강사님께서는 단순히 Vite가 빠르다는 것만을 강조하고 Vue에 대해 학습 할 내용이 많아 추가 설명을 하지 않고 넘어갔다.
    - 빨리 작동할 수 있는 원리가 궁금하여 Vite에 대해서 학습을 진행해보려고 한다.

     

     

    Vite란❓

    • 프랑스어로 “빠르다”라는 사전적 의미를 가지며, 빠르고 간결한 웹 프로젝트 개발 경험에 초점을 맞춰 탄생한 빌드 도구이다.
    • Vite는 React, Vue 등 다양한 템플릿들의 빌드를 지원하고 있었으며 CRA, Vue-Cli 등을 대체할 수 있다.
    • 개발자가 소스 코드를 수정하게 되면 Vite는 수정된 모듈과 관련된 부분만 교체하여 브라우저에 전달한다.
    • Native ESM 을 이용하기 때문에 프로젝트 크기가 크더라도 HMR 시간에 영향을 주지 않는다.
    • 프론트엔드 코드를 수정할 때, Dev Server에서 HMR이 발생하고 브라우저에서 변경된 내용을 확인하게 된다. 즉, Dev Server 구동보다도 HMR 속도가 더 중요하다고 볼 수 있다.
    Vite는 CRA, Vue-cli 등을 사용할 때 보다 개발 시 속도가 더 빠르고, 메모리를 적게 사용한다는 특징이 존재한다.

     

    기존 번들러들의 문제점 ⚠️

    • Webpack, Rollup, Parcel 같은 번들러들은 개발자가 작성한 소스코드와 dependency들을 번들로 묶고 빌드 프로세스를 통해 번들된 코드를 브라우저에 제공한다.
    • 수정할 때마다 위 과정을 매번 반복해서 빌드해야한다는 문제점이 존재

     

    Vite의 핵심 기능 ⚙️

    • Dev Server - 개발 환경에서 HMR과 같은 기능을 제공하는 개발용 서버 기능
      • Dev Server에서 Native ESM을 사용하여 소스를 제공
      • 기존 번들러들의 경우 모든 소스코드를 번들링하여 서비스를 제공했다면, Vite에서는 ESM 기반 방식을 사용하여 번들링 과정이 필요없다.
      • ESM이 나오기전에는 Javascript 레벨에서 지원하는 모듈 시스템이 없었기 때문에 번들링이 필요했던 것이고 ESM이 등장하면서 Javascript 레벨에서 모듈 시스템을 지원하게 되고 브라우저에서도 호환되어 번들링 과정이 필요가 없어졌다.
    • Build - Production 배포를 위한 소스코드 번들링 기능
    • Vite는 Dependencies를 esbuild를 통해 사전 번들링을 진행
    • esbuild를 통해 사전 번들링을 하고 Native ESM 기반의 Dev Server로 인해 서버 구동 속도와 HMR(Hot Module Replacement) 속도가 빠르다.

     

    Vite의 HMR 과정 🎞️

    • Dev Server와 브라우저 사이에 웹 소켓을 연결
    • 파일이 수정되었을 때, Dev Server가 브라우저에게 메시지를 전송하고 이후 브라우저는 모듈을 불러와 react-refresh에게 넘김

    1. Vite에 plugin으로 @vitejs/plugin-react를 등록

    2. npm run dev를 통해 vite Dev Server를 실행하면, Dev Server는 웹 소켓을 받을 준비를 한다.

    // Vite Dev Server Code
    const ws = createWebSocketServer(httpServer, config, httpsOptions)

     

    3. 브라우저에 접속해서 개발자 도구를 열어보면 첫 번째 JS 파일로 @Vite/client를 불러옴

    @vite/client 확인 과정

     

    4. @vite/Client가 JS를 수행하여 개발 서버와 웹 소켓을 연결

    // Browser
    function setupWebSocket(
      protocol: string,
      hostAndPath: string,
      onCloseWithoutOpen?: () => void,
    ) {
      const socket = new WebSocket(`${protocol}://${hostAndPath}`, 'vite-hmr')
    	...

     

    5. Dev Server로부터 메세지를 수신하여 연결을 확인

    연결 확인 과정

     

    6. App.tsx 파일을 수정하게되면 chokidar이 파일 수정을 감지한 뒤, 웹 소켓을 통해 update 타입의 메세지를 발송

    컴포넌트를 수정할 경우, @vitejs/plugin-react에 의해 HMR 대상이라고 판단되어 소켓을 통해 update 타입이 전송되고 그 외에는 full-reload를 전송
    // Vite Watch Code
    const watcher = chokidar.watch(
        // config file dependencies and env file might be outside of root
        [root, ...config.configFileDependencies, path.join(config.envDir, '.env*')],
        resolvedWatchOptions,
      ) as FSWatcher
    
    ...
    watcher.on('change', async (file) => {
        file = normalizePath(file)
        // invalidate module graph cache on file change
        moduleGraph.onFileChange(file)
    
        await onHMRUpdate(file, false)
      })

     

    7. @vite/client가 웹 소켓을 받아서 App.tsx 모듈을 다시 불러옴

     

    8. 불러온 모듈은 @vitejs/plugin-react가 react-refresh에게 넘겨서 컴포넌트 HMR을 진행


    참고 자료 링크 🧷

    https://kg-dlife.tistory.com/210

    https://analogcode.tistory.com/39

    https://velog.io/@woohm402/vite-react-hmr

Designed by Tistory.