Bundler는 대체 왜 날 괴롭히는가? - WebPack, CRA, Vite

HaeMin·2022년 12월 5일
0

한 프로젝트의 유지보수를 진행하며 WebPack과 create-react-app을 함께 사용하는 모습을 확인하였다. Vue로 짜여진 패키지는 webpack으로 빌드하고, React로 짜여진 패키지는 create-react-app의 react-scripts로 빌드하고 있었다. 여러 빌드 툴과 또 dependency 에 따른 오류들이 나를 미치게 해 개념을 정리하며 혼내줄 것이다.

WebPack은 대체 무엇인가?

먼저 가장 크게 느껴지는 의문이 Vite, WebPack, create-react-app 이게 다 무엇이냐 하는 것이다. 결론부터 말하자면 이 셋 모두 Javascript를 번들링해주는 녀석들이다.

JavaScript Bundling

기본적인 html 코드가 다음과 같이 작성되었다고 가정해보자,

<html>
<script src="one.js"></script>
<script src="two.js"></script>
</html>

one.js 파일과 two.js 파일에서 같은 이름의 변수를 사용한다면 각 변수들이 구분되질 못한다. 단적으로 말하자면, 스크립트들 간의 캡슐성이 보장받지 못한다는 이야기이다.
만약, one.js에서 score라는 변수를 500으로 설정하고 연산하고 있는데, 갑자기 two.js에서 score를 1000으로 만들어버리면 예기치 못한 오류가 생겨버린다.

이러한 문제를 해결하기 위해 Javascript 파일들을 하나로 묶어서 각각의 파일들의 변수가 서로 독립적으로 운용될 수 있도록 하자는 Bundling의 개념이 생겨났다.

쉽게 예시를 들자면 one.js의 변수들과 함수들은 one.score 와 같이 사용하고, two.js의 변수와 함수들은 two.score로 사용하기로 하여 이 두 파일을 합치는 것이다.
(이때, 변수명 앞에 이름을 붙이는 것을 namespace라고 한다.)

의존성 ( Dependencies )

앞서 살펴본 예시는 캡슐화의 부재였다면, 이번에는 의존성이다.

<html>
<script src="one.js"></script>
<script src="two.js"></script>
</html>

같은 예시 코드에서 만약 one.js의 함수 sum을 two.js에서 사용하려면 어떻게 해야할까?
위와 같이 one.js를 먼저 선언하고, 그 다음 two.js를 사용한 다음에 전역함수를 사용하기에는 개발자가 신경써야할 부분이 너무 많아진다.
two.js를 개발하기 위해 계속 one.js 파일내용을 왔다갔다 살펴보며 구현해야만 할 것이다.

이때, 우리는 import/require와 같은 방식으로 two.js에 one.js를 추가한 다음 사용한다. 이러한 상황을 two.js 가 one.js에 "의존성을 가진다" 라고 말한다.

JavaScript Bundling Tool

앞서 설명한 Bundling을 구현하는 다양한 도구들이 있다.

CommonJS

CommonJS의 경우 Javascript를 브라우저 뿐만이 아닌 다양한 분야에서 사용하자는 취지로 만들어진 표준 라이브러리이다. 우리에게 익숙한 Node.js도 바로 이 CommonJS의 모듈화를 통해 만들어졌다.

one.js

var a = 3;
b=4;

exports.sum = function(c, d) {
   return a + b + c + d;
}

two.js

var one = require("one")
console.log(one.sum(1,2));

위의 사용예시와 같이 exports와 require을 통해 javascript 파일 상호간의 변수와 함수를 사용하고 또 구분지을 수 있다.
하지만, CommonJS의 경우 브라우저에서 사용하려면 require()한 모듈들을 모두 다운로드 받아야만 사용할 수 있기 때문에 실행 시간이 매우 오래 걸리게 된다.

ES6

import * as one from "./one.js"

console.log(one.sum(1, 2));

최신 버전의 자바스크립트에서는 위와 같이 import를 사용하여 의존성을 정의할 수 있다. 하지만 이러한 방식은 아직 지원하지 않는 브라우저에 대응시키기 어렵다. 아래 사진은 현재 ES6의 import를 지원하지 않는 브라우저 버전들을 보여준다. 빨간 색으로 적힌 버전들이 아직 지원하지 않는 것들이다.

역시 항상 IE가 문제다..

WebPack

드디어 WebPack에 대한 이야기이다. 앞에서 다룬 모든 문제들을 해결한 Bundling Tool -

Bundler

이다.
아래의 그림과 같이 WebPack은 프로젝트의 모든 파일들을 엮어서 배포 가능한 형태로 묶어준다.

  1. babel과 함께 사용하여 모든 브라우저에 대응할 수 있다.
  2. 각각의 js 파일들이 모듈로서 캡슐화의존성 정립이 가능하다.
  3. 번들된 상태로 제공되기 때문에 브라우저의 속도 저하를 걱정하지 않아도 된다.

이러한 WebPack의 특징을 보면 앞서 제시된 녀석들보다 Web의 배포에 도움이 된다고 볼 수 있다.

Create-react-app - CRA

CRA의 깃헙 커밋 목록을 확인해보면 21년 5월 정도에 WebPack5로 마이그레이션 한 흔적을 찾아볼 수 있다. 이처럼 CRA는 WebPack을 기반으로 Facebook에서 오픈소스 프로젝트로 개발한 React.js 전용 Bundler이다.

WebPack은 모든 Web 환경에서 Bundling을 제공하도록 만들어졌기 때문에 설정을 통해 조절할 수 있는 부분이 React를 벗어나는 경우가 있다. (심지어는 WebAssembly에서도 동작한다)
이에 WebPack의 일부 기능들을 추상화를 통해 가리고 React의 빌드가 깨지지 않도록 하는 선에서 번들링 설정들을 제공할 수 있도록 개발한 것이 바로 CRA이다.

따라서 CRA는 WebPack을 통해 동작한다고 봐도 무방한데, WebPack 만큼의 자유도가 없는 대신 안정성을 갖춘 것이다. (React를 쓴다면 자유도가 없는 것도 아니다...)

Vite

Vite 도 번들러 중 하나이다. 최초에는 Vue.js를 타겟으로 개발되었지만, 지금은 React.js와 같이 다른 프레임워크도 지원하고 있다. 간결한 개발을 추구한다는 컨셉을 가지고 있다.

마치며..

오늘의 포스팅은 프로젝트를 괴롭히며 여러 오류를 내뿜던 WebPack이 필요했던 이유와 번들러의 개념에 대해 다루고, 여러 번들러들 (CRA, Vite)에 대해서 다루었다. 이제 나를 괴롭히던 WebPack과 Google API를 유심히 지켜보며 오류를 해결해 Issue Contribution을 해보고자 한다. 다음 과정은 내일 포스팅해보도록 나 자신과 약속하면서 마치겠다. ㅎㅎ


여담으로, velog 첫 포스팅이지만 플랫폼 이름에 맞게 신경 쓴 포스팅 보다는 하루의 개발 일지 정도로 작성하고자 하였다. 앞으로는 Velog에 편하게 글을 작성하고, 여러 포스팅들을 모아서 네이버 블로그와 개인 웹에 정제된 포스팅을 할 계획이다.

profile
개발

0개의 댓글