본문으로 바로가기

웹팩(Webpack)이란?

category 개발/프론트엔드 2023. 1. 11. 18:37

웹팩이란 최신 프론트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러이다. 좀더 알기쉽게 설명하자면 리액트에서 빌드를 수행할때 사용하는 소프트웨어이라고 할 수 있겠다.

 

모듈 번들러는 웹 애플리케이션을 구성하는 자원(컴포넌트, 이미지, CSS파일 등등)을 모듈 단위로 나누어 필요할때마다 조합하여 하나의 결과물로 산출시키는 역할을 한다.

 

프론트엔드 업계에서 많이 사용되는 프레임워크인 리액트, 뷰는 프로젝트 파일의 크기가 꽤나 크다. 특히 최근에는 백엔드의 로직을 일부 프론트엔드로 옮겨오는 추세인지라 그 복잡도가 더 증가했다고 할 수 있다. 이런 대규모 소스코드를 브라우저가 그대로 다운받아서 실행할경우, 너무 느리거나 브라우저가 버티지 못하고 다운되어 버릴 것이다.

 

따라서 웹팩을 사용하여 파일들간의 의존성 관계를 정리하고, 코드를 최적화 하여 하나의 자바스크립트 파일(main.js)로 만들어줘야 한다. 이 파일은 페이지 라우팅이나 세션, 쿠키의 값에 따라 필요한 소스코드만을 다운받고 실행시킨다. 모든 소스코드를 한번에 실행시키지 않기 때문에 그 규모에 비해 실행 속도가 빠르다. 이처럼 웹팩을 사용해서 코드를 하나로 번들링하는 작업을 빌드라고 부른다.

 

토막지식) 빌드, 번들링, 변환은 모두 같은 의미이다.

웹팩이 필요한 이유

웹팩은 크게 세가지 문제를 해결하기 위해 적용한다.

1) 파일 단위의 자바스크립트 모듈 관리의 필요성

자바스크립트는 전역 변수라는 개념을 가지고 있다. 이는 해당 변수가 선언된 곳 보다 낮은 스코프 범위를 가지는 함수라면 해당 변수에 접근할 수 있다는 것을 의미한다. 만약 다음과 같이 코드가 작성되어 있다면 어떨까?

<!-- index.html -->
<html>
  <head>
    <!-- ... -->
  </head>
  <body>
    <!-- ... -->
    <script src="./app.js"></script>
    <script src="./main.js"></script>
    <script>
      getNum(); // 20
    </script>
  </body>
</html>
// app.js
var num = 10;
function getNum() {
  console.log(num);
}
// main.js
var num = 20;
function getNum() {
  console.log(num);
}

이 경우 main.js에서 선언된 num을 사용하게 되고, 변수가 서로 겹치게 되는 불상사가 발생하게 된다. 개별의 파일 자체는 문제없이 작동하겠지만, 하나의 html 파일에 모아놓고 보니 오류가 발생하는 것이다. 이러한 스코프 단위에서 발생하는 이슈는 비단 과거의 html파일에서만 생기는 문제가 아니다.

 

리액트에서는 jsx 문법을 사용하고 있고, 뷰에서는 vue파일을 별도로 사용하고 있다. head와 script까지 달린 구식 html은 모던 프레임워크에서 못 본지 오래됬을 것이다. 그도 그럴것이 복합 컴포넌트니, props drilling이니 프론트엔드에서 발생하는 이슈는 모두 자바스크립트에 관련된 것 처럼 느껴지기 때문이다. 하지만 마지막의 마지막에 실제로 브라우저가 렌더링하는것은 html 문서이다. 그래서 이런 렌더링까지 고려해야 하는 로우 레벨 개발자들은 웹팩이라는 방법론을 떠올릴 수 밖에 없었던 것이다. 그리고 우리는 그 유산을 사용하는 중이다.

 

웹팩은 파일 단위로 코드를 불러오는 방식을 사용해서 이러한 이슈를 해결하였다. 이는 곧 모듈화라고도 불린다.

2) 웹 개발을 도와주는 자동화 도구

우리는 모던 프레임워크를 사용하고 있기 때문에 이 부분에 대해서는 자주 생각해보지 않았을 것이다. 그도 그럴게 리액트는 그냥 명령어 한번만 치면 개발서버, 빌드, 테스트가 수행되지 않는가? 이것에 대해 의문을 가져본 적이 없는것이 일반적일 것이다. 그 많은 복잡한 작동 과정을 어떻게 꿰뚫고 사용하겠는가? 만약 그래야 한다면, 안그래도 높은 모던 프레임워크의 러닝 커브가 하늘을 뚫고 치솟을 더질 것이다.

 

조금 시간을 되돌려서 JQuery를 사용하던 시절로 돌아가 보자. 아직 퍼블리셔라는 직종의 자리가 유효하던 시기로, 약 2000년대 초반 정도가 적당할 것 같다. 이 당시에는 js파일을 모듈화 시켜서 사용한다는 개념 자체가 대중적이지 않았던 시기이다. 대부분의 코드는 html파일에 script 태그를 달아서 작성했고, 모든 의존성은 html파일에 걸려 있는게 일반적이였다.

 

이때 퍼블리셔들의 업무는 디자인 시안대로 웹 UI를 구현하는 것이였다. 그러나 html파일에 마크업이 적용된것을 확인하기 위해서는 매번 브라우저를 새로고침 해줘야 하는 불편함이 있었다. 이때 이러한 불편함을 해소하기 위해 나온것이 바로 Adobe Dreamweaver다.

 


당시 드림위버의 지위는 대단했다. 그저 새로고침을 매번 눌러줘야 하는 불편함이 해소된것 뿐만이 아니라, 지금의 ide에서 제공하는 기능인 자동완성을 거의 최초로 지원했었고 이미지 파일과 같은 에셋들을 드림위버 안에서 손쉽게 조작할 수 있었다. 그 당시로써는 혁신이나 다름 없는 소프트웨어였다.

 

하지만 이런 드림위버도 한계는 있었다. 강력한 기능에 비해 잔 고장(오류)가 너무나도 많았고, 유료 정책을 유지한 어도비로 인해 접근성이 낮았다. 결정적으로 모바일 웹 시대가 도래하면서 인터넷 익스플로어의 입지가 좁아졌고, 자연스럽게 드림위버 또한 역사의 뒤안길로 사라져 갔다.

 


이러한 무겁고 불편한 문제점들을 일부 해결하고 좀더 가벼운 실시간 에디터였던 Brackets과 같은 에디터들이 등장했지만, 퍼블리셔라는 직군 자체가 사라져가고 더 많은 기능을 구현해야 하는 수요에 맞춰 프론트엔드 직군이 강세를 띄면서 bracket또한 오래가지는 못했다.

 

옛날 애기가 길어졌는데, 실시간 새로고침은 지금 우리가 사용하는 프레임워크에서는 당연할정도의 기능이지만 과거에는 그 기능 하나만으로 새로운 소프트웨어 분야가 탄생할정도로 혁신적이였다는 것이다. 이 외에도 html, css, js 파일을 압축하고, 이미지를 압축시켜 파일 크기를 줄이는 등 브라우저 퍼포먼스를 높히기 위한 많은 고민이 웹팩에 녹아 있다.

3) 웹 어플리케이션의 빠른 로딩 속도와 높은 퍼포먼스

SPA니 CSR이니 SSR이니 말이 많지만 이 모든 것들의 목표는 웹페이지를 최대한 빨리 보여주는 것이다. 추가로 사용자 경험도 유지하고 말이다. 우리는 웹사이트가 3초 이상 제대로 나오지 않으면 뭔가 잘못됬다고 느낀다. 그정도로 신예 웹사이트들은 순식간에 화면을 뿌려주고 있다. 3초만에 모든 파일을 받아오는건 어려우니 lazy loading, skeleton loading이라는 개념도 나왔다. lazy loading은 필요할때만 자원을 요청하는 것으로, 웹팩의 철학과도 맡닿아 있는 부분이 있다.

 

웹팩의 최대 목표는 프로젝트 코드를 최적화시켜 빨리 화면을 보여주는 것이다. 이를 이루기 위해 코드와 이미지를 압축하고, lazy loading등을 사용하기도 한다. 뿐만 아니라 개발자가 개발 과정에서 불편함을 겪지 않도록 코드가 변경될때마다 바로 적용되도록 하는 기능도 포함되어 있다.

웹팩 사용하기

리액트로 프로젝트를 개발하고 배포할 때 react-script에서 제공하는 것 만으로는 부족해서 webpack을 따로 설치해서 사용하는 방법이 있다. 이 방법에 대해서는 많은 글에서 훨씬 더 잘 설명하고 있기 때문에 이 글에서 다루도록 하지는 않겠다.

 

개발하면서 더 자주 접하는것은 바로 config 파일이다. 확장자가 .config.js 으로 되어있는 파일을 말한다. 보통 루트 폴더에 위치하며, nextjs나 jest, storybook과 같은 라이브러리에 설정을 적용하는데 쓰인다. stack overflow에 올라오는 질문중 꽤 많은 질문들이 이 config 파일 설정에 대한 것들이 있다.

 

config 파일은 말그대로 설정 파일 이므로 프레임워크, 라이브러리 마다 다르게 적용된다. 심지어는 config라고 적혀있지 않은 경우도 많으니 말이다. 예를 들자면 nextjs와 webpack을 함께 사용하는 환경에서는 서로 호환되도록 설정을 맞춰줘야만 한다(굉장히 까다로운 작업이다). next.config.js뿐만 아니라 _app.tsx를 수정해줘야 하며, 이와 함께 storybook의 main.js, preview.js도 설정해줘야 한다.

 

우리는 직접적으로 웹팩을 사용하기보다는 그 외에 라이브러리를 설정하는데 더 많은 시간을 쓰는것이 사실이다. 그도 그럴것이, 이미 react에 webpack build & bundling 기능이 내포되어 있고 nextjs에서도 똑같이 지원하니 말이다. 역시 이래서 모던 프레임워크라고 불리나 보다.

마치며

웹팩이라고는 들어봤어도, 그 실체에 대해서는 잘 알고 있지 못했다. 그냥 리액트 프로젝트를 생성하면 같이 딸려오는 존재 정도로만 인식하고 있었으니 말이다. 그 웹팩이 자동화 도구와 lazy loading과 같은 최적화 및 개발 효율성을 도와주는 역할을 한다는건 이 글을 쓰면서 처음 알게 되었다.

 

모던 프레임워크가 더욱 다루기 쉬워지고, 그에 맞춰서 강의나 학원들은 이미 설정되어 있는 프로젝트만 가지고 진행하는 경향이 있는것 같다. 많은 사람들이 초기 설정 단계에서 좌절하고 무릎꿇으니 이해는 하겠다만, 이런 중요한 라이브러리가 프로젝트를 받치고 있다는걸 모른채로(작동방식을 모른채로) 개발을 하는것과, 빌드 과정과 최적화가 실제로 어떤 원리로 진행되고 그 과정을 깨우치고 개발하는것은 정말 큰 차이가 있을것 같다. 아마 그게 비범한 개발자와 평범한 개발자의 차이점이 아닌가 싶다. 잘 돌아가는 것을 뜯어보고 분석하는 성격 말이다.

레퍼런스

Introduction | 웹팩 핸드북
꾸생의 DevLog - React 리액트 webpack & babel 설정하기
React 개발 환경을 구축하면서 배우는 웹팩(Webpack) 기초
React Webpack이란?