작년 말, 조금은 늦게 Webpack을 접했고, 이제는 Webpack 없이 어떻게 Front-end 개발을 시작할 수 있을까 의문이 들 정도로 Webpack이라는 도구에 많은 것을 의지하고 있다.

그렇게 여러 프로젝트들을 당연하다는 듯이 Webpack으로 시작하거나 리팩토링하다보니 스스로야 너무 편하지만, 다른 누군가와 협업을 하게 될 경우 익숙하지 않은 Webpack 개발 환경을 사용하길 어떻게 설득해야할지 생각을 정리해 둘 필요성을 느꼈다.

분명히 Webpack을 사용하게되면 프로젝트의 시작에 꽤많은 시간이 필요하고, Front-end 개발자로서는 ‘개발 환경설정을 위한 시간 투자’가 상당히 불편하고 어색하게 느껴질 수 있다. 그럼에도 불구하고 Webpack을 사용하여야 하는 이유, JavaScript 개발자로서 Webpack이 기본 소양이어야만 하는 이유에 대해 정리해 보고자 한다.

글은 개괄적으로 쓸 예정이며, 자세한 내용은 링크를 통해서, 또는 글에서 나온 용어를 검색해서 확인할 수 있다.

Entry 설정을 통한 JavaScript 리소스 모듈화

Webpack은 기본적으로 JavaScript Bundling 도구이다. Bundle은 한글로 ‘묶음, 꾸러미’ 라는 뜻으로 여러 JavaScript 소스를 하나로 묶는 도구라는 뜻이다.

Webpack 설정 내의 entry객체를 통해 하나로 묶을 소스들의 위치를 정의할 수 있으며, output객체 내에 정의된 규칙에 따라 특정 위치에 한 개, 또는 복수의 bundle 파일을 생성할 수 있다.

따라서 어떻게 설정하느냐에 따라 편하고 의미있는 폴더 구조를 만들어낼 수 있다.

예를 들어 개발용 리소스에서는 template, style, script를 페이지별로 나누어 담아 사람이 이해하거나 사용하기 쉬운 폴더 구조를 만들고, 빌드된 결과 내에선 웹서버에서 설정하기 편하도록 template, style, script 파일을 확장자 별로 나누어 폴더에 담을 수 있다.

예를 들어 아래와 같은 폴더 구조를 구성하면, 작업 중인 페이지의 여러 리소스들을 찾아 헤매는 번거로움을 줄이면서, 동시에 서버 개발자에게는 익숙한 형태의 리소스 전달이 가능하다.

개발용 리소스

pages
|--about
|    |--about.html
|    |--about.css
|    `--about.js
`--home
    |--home.html
    |--home.css
    `--home.js

빌드된 결과

build
|--html
|    |--about.html
|    `--home.html
|--css
|    |--about.css
|    `--home.css
`--js
    `--index.js
    

CommonsChunkPlugin 자동생성

chunk는 한글로 번역하면 ‘하나로 뭉쳐진 덩어리’이다.

Webpack은 output설정을 통해서 entry객체를 바탕으로 원하는 위치에 여러 JavaScript 파일을 생성할 수 있다.

이렇게 하면 하나로 Bundle된 엄청 큰 사이즈의 JavaScript가 생성되는 것을 피할 수 있지만, 각 페이지에서 중복되어 여러번 로드되는 JavaScript 코드가 생겨 오히려 전반적인 서비스의 유저경험을 저해할 수 있다.

CommonsChunkPlugin을 활용하면 중복 사용되는 JavaScript 모듈을 별도의 공통된 파일로 생성할 수 있다. 공통된 리소스만 뭉쳐진 파일은 초기에 로드한 뒤 브라우저 캐쉬를 통해 빠르게 로드할 수 있다.

NPM으로 JavaScript 리소스 일원화

Webpack은 CommonJS 모듈을 포함한다.

대부분의 Major 라이브러리는 NPM 생태계를 통해 제공되고 있으며, CommonJS를 통해 읽어오고 Webpack을 통해 브라우저에서도 작동가능한 JavaScript 파일로 번들링할 수 있다.

이렇게 하면 라이브러리를 로드하기 위해 Temaplate 파일에 별도의 지저분한 <link>, <script> 태그를 작성할 필요가 없어지고, NPM을 통한 라이브러리의 버전관리도 가능하다.

Loader를 활용한 Node.js 도구의 활용

Webpack은 JavaScript 파일을 entry로 지정하여, JavaScript 내에서 Front-end에 필요한 여러 리소스를 읽어들이고, 수정하고, Build할 수 있다.

특정한 확장자가 포함된 파일을 CommonJS 모듈을 통해 읽어들이고, 읽어들인 파일의 형식에 따라 처리하기 위해 필요한 도구가 loader이다. 뭐하려 불편하게 JavaScript로 CSS와 각종 Asset을 읽어들이냐고 물을 수 있을 것이다. loader를 통해 Front-end 리소스를 관리하는 데에는 다음과 같은 장점이 있다.

  • Sass, ESLint, Babel 등의 도구를 위한 설정과 빌드 프로세스를 일원화할 수 있다.
  • Script 뿐만 아니라 Style, Template 파일에서도 HMR(Hot Module Replacement)를 사용할 수 있다.
  • 정적리소스의 Cache 방지를 위한 Timestamp나 Hash를 간편하게 추가할 수 있다.
  • 각 페이지별 template 파일에 필요한 <script>태그나 <link>태그를 자동으로 추가할 수 있다.

Webpack Configuration으로 간편한 로컬/테스트/리얼 환경별 빌드 관리

Webpack은 Objectreturn하는 별도의 webpack.config.js 설정파일을 기반으로 돌아간다.

CLI 명령어Compiler 모듈을 통해 복수의 설정파일을 운영할 수 있으며, 설정한 내용에 근거해 Local/Stage/Real 등의 환경별 다른 빌드 옵션을 관리할 수 있다.

일반적으로 개발과 테스트를 위한 환경에서는 브라우저 개발자 도구 활용을 위한 sourcemap관련 옵션을 추가하거고, 상용 서비스 환경에서는 유저의 편이와 서버 리소스 절약을 위한 uglify등의 optimize 플러그인, 스크립트를 통해 로드하는 정적리소스들을 추출하기 위한 extract-text-webpack-plugin 등을 추가한다.

또한 개발 환경에서 Front-end와 Back-end 서버를 따로 운영하는 등의 경우 proxy 설정을 통해 각 서버의 리소스 교환을 손쉽게 관리할 수도 있다.

Webpack-dev-server 활용한 개발 편의성 증대

JAVA 등의 Back-end 언어와 협업하는 환경에서 Front-end 개발자는 큰 시련을 겪는다. Front-end 리소스의 수정사항이 늦게 반영되거나, 잘못 업데이트되거나 배포되는 이슈들 속에서 Front-end 개발자는 자신의 개발 실력과 무관한 잡다한 스트레스 속에서 수영하게 된다.

webpack-dev-server는 Webpack 설정을 통해 Front-end만의 개발용 Node.js 서버를 손쉽게 구축하도록 돕는다.

Back-end 리소스와 무관하게 독립적으로 돌아가는 서버로 빌드에 소요되는 시간을 대폭 줄일 수 있으며, 매번 서버에 문제가 생길 때에 Back-end 개발자와 커뮤니케이션해야하는 번거로움도 해소할 수 있다. HMR (Hot Module Replacement)을 통해 수정된 사항을 브라우저에서 빠르게 확인할 수도 있다.

또한 webpack-dev-server는 실질적으로 물리적인 파일을 Build해내는 것이 아니라, Memory내에 Cache 한 결과를 라우팅하기 때문에 watch를 통해 변경사항을 매번 빌드하는 것에 비해 쾌적한 개발 환경을 구축할 수 있다.

마치며

이 외에도 Webpack에는 내가 아직 사용해보지 못한 수많은 장점이 존재한다. 그러나 어떤 도구든 도구에 대한 의존성을 너무 크게 가져가는 것은 바람직하지 않다. 처음 Webpack을 접하는 사용자라면, 가장 기초적인 Webpack 설정으로 시작해서 다른 Major 도구들에서 사용하는 Webpack의 기능을 하나하나 살펴보길 바란다.

대표적으로 React 프로젝트 자동 생성 도구인 create-react-app을 살펴보는 것을 추천한다. 도구를 통해 React 프로젝트를 생성한 후, $npm run inject 명령어를 실행하면 상세한 환경별 Webpack 설정 파일을 확인해 볼 수 있으며, 각 도구의 의미와 용법을 방대한 주석과 함께 공부할 수 있다.