webpack을 JavaScript 파일을 합치는 도구로만 보면 README의 절반만 읽게 됩니다. 이 프로젝트의 설명은 JavaScript뿐 아니라 CSS, 이미지, JSON, CoffeeScript, LESS 같은 자원까지 변환하고 패키징할 수 있다고 말합니다. 브라우저가 다양한 입력 형식을 직접 떠안는 대신, 빌드 단계가 그 차이를 정리하는 구조입니다.
그 정리는 모듈 시스템에서도 드러납니다. webpack은 ES Modules, CommonJS, AMD를 함께 묶을 수 있고 의존성을 컴파일 중에 해석합니다. 덕분에 런타임에 남는 의존성 처리 부담을 줄일 수 있습니다. loader는 파일을 전처리하는 통로입니다. README가 예로 드는 TypeScript의 JavaScript 변환, Handlebars 문자열의 컴파일 함수 변환, 이미지의 Base64 변환은 소스와 브라우저 실행물 사이에 빌드라는 경계가 있음을 잘 보여줍니다.
초기 로딩을 둘러싼 선택은 code splitting에서 더 선명해집니다. 모든 것을 하나의 bundle에 넣으면 구조는 단순해지지만 첫 진입에 필요하지 않은 코드까지 함께 내려갈 수 있습니다. 반대로 여러 chunk를 만들면 애플리케이션 일부를 런타임에 비동기로 불러올 수 있습니다. 첫 화면을 가볍게 만들 여지는 커지지만, 어떤 기능을 어느 시점에 로드할지와 그에 따른 배포 구성을 함께 관리해야 합니다.
plugin interface는 이 경계를 고정된 상자처럼 만들지 않습니다. webpack 내부 기능 대부분이 plugin interface를 사용하므로, 프로젝트는 필요한 변환과 패키징을 확장할 수 있습니다. 유연함의 대가도 있습니다. loader와 plugin이 많아질수록 브라우저에 도착하는 코드와 자산이 어떤 과정을 거쳤는지 추적해야 합니다.
여기서 말하는 브라우저 경계는 보안 샌드박스가 아닙니다. webpack이 다루는 것은 모듈과 자산을 빌드에서 정리해 런타임으로 넘기는 방식입니다. README의 호환성 안내처럼 ES5 브라우저를 겨냥할 수 있어도 import()와 require.ensure()에는 Promise가 필요하고, 구형 브라우저라면 polyfill을 준비해야 합니다. 결국 webpack을 평가할 때는 bundle이 생겼는지만 볼 일이 아닙니다. 어떤 입력을 빌드에서 흡수했는지, 어떤 코드를 chunk로 늦췄는지, plugin과 loader가 런타임의 부담을 어떻게 바꿨는지를 봐야 합니다.