패키지 매니저와 비슷하게 헷갈리는 번들러..
번들러를 왜 사용하냐면?
번들러를 알려면 모듈화 먼저 학습해야한다!
나는 ES6+ 문법을 학습해서 이미 import, export와 같은 모듈화된 JS에 익숙하지만,
기존의 JS는 script 삽입으로 로드해서 불러오는 방식으로, 각 script들이 전역 객체를 공유하며 변수가 중복되는 문제가 발생될 수 있었다.
이에 따라 모듈화의 필요성이 대두되면서 CommonJS, AMD라는 모듈화 방식이 나오는데..
CommonJS는 require()로 스크립트를 불러오고, module.exports로 모듈화시키는 방식이 대표하고 있고, Node.js에서 채택해서 사용하고 있는 방식이다.
반면 AMD(Asyncronous Module Definition) 방식은 대표적으로 RequireJS가 있고, 이는 브라우저에서 채택한 방식이다.
내가 가장 헷갈렸던건 그래서 CommonJS, AMD를 뭐라고 정의할 수 있을까?
이들은 “JS 모듈화 방식”이고, 어떠한 특정 라이브러리의 이름이 아니다!
그렇다면 UMD는?
모듈 시스템이 위와 같이 두 그룹으로 나눠져 사용하다보니 서로 호환이 안되게 되고, 이를 해결하기 위한 모듈 시스템이 바로 UMD.
UMD 모듈 방식은 define을 사용하는지 module.exports를 사용하느냐에 따라 각기 사용법대로 분기가 나눠져 있다.
그리고 ES6에서 import, export를 사용하는 모듈 기능이 나온다!
이게 바로 ESM = (Native) ES Module
ES6에서 추가된 모듈 기능!
script 태그에 type="module" 속성을 추가하면, 해당 파일은 모듈로서 동작한다.
기존의 script 삽입이 전역 객체를 공유해 말썽이었다면, ES6에서는 type="module" 속성을 추가함으로써 모듈 파일마다 개별 스코프를 가질 수 있게 된 것.
모듈 내에서 외부에 공개해 참조하게 하고 싶은 변수/함수/클래스가 있다면 export 키워드를 붙이고,
이렇게 export된 변수/함수/클래스를 가져올 때는 import 키워드를 사용한다.
import/export 자세한 사용법에 대해서는 이미 잘 알고 있으니 패스!
번들러는 이러한 각기 모듈들을 한데 모아 묶어주는 도구
처음에는 ESM 등장 전 각 모듈화 진영의 방식을 브라우저와 호환하기 위해서 번들러가 필요했다.
그런데 ESM이 생겼음에도 번들러가 필요한 이유는?
ES6에서 사용할 수 있다고 마법처럼 모든 브라우저에서 ESM을 사용할 수 있게 되는 것은 아니다.
JavaScript 문법 버전의 차이도 있고, 이전 브라우저와의 호환성도 문제가 된다.
따라서 ESM의 등장에도 불구하고, 번들러는 여전히 모듈 종속성을 처리하고 번들링을 해주기 위해 사용되었다.
그리고 브라우저에서 ESM을 자체 지원하고 대부분의 브라우저에서 지원이 되는 지금은 더 이상 번들러에 의존하지 않을 수 있게 되었다.
이에 번들러는 기본 “번들링”이라는 기능에 더해 코드 스플리팅, 종속성 해결, 최적화, 브라우저 호환 보장 등의 기능이 있어 선택적으로 채택되어 사용할 수 있는 도구가 되었다.
기존에 CRA를 사용하다가, Vite가 빠르다고 하여 Vite로 넘어가는데,
이 과정에서 CRA는 뭐지, Vite는 뭐고 왜 빠르지..하는 질문이 생겼다.
그 질문을 오늘에서야 답을 구해본다.
CRA는 빠르게 리액트 프로젝트 개발 환경을 구성할 수 있는 도구로 알고 있었는데, 내부적으로 번들러 webpack 및 빌드 프로세스가 설정된다고 한다.
Vite도 마찬가지로 개발 환경을 구성할 수 있고, 기본적으로 ESM 지원을 하며, 사전 번들링으로 Esbuild를 사용한다고 되어 있다.
모듈 번들러를 검색하면 대표적으로 webpack, rollup, parcel이 나오는데,
그렇다면 CRA, Vite를 번들러-라고 부르긴 어려울 것 같다.
아직 학습해야 할게 많지만 이렇게 카테고리별로 구분하니 조금은 정리되는듯.