[F-Lab 모각코 챌린지 60일차] Vite

Nami·2023년 7월 30일
0

66일 포스팅 챌린지

목록 보기
60/66

Vite

WHY?

브라우저에서 ESM(ES Modules)을 지원하기 전까지, JavaScript 모듈화를 네이티브 레벨에서 진행할 수 없었다. 그래서 소스 모듈을 브라우저에서 실행할 수 있는 파일로 크롤링, 처리 및 연결하는 Bundling 번들링이라는 해결 방법을 사용해야 했었다.

크롤링 Crawling

  • 웹사이트에서 데이터를 수집하는 과정을 말한다.
  • HTML, CSS, JavaScript 등의 내용을 분석하여 원하는 정보를 추출하는 작업

번들링 Bundling

  • 모듈화된 소스 코드를 브라우저에서 실행할 수 있는 파일로 한데 묶어주는 작업
  • 모듈 시스템이 없을 때 HTML 파일에 스크립트 파일을 불러와서 사용할 경우 전역 공간에 모든 변수가 노출될 수 있었고 여러 스크립트를 불러왔을 때 변수의 이름이 겹쳐 충돌이 발생하는 문제점이 생김.
<html>
  <script src="/src/foo.js"></script>
  <script src="/src/bar.js"></script>
  <script src="/src/baz.js"></script>
</html>
// foo.js, bar.js, baz.js 중 하나라도 변수 이름이 겹치는 선언이 전역에 있다면 충돌이 발생한다.

Module Bundling

Javascript 모듈화

이전에는 CommonJS, AMD(Asynchronous Module Definition), UMD(Universal Module Definition) 등의 모듈 시스템이 있었지만, 이들은 언어 자체에 내장되어 있지 않아서 브라우저에서 바로 사용할 수 없었다.

2008년에 구글에서 브라우저 외부에서도 JavaScript를 실행시킬 수 있는 V8엔진을 소개하면서 모듈화에 대한 필요성이 더욱 부각됐다. 브라우저 외부 환경에서 JS를 실행할 수 있게 되면서, 특히 Node.js를 통해 JavaScript로 서버를 개발하는 것이 큰 인기를 얻게 됐다. 더불어 모듈 표준화를 위한 움직임이 본격적으로 시작됐다.

Native ESM(ES Modules)

EcmaScript 6 (ES6)에서 도입된 기능. 브라우저와 Node.js에서 네이티브로 JavaScript 모듈 시스템을 지원한다.

  • import 및 export 키워드를 사용하여 네이티브로 간단하고 직관적인 모듈화 구현.
  • 모듈 표준화
  • 동기/비동기 로드를 지원, 편리한 순환 참조 관리, 쉬운 트리 쉐이킹
  • IE 같은 구형 브라우저에서는 제대로 동작하지 않는다는 문제점이 있었음
<!-- 모듈을 포함하는 HTML 파일 -->
<script type="module">
  // 모듈 로드
  import { greet } from './greeting.js';

  // 모듈의 함수 사용
  greet('John');
</script>
// greeting.js 파일
export function greet(name) {
  console.log(`Hello, ${name}!`);
}

기존 Bundler

모든 브라우저에서 모듈 시스템을 완전하게 지원하지 않았기 때문에 개발자들은 '번들링'이라는 우회적인 방법을 사용해야 했다. 따라서 브라우저와 무관하게 모듈 시스템을 지원하기 위해 Webpack, Rollup 그리고 Parcel 같은 번들링 도구, 번들러가 탄생했다. 이런 번들러 도구는 프런트엔드 개발자의 생산성을 크게 향상시켜줬다.

기존 번들러들은 엔트리 JavaScript 파일부터 시작해서 소스 코드와 node_modules 폴더 전체 코드 베이스를 묶고, 필드 프로세스를 통해 실행한 다음 번들된 코드를 브라우저에 제공한다.

콜드 스타트 방식(최초로 실행되어 이전에 캐싱한 데이터가 없는 경우를 의미)으로 개발 서버를 구동할 때, 번들러 기반의 도구의 경우 애플리케이션 내 모든 소스 코드에 대해 크롤링 및 빌드 작업을 마쳐야지만이 실제 페이지를 제공할 수 있다.

웹 애플리케이션이 커지면 커질수록 애플리케이션을 시작하는데 오래 걸리게 되었고, 또한 대부분의 번들러는 Node.js 기반으로 돌아가기 때문에 싱글 스레드로 인한 처리 한계를 가졌다.

차세대 모듈 번들러 등장

위에서 나타난 문제점을 해결하기 위해 snowpack, vite 같은 차세대 번들러들이 등장했다.

더욱 빠른 서버 구동

Vite는 애플리케이션의 모듈을 Dependencies와 Source code 두 가지 카테고리로 나누어 개발 서버의 시작 시간을 개선했다.

Dependencies 의존성

  • 개발 시 그 내용이 바뀌지 않을 일반적인(Plain) JavaScript 소스 코드
  • Vite는 사전 번들링을 네이티브 영역에서 돌려 성능을 높였다.
  • Go 기반의 Esbuild를 사용, 기존 번들러 대비 10-100배 빠른 속도를 가진다.

더욱 빠른 소스 코드 갱신

Source code 소스 코드

  • JSX, CSS 또는 Vue/Svelte 컴포넌트와 같이 컴파일링이 필요하고, 수정 또한 매우 잦은 Non-plain JavaScript 소스 코드
  • Native ESM을 이용
  • 소스코드는 Native ESM을 사용하고, NPM 패키지들은 Esbuild로 사전 번들링을 수행한다.


위에 초록색 상자로 표시된 route를 어떤 페이지라고 해보자. 이 페이지를 요청하면 브라우저는 route에 해당하는 브랜치의 정보만 필요하다. 따라서 브라우저는 ESM을 통해 이 페이지의 모듈에 대한 소스 코드만을 번들러에게 요청하고, 번들러는 해당하는 소스 코드만을 전달한다.

어떤 모듈이 수정됐을 때도 번들러는 수정된 모듈과 관련된 부분만 교체하고, 브라우저에서 해당 모듈을 요청하면 교체된 모듈을 전달하면 되기 때문에 전체를 다시 번들할 필요가 없다. 전 과정에서 완벽하게 ESM을 이용하기에, 앱 사이즈가 커져도 HMR을 포함한 갱신 시간에는 영향을 끼치지 않는다.

여기서 더 나아가 vite의 경우 HTTP 헤더를 이용해 요청한 소스 코드가 304 Not Modified, 디펜던시는 Cache-Control: max-age=31536000, immutable를 이용해 캐시되도록 함으로써 요청을 줄여 성능을 더 높였다.

Vitest를 사용하기 위해서 Vite를 자연스레 설치하게 되었는데 (Webpack 사용시에도 물론 쓸 수 있음.) 나는 번들러를 써본 적이 없어서 Vite도 써보고 싶었다. 들어보기만한 것들에 대해 더욱 잘 알게되었다.


2개의 댓글

comment-user-thumbnail
2023년 8월 4일

요즘 기술선택때문에 vite랑 webpack..에대해서 저울질하고 있는데 잘 주어담고 갑니다. 👍

1개의 답글