대가는 결과를 만든다

Vite에 대하여 좀 더 자세히 본문

카테고리 없음

Vite에 대하여 좀 더 자세히

yunzema 2023. 11. 6. 17:11
반응형

목차

1. 번들러

2. Webpack

3. Rollup

4. Esbuild

5. Vite


간단 정리: 기존 브라우저에 모듈 기능이 없었던 시절을 위해 존재하는 번들링 과정 때문에, 개발과정에서 개발서버 실행 및 수정 코드 반영이 비효율적으로 느리다. 현재 네이티브 모듈 기능을 지원 하게된 모던 브라우저에 맞춰 개발서버 실행 시 번들링없이 빠르게 작업할 수 있도록 개발자 경험을 향상 시키고자 Vite가 등장했다.

 

 

1. 번들러

- 배경: ES Module(ES6 import) 미지원 -> 웹서비스 규모 커짐에 따라 코드 방대해짐 -> 분리(전역객체를 사용) -> 모듈 시스템 필요!

- 기본 역할: 필요한 모든 종류의 파일들을 모듈단위로 나누어 최소한의 파일 묶음(번들)로 만들어주는 역할

- 추가적인 역할: 트랜스파일링, 개발서버 구동, 브라우저에서 로드방식, 최적화 등등

 

2. Webpack(v5)

- 2012 등장, 2018 SPA 등장으로 역할이 더 중요해지고, 필수가됨.

- 주요 Feature

  - 오픈소스/커뮤니티 기반 plugin, loader를 활용하여 번들에 대한 설정, 튜닝 가능

  - HMR(Hot Module Replacement) 개발서버 지원 (소스코드 변화 감지 후 바로 반영)

  - code splitting 번들로드 최적화

  - v4 commonjs 번들링, v5 ES6모듈로 번들링이 가능 해짐

- 각 모듈들이 각자 고유 스코프를 지닌 상태로 번들링되며, 각 모듈들에 오버헤드/중복코드가 생길 수 있다. 상수의 경우 uglify에 제한이 있다.

  - 대신 코드 스플리팅을 통해 최적화 할 수 있는 기능이 좀 더 강화되어있다.

- 다양한 종속성이 있는 복잡한 어플리케이션에 유리

 

3. Rollup(v4)

- Webpack이후 후발주자

- Webpack보다는 덜복잡한 설정 방식

- ES6모듈로 빌드 가능

- 번들링 방식의 차이로 인해 webpack보다 일반적으로 속도가 빠름.

  - 모든 모듈들을 상위 스코프에 배치(scope hoisting)하여 번들하는 형태(flat bundling)로 중복코드 제거와 uglify를 통해 최종 번들의 크기와 로드시간을 향상 시킨다.

=> 라이브러리/패키지 개발 시 니즈를 충족하는 방향으로 자리잡음

 

* Webpack과 Rollup의 비교를 잘정리한 글

Bundle Process Difference Rollup vs Webpack

- https://www.evolvingdev.com/post/webpack-vs-rollup

 

4. Esbuild

- 10~100배 빠른 빌드 시간

  - Go언어 기반 네이티브 코드 방식으로 동작(JIT 컴파일 방식인 자바스크립트로 작성된 기존 번들러와 속도 차이)

  - prasing, linking, code 생성 단계 중 parsing, code생성 단계에서 병렬처리로 속도 이점 크게 작용

  - esbuild에서 사용하는 typescript praser는 성능을 우선순위로 하여 커스텀되어 있음

- EsBuild 자체 통합 빌드 툴은 아직 없음

https://esbuild.github.io/faq/#why-is-esbuild-fast

 

 

5. Vite(v4)

5-1. 배경

 - 서비스 사이즈/사용 모듈 증가 -> 개발서버 구동, HMR 느린 피드백 루프 -> Poor DX

 - Native ESM: 모던 브라우저가 기본적으로 내장된 Module 기능을 지원하기 시작 (https://ko.javascript.info/modules-intro)

    - <script type="module">...</script>

    - 특징: 모듈레벨 스코프, this는 undefined, 단 한번만 평가됨, 지연실행(HTML문서 완성된 후 실행)

    => Vite는 이 Native ESM을 적극활용하여 기존에 번들러가 브라우저를 위해 모듈화 해주던 작업을 브라우저가 알아서 제 때에 모듈을 로드하는 방식으로 동작하게 지원한다.

 

5-2. 개발 서버 cold start 방식의 개선

 

- 개선방향 : 모든 소스 코드에 대한 번들링 작업 완료 후 개발서버 구동이 완료되던 방식 -> dependency와 source code 두 카테고리로 나누어 처리하여 개발서버 구동시간 개선

  - dependency code: 내용이 바뀌지 않는 코드들의 비효율적인 번들링 과정 개선 => EsBuild를 통한 사전 번들링

  - source code: Native ESM(브라우저의 module 기능)방식에 맞게 소스코드를 제공한다. 브라우저가 요청하는대로 소스코드를 변환하여 제공(번들러의 역할을 브라우저에게 위임, 소스코드를 번들링하지 않음!)

 

=> 수정 시 수정된 모듈만 교체하고, 브라우저는 교체된 모듈만 요청하므로 앱 사이즈가 커져도 갱신시간에 영향을 끼치지 않음

(+ HTTP 헤더 캐시컨트롤을 활용하여 요청횟수 및 페이지 로딩에 대해 최적화가 되어 있어 빠름)

https://ko.vitejs.dev/guide/why.html

- 개발서버 실행 환경에선 기본적으로 typechecking을 제공하지 않음(속도에 초점). 개발환경 IDE에 위임하고, 빌드시에 수행한다

 

5-3. Command

- dev(vite) : 개발서버로 실행 default port 3000

- build(vite build) : 프로덕션 빌드. Rollup을 활용 (Svelte, Rollup을 만든 리치해리스, Vite를 공식 번들러로 사용한 Svelte. 서로 밀어주기?)

- serve(vite preview) : build한 dist경로의 파일을 호스팅 default port 5000

 

5-4. Compatibility

 

- node 버전 : 14.18+, 16+ (템플릿에 따라 더 상위버전을 요구하는 경우도 있음. 참고: https://vitejs.dev/guide/#scaffolding-your-first-vite-project)

- 브라우저 호환성 : native ES Modules, native ESM dynamic import, import.meta가 지원되는 브라우저가 대상이다. (참고: https://vitejs.dev/guide/build.html)

  - chrome >=87

  - firefox >= 78

  - safari >=14

  - edge >= 88

  - *Legacy 브라우저에 대해서는 @vitejs/plugin-legacy를 통해 전용 청크를 별도로 지원해주므로, native ESM을 지원해주지 않는 브라우저에 대해 커버 가능하다.

 

5-5. Build Optimization

 

- css 파일 분리: 비동기적으로 불러와지는 청크 내에 CSS 코드가 포함된 경우, 자동으로 추출해 파일로 분리 -> <link> 태그를 이용해 분리된 cssz코드를 불러오게끔하여 FOUC(Flash of unstyled content)현상을 회피(css가 개별적인 파일로 분리된 경우는 해당 설정 불필요)

- async chunk loading optimization

 

최적화되지 않은 경우, 먼저 비동기적으로 A load ->  A parse ->  C load

vite는 Preload 스텝을 이용해 A를 가져올 때 C 청크를 병렬적으로 가져올 수 있도록 Dynamic Import 구문을 자동으로 재작성 => A, C를 병렬적으로 로드

 

5-6. 환경 변수

 

- vite에서는 모든 파일을 native ESM을 통해 제공된다.

- import.meta.env 객체를 통해 환경변수에 접근가능

import.meta.env.(MODE{string}|BASE_URL{string}|PROD{boolean}|DEV{boolean}|SSR{boolean})

 

- .env 파일의 환경변수 파일도 import.meta.env 객체를 통해 접근 가능. Vite에서 접근 가능한 환경변수 구분은 VITE_ prefix를 사용

VITE_MY_KEY=123
API_KEY=FOO123456

*VITE_MY_KEY는 접근 가능하지만, API_KEY는 client bundle에서 사용할 수 없음.

 

5-7. 기타

- vite의 ecosystem : https://patak.dev/vite/ecosystem.html

- 플러그인 설치를 통해 PostCSS, Preprocessor를 지원하고 hot reloading 지원한다.

  - postcss-nested: css 파일 내에서 nested 문법 지원

  - sass

- asset

  - import 구문을 통해 asset을 사용하면, 해당 에셋의 경로로 사용하면 된다. 빌드환경에 맞게 자동으로 경로를 세팅해준다. (hash name 포함)

  - 하드코딩된 root 경로를 통해 정적 asset을 사용하는 경우 public 디렉토리 기준으로 asset을 배치해야 한다.

- plugin: webpack같이 3rd party plugin을 rollup interface를 통해 구현할 수 있다.

- Glob import: 여러 모듈을 한번에 가져올 수 있는 기능. 상대경로, 절대경로, alias 경로 이용

//dynamic import
//source code
const modules = import.meta.glob('./dir/*.js')

//vite transformation code
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
  './dir/bar.js': () => import('./dir/bar.js')
}

//direct import
const modules = import.meta.glob('./dir/*.js', { eager: true })

//vite transformation code
import * as __glob__0_0 from './dir/foo.js'
import * as __glob__0_1 from './dir/bar.js'
const modules = {
  './dir/foo.js': __glob__0_0,
  './dir/bar.js': __glob__0_1
}

 

Comments