웹팩 이해하기 - 1
그 동안 React.js로 개발을 진행할 때는 항상 CRA(create-react-app)*를 사용하여 개발 환경을 설정하였다. 그래서 CRA를 사용하면 바로 개발을 시작할 수 있었기 때문에 개발 환경에 대한 고민을 깊게 해보지 않았다.
그런데 이번에 팀 프로젝트를 진행하면서, CRA를 사용하지 않고 개발 환경을 설정해야하는 상황을 마주하게 되었다.
구글에 ‘프론트엔드 개발 환경 설정’과 같은 키워드를 검색하면, 웹팩에 대한 글을 많이 볼 수 있다. 그래서 이번 글에서는 많이 들어본 것 같지만 아직도 잘 모르겠는 웹팩에 대해 알아보려고 한다.
CRA* - 특정 환경의 개발을 바로 진행할 수 있도록 만든 기초 환경을 통틀어 보일러 플레이트(boiler plate)라고 부르기도 하는데, CRA도 이러한 보일러 플레이트의 일종이라고 할 수 있다.
웹팩이란?
웹팩 공식문서에서 웹팩
은 JavaScript 애플리케이션을 위한 module bundler
이라고 설명하고 있다. 그럼 module
과 bundler
는 또 무엇일까?
-
모듈 (module)
모듈은 HTML 파일에서도 자주 봤던 단어이다. 이를 보면 javascript 파일을 의미하는 것처럼 보인다.
<script type="module" src="app.js"></script>
웹팩 공식문서에서 모듈은 모듈 프로그래밍에서 개별적인 기능을 하는 작은 단위라고 설명하고 있다. javascript 에서 보면 각각의 javascript 파일을 모듈이라고 할 수 있을 것 같다.
그렇지만 웹팩에서의 모듈은 javascript 파일뿐만 아니라 애플리케이션을 구성하는 HTML, CSS, Javascript, Images, Font 등 많은 파일들을 모듈이라고 한다.
-
번들러 (bundler)
번들을 우리말로 해석하면 ‘묶음, 꾸러미’ 라는 뜻이다. 그럼 번들러는 묶어주는 도구정도로 유추할 수 있을 것 같다.
웹팩에서는 애플리케이션을 구성하는 모든 모듈을 병합하고 압축해서 만들어진 하나 이상의 파일을 번들 이라고 하며, 이러한 동작을 모듈 번들링이라고 한다.
따라서 웹팩 정의에 나오는 모듈 번들러란 모듈을 번들링하는 도구라고 할 수 있을 것 같다.
요약해보자면 웹팩은 애플리케이션에 필요한 모든 파일(모듈)을 병합하고 압축해서 하나의 결과물(번들)을 생성하는 도구라고 설명할 수 있을 것 같다. 그렇다면 왜 모듈 번들링을 해야하는 걸까?
웹팩의 필요성
웹팩 공식문서와 핸디북 등에서 웹팩이 만들어진 이유와 웹팩이 사용되기 전의 기술들에 대해 자세하게 설명해주고 있다. 그렇지만 그 당시의 기술들을 경험해보지 못한 입장에서 모든 내용을 완전하게 이해하고 공감하지는 못하였다. 그래도 내가 이해한 부분에 대해 최대한 정리해보려고 한다.
-
모듈화의 필요성
웹팩이 등장한 가장 큰 이유는 모듈화와 관련이 있는 듯 하다.
과거의 웹 애플리케이션에서 javascript의 역할은 단순했기 때문에, 파일의 크기도 작았다. 그래서 HTML에 script 태그를 넣는 것만으로도 충분했고, 모듈에 관한 표준 문법이 필요성이 딱히 없었던 것 같다.
하지만 현대의 웹 애플리케이션에서 javascript의 비중이 커지면서, 기능이 복잡해지고 코드의 크기도 커졌다. 커져버린 코드를 하나의 파일로 관리하게 되면 가독성 및 유지 관리에 문제가 발생할 수 있기 때문에 코드를 나누어 관리할 수 있는 모듈에 대한 필요성잉 생기게 된 것이다.
이에 따라 필요한 모듈을 언제든지 불러올 수 있게 해 주거나, 코드를 모듈 단위로 구성해 주는 방법 등 다양한 라이브러리를 만들어졌고, CommonJS*와 AMD*, UMD* 같은 모듈 시스템이 생겨나게 되었다.
이러한 흐름에 맞춰 ES2015+부터는 javascript의 표준 공식 기능으로 모듈화(import, export)를 기본 지원하게 되었다.
CommonJS* - javascript를 브라우저에서뿐만 아니라, 서버사이드 애플리케이션이나 데스크톱 애플리케이션에서도 사용하고자 하는 움직임이 있었고, 이를 위해서는 모듈화가 필요하였다. 이를 위해 모듈 방식을 정의하게 되었는데, 그것이 CommonJS 이다.
AMD(Asynchronous Module Definition)* - 필요한 모듈을 네트워크를 이용해 내려받아야 하는 브라우저 환경(비동기 상황)에서도 javascript 모듈을 사용하고자 하였다. 이를 위해 브라우저 내에서의 실행에 중점을 둔 모듈 방식을 정의하게 되었는데, 그것이 AMD 이다.
UMD(Universal Module Definition)* - UMD는 이름에서 알 수 있듯이, CommonJS와 AMD를 통합한 모듈 방식이다. 모듈 구현방식이 CommonJS 와 AMD로 나뉘기 때문에 서로 간의 호환성 문제가 있었고 이를 해결하기 패턴으로 등장하였다.
-
빠른 로딩 속도와 높은 성능
웹팩의 공식문서에 보면 웹팩은 성능 및 로딩 시간에 관심이 있다고 나와있다.
웹 어플리케이션을 실행시킨다면 브라우저는 javascript와 images, css 등의 파일을 읽어들일 것이다. 앞서 말했듯이 현대의 웹 어플리케이션의 규모가 커지면서 당연히 파일의 수도 많아지게 되었다. 이러한 파일들을 전부 따로 불러들인다면 로딩 시간이 길어질 수 밖에 없다.
웹팩을 사용해서 많은 파일들(모듈)을 병합하고 압축해서 하나의 결과물(번들)로 만들면, 파일의 수와 크기가 줄어들게 된다. 애플리케이션을 실행시키기 위해서 이 결과물만 읽어들이면 되기 때문에 로딩 시간을 줄일 수 있는 것이다.
여기에 웹팩의 Code Splitting* 과 같은 방법을 사용하면, 필요할 때에만 불러올 수 있도록 번들를 분할하여 성능을 더 개선할 수 있다. (웹팩을 통해 성능을 개선하는 자세한 방법들에 대해서는 추후에 추가적으로 작성해보려고 한다.)
*Code Splitting - Code Splitting은 코드를 분할하고, 요청에 따라 로드할 수 있도록 해주는 방법이다. Code Splitting을 하지 않은 경우, 애플리케이션을 실행시켰을 때 모든 코드가 한번에 요청이 되어서 로딩 시간이 길어질 수 있다. Code Splitting을 하게 되면, 필요한 순간 필요한 코드만 불러오기 때문에 우선 순위를 제어할 수 있고, 로딩 시간도 줄일 수 있다.
마무리
이 번 글에서는 웹팩의 정의와 필요성에 대해 알아보았다. 그 동안 CRA를 사용하면서 웹팩이 해주는 역할을 당연하게 생각하고, 왜 궁금해하지 않았는지 스스로를 되돌아보는 시간이었다.
다음 글에서는 웹팩의 핵심 요소인 Entry, Output, Loaders, Plugins 에 대한 개념을 알아보고, 웹팩을 설정하는 간단한 실습을 해보려고 한다.