브라우저에서 ES 모듈을 사용할 수 있게 되기 전에는 개발자가 모듈화된 방식으로 JavaScript를 작성할 수 있는 기본 메카니즘이 없었습니다. 그렇기 때문에 소스 모듈을 크롤링하고 처리하여 브라우저에서 실행할 수 있는 파일로 연결하는 도구를 사용하는 ‘번들링’이라는 개념에 익숙해져 있었습니다.
시간이 지남에 따라 Webpack, Rollup, Parcel과 같은 도구가 등장하여 프론트엔드 개발자의 개발 환경을 크게 개선했습니다.
하지만 점점 더 야심찬 애플리케이션을 개발함에 따라 처리해야 하는 JavaScript의 양도 급격히 증가하고 있습니다. 대규모 프로젝트에는 수천 개의 모듈이 포함되는 경우도 드물지 않습니다. JavaScript 기반 도구의 성능 병목현상이 발생하기 시작했습니다. 개발 서버를 가동하는 데 비합리적으로 긴 대기 시간(때로는 몇 분까지!)이 소요될 수 있으며, 핫모듈 Replacement(HMR)를 사용하더라도 파일 편집 내용이 브라우저에 반영되는 데 몇 초가 걸릴 수 있습니다. 느린 피드백 루프는 개발자의 생산성과 만족도에 큰 영향을 미칠 수 있습니다.
Vite는 브라우저에서 네이티브 ES 모듈을 사용할 수 있게 되고 네이티브 언어로 컴파일되는 JavaScript 도구가 등장하는 등 에코시스템의 새로운 발전을 활용하여 이러한 문제를 해결하는 것을 목표로 합니다.
개발 서버를 콜드스타트할 때 번들러 기반 빌드 설정은 전체 애플리케이션을 열심히 크롤링하고 빌드한 후에야 서비스를 제공할 수 있습니다.
Vite는 먼저 애플리케이션의 모듈을 종속성과 소스 코드의 두 가지 범주로 나누어 개발 서버 시작 시간을 개선합니다.
Dependencies 는 대부분 개발 중에 자주 변경되지 않는 일반 JavaScript입니다. 일부 대규모 종속성(예: 수백 개의 모듈이 포함된 컴포넌트 라이브러리)은 처리 비용이 상당히 많이 들기도 합니다. 종속성은 다양한 모듈 형식(예: ESM 또는 CommonJS)으로 제공될 수도 있습니다.
Vite는 esbuild를 사용하여 종속성을 사전 번들링합니다. esbuild는 Go로 작성되며 JavaScript 기반 번들러보다 10~100배 빠르게 종속성을 사전 번들링합니다.
Source code 에는 변환이 필요한 일반 JavaScript가 아닌 것(예: JSX, CSS 또는 Vue/Svelte 컴포넌트)이 포함되어 있는 경우가 많으며 자주 편집하게 됩니다. 또한 모든 소스 코드를 동시에 로드할 필요는 없습니다.(예: route 기반 코드 스플릿 사용)
Vite는 네이티브 ESM을 통해 소스 코드를 제공합니다. 이는 본질적으로 브라우저가 번들러의 작업 일부를 대신하도록 하는 것입니다. Vite는 브라우저의 요청에 따라 필요에 따라 소스 코드를 변환하여 제공하기만 하면 됩니다. 조건부 동적 import 뒤에 있는 코드는 현재 화면에서 실제로 사용되는 경우에만 처리됩니다.
번들러 기반 빌드 설정에서 파일을 편집하면 앱의 크기에 따라 업데이트 속도가 선형적으로 저하된다는 명백한 이유로 전체 번들을 다시 빌드하는 것은 비효율적입니다.
일부 번들러에서는 개발 서버가 메모리에서 번들을 실행하므로 파일이 변경될 때 모듈 그래프의 일부만 무효화하면 되지만 여전히 전체 번들을 재구성하고 웹 페이지를 리로드해야 합니다. 번들을 재구성하는 데는 많은 비용이 들 수 있으며 페이지를 리로드하면 애플리케이션의 현재 상태가 사라집니다. 따라서 일부 번들러는 페이지의 나머지 부분에 영향을 주지 않고 모듈을 ‘hot replace’할 수 있는 Hot Module Replacement(HMR)를 지원합니다. 이렇게 하면 DX가 크게 개선되지만 실제로는 애플리케이션의 크기가 커지면 HMR 업데이트 속도도 크게 저하되는 것으로 나타났습니다.