Javascript

Vite

muyeon 2024. 5. 13. 20:48
Vite 를 왜 사용해야 할까?
그냥 마냥 사용하면 될까? 주의점은 없을까?

번들링?

 

번들링은 빌드라고도 할 수 있다.

사용자에게 웹 애플리케이션을 제공하기 위해 여러 코드와 프로그램들을 묶는 행위라고 정의할 수 있다.

개발자는 최종적으로 번들링된 웹 애플리케이션을 만들어내고, 사용자가 웹 애플리케이션을 이용할 때는 번들링한 파일을 받아와 브라우저가 이 번들을 실행한다.

 

 


왜 번들링을 해야해?

 

코드를 번들링한다는 것은 단순히 묶기만 하는 것이 아닌 압축하는 개념과 비슷하다.

번들 파일은 원본 프로그램 파일보다 크기가 작아지고 실행 속도, 로딩 속도 또한 빨라진다.

 

압축한 파일을 받아와 압축해제 전까지 파일을 조작할 수 없는 것처럼, 또한 번들링된 웹 애플리케이션은 사용자가 임의로 조작할 수 없다. 

 

js 에서 변수는 기본적으로 전역범위를 가지기 때문에 하나의 프로젝트 폴더에서 여러 개의 js 파일이 있더라도 공유하는 위험이 있다.

변수를 중복 선언하거나 의도치 않은 값을 할당해 생기는 에러를 번들링 도구는 모듈 번들링으로 해결한다.


HMR (Hot Module Replacement)

 

코드 변경 사항을 페이지 새로 고침 없이 실시간으로 브라우저에 반영하는 기능이다.

이로서 웹 개발 속도를 높이고 효율성을 극대화 할 수 있다.

 

vite 는 기존 HMR 구현 방식과 차별화된 방식으로 구현했다.

전체 페이지를 로드하는 대신 수정된 모듈만 선택적으로 업데이트해 페이지 리로드를 최소화하고 애플리케이션의 상태를 유지한다.

이는 기본적으로 활성화 되어있다.


ESM (ECMAScript Modules)

 

ESM 은 자바스크립트에 도입된 네이티브 모듈 지원을 의미한다.

이는 기존 모듈 시스템에 비해 여러가지 장점을 제공한다.

 

  •  ECMAScript 스펙에 정의된 표준화 모듈 시스템이기에 자바스크립트 환경 및 도구에 호환성을 보장한다.
  •  개별 모듈을 가져오고 내보내는 것을 가능하게 해 모듈성과 코드 구성을 향상시킨다.
  •  정적 분석 도구가 코드 종속성을 더 잘 이해하고 최적화 하도록 돕는다.
  •  트리 쉐이킹을 지원하는데 이는 사용되지 않는 코드를 번들에서 제거하는 프로세스로, 결과적으로 더 작고 빠른 애플리케이션을 만들 수 있다.
  •  자바스크립트에 네이티브로 통합되어 외부 모듈 로더나 구성이 필요하지 않다.

vite & ESM

 

  •  vite 는 ESM 네이티브 기능을 사용해 모듈을 효율적으로 로드한다.
  •  HMR 이 효과적으로, 수정된 모듈만 업데이트 한다.
  •  모듈을 번들링하고 최적화하여 프로덕션 배포를 위한 더 작고 빠른 코드를 생성한다.

 


Vite 를 사용해야 하는 이유

 

브라우저에서 ESM 을 지원하기 전까지 js 모듈화를 네이티브 레벨에서 진행할 수 없었다.

그래서 소스 모듈을 브라우저에서 실행할 수 있는 파일로 번들링 해야 했다.

 

webpack, rollup, percel 과 같은 도구는 이런 번들링 작업을 진행하 줌으로써 프론트엔드 개발자의 생산성을 크게 향상시켰다.

 

하지만 웹 애플리케이션들이 발전함에 따라서 js 모듈의 개수도 많이 증가했다.

이런 상황에서 js 기반의 도구는 성능 병목 현상이 발생했고, 번들링 작업의 소요시간은 늘어났다.

 

번들러 기반의 도구는 애플리케이션 내의 모든 소스코드에 대해 빌드 작업을 마쳐야만 페이지를 제공할 수 있었다.

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

 

기존 작업 도구들은 js 로 만들어져 번들링과정이 비효율적이었고, vite 는 사전 번들링으로 Esbuild 를 사용한다. 이는 Go 로 작성되어 기존 번들러 대비 10~100배 빠른 속도를 제공한다.

 

소스코드도 마찬가지로 컴파일링이 필요하고 수정또한 잦을 수 있다. 이를 모두 불러오는 것은 낭비이다. vite 는 Native ESM 을 통해 이를 제공하고 해결했다. vite 는 브라우저가 요청하는 대로 소스코드를 변환하고 제공하기만 하면 된다. 동적 import 의 경우 현재 화면에서 실제로 사용되는 경우에만 처리된다.


느린 소스코드 갱신

 

번들러 기반으로 개발을 진행할 때 소스코드를 업데이트 하게 되면 번들링 과정을 거쳐야 했다.

따라서 서비스가 커질 수록 갱신 시간이 느려진다.

이렇게 되는 이유는 "모든 파일" 을 번들링 해야하기 때문이다. 이러한 이슈를 해결하고자 HMR 이라는 대안이 등장했으나 이 역시 명확한 답은 아니었다.

 

vite 는 HMR 을 지원하기는 하나 번들러가 아닌 ESM 을 이용한다. 어떤 모듈이 수정되면 vite 는 그저 수정된 모듈과 관련된 부분만을 교체할 뿐이고, 브라우저에서 해당 모듈을 요청하면 교체된 모듈을 전달한다.

모든 과정에서 ESM 을 이용해 앱 사이즈가 커져도 HMR 을 포함한 갱신 시간에는 영향을 끼치지 않는다.

 

vite 는 HTTP 헤더를 활용해 전체 페이지의 로드 속도를 높인다. 이로 요청 횟수를 최소화해 페이지 로딩을 빠르게 만들어 준다.

 


사용법

 

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

 

Vite

Vite, 차세대 프런트엔드 개발 툴

ko.vitejs.dev

npm create vite@latest

 


주의점

 

import 경로를 식별하는 것에 주의해야한다.

vite 가 임포트 경로를 추측하는데 사용하는 default 옵션은 아래와 같다.

 

['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']

 

만약 이 상황에서 import './Component' 로 ./Component.jsx 를 임포트하는 경우 vite 는 다음 단계를 거친다.

 

1. /Component 가 존재하는지 확인, 없음

2. /Component.mjs 가 존재하는지 확인, 없음

3. /Component.js 가 존재하는지 확인, 없음

4. /Component.mts 가 존재하는지 확인, 없음

5. /Component.ts 가 존재하는지 확인, 없음

6. /Component.jsx 가 존재하는지 확인, 있음

 

하나의 임포트 경로를 식별하는데 6번의 작업이 필요하게 된다. 즉 암시적인 임포트가 많아질 수록 경로를 식별하는데 더 많은 시간이 필요하게 된다.

 

임포트 방식을 import './Component.jsx' 와 같이 명시적으로 지정하는 것이 더 좋고, resolve.extensions 의 목록을 좁혀 파일시스템의 작업을 줄이는 방법도 있다. 하지만 후자의 경우 node_modules 내의 파일에 대해서도 잘 수행되는지 확인이 필요하다.

 

TS 를 사용하는 경우 tsconfig.json 의 compilerOptions 에 "moduleResolution": "bundler" 와 "allowImportingTsExtensions": true 를 추가해 .ts 와 .tsx 확장자를 코드에서 바로 사용할 수 있다.

 

또한 다른 여러 주의점들이 존재한다. 아래 링크를 참고.

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

 

Vite

Vite, 차세대 프런트엔드 개발 툴

ko.vitejs.dev


마무리

 

그냥 많이 쓰기에 기술들을 사용하는 것을 많이 보았다.

어떤 기술이라 사용하고, 왜 사용하는지 문제점은 없는지 조금이라도 알아보고 사용하는 것이 중요하다고 생각한다.


참고링크

 

 

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

 

Vite

Vite, 차세대 프런트엔드 개발 툴

ko.vitejs.dev