번들러 등장 전
초기 웹은 HTML, JS 파일의 크기가 작았고, 서비스의 유지보수 또한 크게 어렵지 않았다고합니다.
그러나, 점점 기술이 발전 → 파일 하나당 코드의 양 증가, 페이지 증가 등등의 이슈로 크고 작은 문제들이 발생합니다.
이때 발생한 문제점은 충돌 + 속도 이슈
1) 중복 이름으로 인한 충돌 , 오류
2) 파일 전송 속도 문제
웹 애플리케이션이 커진다면, 웹 애플리케이션을 위한 파일을 제공하여 그리기까지 오래걸림
유지보수 측면에서 각각 기능별로 쪼개서 개발하는 것이 유리한데, 파일이 많아지거나 파일이 커지면 속도 이슈 또한 커짐. 그렇다고 하나로 개발은 사실상 불가능함
→ 가독성, 유지보수를 위해 파일 분리 시 네트워크 병목현상 발생, 응답 시간을 위해 파일 수를 줄이면 가독성, 유지보수가 힘들어짐
이런 문제를 해결해 주는 번들러가 탄생
번들러가 하는일은 여러 개의 파일을 하나의 자바 스크립트 파일로 묶어줌
대표적으로 webpack
parcel
등이 존재했다.
webpack이 대세를 이루며 번들링이 진행됐다.
webpack
장점
webpack
단점
공식문서를 들여다 봐보자
문제점이 있었다!
브라우저의 ES Module지원 전까지 Javascript 모듈화를 네이티브 레벨에서 진행할 수 없었다.
그래서 소스 모듈을 브라우저에서 실행할 수 있는 파일로 크롤링 + 처리 및 연결 하기 위해 번들링이란 해결 방법을 사용했다.
Webpack, Rollup 그리고 Parcel과 같은 도구로 번들링을 진행했다.
그러나, 애플리케이션이 점점 발전하고, 처리할 모듈의 개수도 증가함
→ js 기반의 도구의 성능 병목 현상 발생
→ 개발서버 실행시 느려지거나, hmr시에 수초 이상 걸림
Vite는 이러한 것에 초점을 맞춰, 브라우저에서 지원하는 ES Module 및 네이티브 언어로 작성된 js 도구 등을 활용해 문제해결
콜드 스타트 시 개발 서버 구동시에, 번들링 기반의 도구는 애플리케이션 내 모든 소스 코드에 대해 크롤링 및 빌드를 마쳐야 실제 페이지 제공이 가능함
vite는 애플리케이션의 모듈을 dependencies
와 source code
두 가지 카테고리로 나누어 개발 서버의 시작 시간을 개선함
dependencies
: 개발 시 내용이 바뀌지 않을 일반적인 js 소스 코드 기존 번들러: 컴포넌트 라이브러리 같이 몇백 개의 js 모듈을 갖고있는 경우 번들링 과정 비효율 적이고 많은 시간이 필요함 vite의 사전 번들링 기능은 Esbuild를 사용함 Go로 작성된 Esbuild는 Webpack, parcel과 같은 기존 번들러 대비 10 ~ 100배 빠름Source code
: vue / svelte, jsx , css 등 컴파일링이 필요하고, 수정 또한 매우 잦은 non-plain js 소스 코드 vite 는 native esm을 이용해 소스코드를 제공 → 본질적으로 브라우저가 번들러의 작업의 일부를 차지할 수 있음. vite는 브라우저가 요청하는 대로 소스 코드를 변환하고 제공함. 조건부 동적 import 이후 코드는 현재 화면에서 실제로 사용되는 경우에만 처리기존의 번들러 기반으로 개발을 진행: 소스 코드 업데이트 → 번들링 과정을 다시 실행해야함
즉, 서비스가 커지면 소스 코드 갱신 시간이 선형적으로 증가함
일부 번들러는 메모리에서 작업을 수행해서 실제로 갱신에 영향을 받는 파일들만을 새롭게 번들링하도록 함 → 결국, 처음에너는 모든 파일에 대한 번들링을 수행해야함
“모든 파일 번들링” & 이것을 다시 웹 페이지에서 로드하는 것은 비효율적 → 개선을 위해 HMR 이라는 대안이 나옴 → 명확한 해결책은 아님
vite는 HMR을 지원함 → 이는 번들러가 아닌 ESM을 이용하는 것
모듈 수정 → (vite는 그저 수정된 모듈과 관련된 부분만 교체) → 브라우저에서 해당 모듈을 요청 → 교체된 모듈 전달
이 전체 과정에서 ESM이용
즉, 앱 사이즈가 증가해도 HMR을 포함한 갱신 시간에는 영향이 없다.
ESM 이 대부분 지원되지만, 프로덕션에서 번들 되지 않은 ESM을 가져오는 것은 중첩된 import로 인한 추가 네트워크 통신으로 여전히 비효율
프로덕션 환경에서 최적의 로딩 성능을 얻으려면 트리 셰이킹, 지연 로딩 및 청크 분할을 이용하여 번들링 하는 것이 더 좋음
개발 서버와 프로덕션 빌드 간에 최적의 출력과 동작 일관성을 보장 못하고있음
→ 빌드 최적화를 하는 이유
Vite의 현재 플러그인 API는 esbuild를 번들러로 사용하는 것과 호환되지 않음
esbuild가 더 빠르지만, vite가 rollup의 유연한 플러그인 api 및 인프라를 적극적으로 채택한 것은 생태계에서 의 성공게 큰 기여
import
그리고 사전 번들링import { someMethod } from 'my-dep'
위 코드는 동작할까요? 네이티브 es에서는 동작하지 않습니다.
/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd
와 같이 URL을 이용해 ESM을 지원하는 브라우저에서 모듈을 가져올 수 있도록 import
구문을 수정.디펜던시는 반드시 캐싱
vite 는 HTTP 헤더를 이용해 디펜던시를 브라우저에서 캐싱 max-age=31536000,immutable
ESM을 통해 HMR API를 제공, HMR 기능이 있는 프레임워크는 API를 활용하여 페이지 다시 로드 및 애플리케이션 상태를 날리지 않고 즉각적으로 정확히 업데이트 제공가능
vite는 .ts 파일에 대해서 트랜스파일링만 수행, 타입 검사는 ide 와 빌드 프로세서에서 수행
Vite의 TypeScript 컴파일링은 Esbuild를 이용하며, TypeScript 소스 코드를 JavaScript 소스 코드로 변환하는 작업에 대해 tsc
대비 약 20~30배 정도 빠른 퍼포먼스를 보이고 있습니다. (HMR은 50ms 미만)
Frameworks like Vite use a technique where they don’t bundle application source code in development mode. Instead, they rely on the browser’s native ES Modules system. This approach results in incredibly responsive updates since they only have to transform a single file.
We experimented with this approach, but ran into scaling issues with large applications made up of many modules. A flood of cascading network requests in the browser lead to a relatively slow startup time. For the browser, it’s faster if it can receive the code it needs in as few network requests as possible - even on a local server.
That’s why we decided that, like webpack, we wanted Turbopack to bundle the code in the development server. Turbopack can do it much faster, especially for larger applications, because it is written in Rust and skips optimization work that is only necessary for production.
turbopack과의 상세 비교는 다음 글에서 작성하도록 하겠습니다.
반박하는 내용
Outsider / 최근 Vercel이 Turbopack이라는 새로운 번들... | 커리어리
참조