본문으로 바로가기

Webpack Guide for beginner #1

category Web Tech/Webpack 2019.08.05 07:43

Webpack 이란 무엇인가?


Webpack 공식 사이트 소개 이미지


Webpack 페이지에서 소개하듯이 웹팩은 모듈 번들러(Module Bundler)입니다.
그렇다면 번들러(Bundler)란 무엇일까요?
번들러는 소프트웨어 및 일부 하드웨어와 함께 작동하는데 팔요한 모든 것을 포함하는 패키지라고 정의하고 있습니다.   이를 프로그래밍적으로 접근하자면 번들러란 필요한 의존성에 대해 정확하게 추적하여 해당하는 의존성들을 그룹핑 해주는 도구라고 할 수 있습니다.

다시말해, Webpack 은 공식 사이트 이미지에서 소개하듯이 웹페이지를 동작시키기 위한 서로 연관 관계가 있는 웹 자원(웹앱 애플리케이션의 구성파일)들인 js, css, img, webfont, etc.. 와 같은 구성파일들의 관계들을 Webpack 에서 인식하여 번들링하게 되면 최종적으로 기존의 원본 파일들을 압축, 축소하여 최적화된 스택틱 자원(파일)으로 전환해주는 작업을 하게 되는데 이러한 작업을 번들링이라고 합니다.


Module Bundler는 각각의 모듈들에 대해 의존성 관계를 파악하여 그룹핑해주는 것으로,

webpack 은 의존성들의 관계들을 묶으면서 여러가지 기능들을 자동 수행시켜주는 도구입니다.



Webpack 사용 이유 및 배경과 장점은?

Webpack 사용 이유 및 배경

이미 언급했 듯이 웹페이지는 수 많은 구성요소로 이루어져 있으며, 기본적인 html, js, css 파일 외에도, 웹폰트, 이미지, json 데이터 등등 수 많은 파일들을 요청하고 받아와야 합니다. 이 수 많은 파일들은 하나의 요청이 끝나야 다음 요청을 보낼 수 있기 때문에 요청이 많을 수록 비효율적일 수 밖에 없습니다. 그래서 요청수를 줄이기 위해 이미지는 스프라이트화 시켜서 한 번만 받고 Gulp, Grunt 와 같은 번들러로 js, css 파일을 하나로 합치는 작업을 수행하기도 합니다. 기존 번들러들도 개발 편의성과 최적화에 도움이 되지만 이보다 더 뛰어난 Webpack 이 등장하게 됩니다.

그리고 요즘에 널리 사용되는 최신 프론트엔드 프레임워크 중에는 React, Angular, Vue 등이 있는데, 이런 최신 프레임워크를 사용하다 보면
자연스럽게 웹팩을 접하게 됩니다.
이러한 최신 프론트엔드 프레임워크는 서버사이드 템플릿 시대를 지나 단일 페이지 애플리케이션(Single Page Application, SPA) 개발이 인기를 얻으면서 나타나게 되었으며 그로 인해 자바스크립트의 코드량이 기하급수적으로 증가하게 되었습니다.

이런 코드량은 많게는 수천, 수만 줄의 자바스크립트 코드에서 특정 코드를 찾아 수정하기란 여간 쉬운 일이 아닐 것입니다.
그렇기 때문에 개발 초기 단계에 API 기능과 UI 컴포넌트에 맞도록 자바스크립트 코드를 모듈별로 분리하게 되었습니다.
하지만, 분리해 놓은 여러 개 혹은 수많은 자바스크립트 파일들을 하나씩 따로 로드해 온다면 웹페이지 로딩시 커다란 속도 저하 문제가 발생할 여지가 농후합니다.   그래서 이런 웹팩과 같은 모듈 번들러를 통해 수많은 자바스크립트 파일들을 하나의 JS 파일로 번들링하는 작업이 필요하게 되었고, 프로젝트의 성능 향상과 보다 나은 구조, 개발자의 쾌적(?)한 환경을 위해서 웹팩의 사용이 중요 해졌습니다.

 

 

Webpack 장점

Webpack 과 같은 유사한 작업을 하는 도구들 중에는 Browserify, Grunt, Gulp 등이 있습니다.


그렇다면 왜 위 도구들보다 Webpack 이 나은지 그리고 무슨 차이가 있을까요?

기존에도 웹 개발 생산성을 높이기 위해 Grunt, Gulp 와 같은 도구들로 개발 라이프 사이클을 줄일 수 있었지만 그에 더 나아가 웹팩은 모듈 의존성까지 관리해주는 특징이 있습니다.

기존 task runner 인 Grunt, Gulp 는 오로지 리소스들에 대한 툴로 사용되며 dependency graph 에 대한 개념이 없습니다. WebpackPackage Bundler(의존성,종속성을 가진 애플리케이션 모듈을 정적인 소스로 재생산) 이며 Gulp, Grunt 는 Task Runner(반복 가능한 특정 작업을 자동화) 입니다. 다시 말해, Task Runner 는 그저 미리 정의해 놓은 어떠한 작업을 실행하는 것이고 Package Bundler 는 말 그대로 어떤 소스들을 하나의 패키지화 하는 것입니다. Grunt, Gulp 는 일련의 태스크를 정의하고 실행하면 번들링도 할 수 있는 도구이지만, webpack 은 애초부터 의존성 관리까지 포함한 번들링을 위해 나온 도구입니다.
다시말해, 연필을 계속해서 뾰족하게 깎다보니 제법 이도 쑤실 수 있게 된게 걸프나 그런트고 처음부터 이쑤시개라고 이름달고 나온게 웹팩입니다.
더 자세한 내용은 Webpack VS Gulp , Grunt or Gulp vs Webpack 의 차이 를 참고해 보기 바랍니다.

 

초기의 ES5 자바스크립트 코드 기반의 모듈 관리라는 것은 언어 자체적으로 지원이 되지 않았기 때문에 복잡한 웹 앱을 관리하기 위해 자바스크립트 파일을 모듈 단위로 관리하는 AMD, CommonJS, ES6(Modules) 기타 모듈로더들이 등장했었고 이를 모두 통합해서 사용할 수 있는 도구가 Webpack 입니다. 기존 도구들로도 수많은 라이브러리를 연동해서 모듈로더를 사용하고 성능 최적화를 시킬 수 있었으나 Webpack 은 좀더 나아가 가독성이나 다수 모듈 미병행 처리등의 약점을 보완하면서 기존 모듈로더들의 장점을 수용하여 상용화된 서비스를 제공해 준다는 장점이 있습니다.

그렇기 때문에 크고 복잡한 다양한 리소들이 들어있는 프로젝트에는 Webpack 을 사용하는 것이 최상의 선택이 될 수 있습니다.
그리고 Browserify 는 Webpack 과 유사한 도구이지만, 속도면에서 Webpack 이 더 우월하다고 평가받고 있습니다.

 

자바스크립트 모듈화 이슈

html
<script src="/js/vendor/vendor01.js"></script>
<script src="/js/module01.js"></script>
<script src="/js/lib/library01.js"></script>
<script src="/js/module02.js"></script>
<script src="/js/module03.js"></script>

위 코드는 일반적인 방식인 <script> 태그로 자바스크립트 모듈화를 하는 예제로 이와 같이 사용할 경우에 나타날 수 있는 문제점으로 여러 개의 파일을 로딩하더라도 같은 스코프를 공유하기 때문에 전역 변수의 충돌과 라이브러리 로딩 순서에 따른 이슈, 복잡도에 따른 관리상 문제를 야기할 수 있습니다.



Webpack 철학

  • 모든 것은 모듈이다.

    모든 웹 자원(js, css, html, img, webfont...)을 모듈 형태로 로딩이 가능합니다.
    보통 css, html 을 자바스크립트로 로딩( <script src="index.html"></script> )이 되지 않기 때문에 모듈로 보기 어렵습니다.
    하지만 Webpack 은 css, html, images 등을 자바스크립트로 로딩이 가능하도록 지원하고 있습니다.

  • 초기에 불필요한 것들을 모두 로딩(예를 들어, Lazy 로딩처렁)하지 않고, 필요할 때에 필요한 것만 로딩하여 사용



  • 다른 module bundler에 비해 performance 가 우수
  • Loader 가 존재하여 다른 리소스를 순수 JavaScript 로 변환하고 모든 리소스에 대한 모듈을 구성
  • 기존 모듈 로더들과의 차이점으로 모듈 간의 관계를 chunk 단위로 나눠 필요할 때 로딩

    chunk(청크)란 하나의 덩어리라는 뜻으로, 코드를 쪼개는(스플리팅) 과정에서 생성되는 자바스크립트 파일 조각을 의미

  • 다양한 플러그인을 제공 & 3rd-party library 에 대해 모듈로 통합하는 기능을 제공
  • 모듈 단위로 개발이 가능
    • 모듈 단위 코딩은 가독성과 유지보수 효율을 높입니다.
    • 스코프에 신경 쓰지 않고 개발이 가능
    • 라이브러리 종속 순서를 신경 쓰지 않아도 됩니다.
  • ES6+ 자바스크립트를 사용

    babel 을 사용하여 es2015(ES6+)와 같이 브라우저에서 지원되지 않는 javaScript code 를 변환하여 사용하는데 도움

  • LESS, SASS(SCSS) 등 사용 가능



Webpack 개발환경 설정에 앞서 알아야 할 것들

웹팩을 사용하기 위해서는 개발환경 설정에 필요한 선행 지식들이 필요합니다.

개발 환경 설정에 필요한 Node.js, NPM(Node Package Manager), CLI(Command Line Interface) 등을 학습한 후에 본격적인 웹팩 설정에 대해 알아보도록 하겠습니다.


Node.js

웹팩을 포함한 여러 빌드시스템들은 node.js 의 스트림 기능을 기반으로 하고 있기 때문에 node.js 가 설치되어 있어야 합니다.

먼저 자신의 운영체제에 적합한 node.js 설치를 하도록 합니다.

Webpack 을 포함한 대부분의 번들러에 필요한 구성 파일들, 그리고 라이브러리등의 기타 수많은 파일들은 Node.js 를 설치(NPM 포함)해야 필요한 구성 파일들의 패키지(꾸러미)를 다운 받아서 설치하고 구성할 수 있습니다.

그리고나서 Node.js 의 npm 명령어을 이용하여 패키지를 다운받거나 실행하는 작업들을 실행해 나갈 수 있습니다.

nodejs 사이트는 운영체제를 탐색하여 node.js 설치 프로그램을 다운받을 수 있도록 하고 있기 때문에 해당 OS별 실행프로그램을 선택할 필요가 없을 것입니다. 설치 과정은 여기서 다루지 않습니다.


Node.js 는 명칭에서도 표현하고 있듯이 자바스크립트를 개발 언어로 사용하는 소프트웨어 플랫폼입니다.

구글 크롬 웹브라우저와 안드로이드 웹브라우저에 탑재된 V8 엔진 위에서 동작하고, 프론트측이 아닌 서버측에서 실행되는 서버사이드 언어(Server Side Language)입니다.

그리고 설치 과정 중에 "npm package manage" 라는 항목이 있을 것입니다.

이를 NPM(node package manager)라고 하는데 Node.js 기반의 패키지 모듈들을 관리하는 도구입니다.

Node.js 설치를 끝내셨다면 운영체제를 다시 시작해야 Node.js 가 정상적으로 작동합니다.


Node.js를 설치가 끝났다면 CLI 에서 node --version 명령어로 Node.js 가 설치되었는지 아래와 같이 확인하도록 합니다.

$ node -v
v8.11.3

--version-v로 줄여서 사용할 수 있으며, 위와 같이 버전이 출력되었다면 올바르게 node.js 설치가 된 것입니다.

$ 기호는 명령 줄 인터페이스에서 사용하라는 상징 기호의 의미로 $ 기호는 타이핑하지 않습니다.

Mac 에서 명령어 입력시 실행이 안된다면 sudo node -v 로 맨 앞에 sudo 를 붙여주셔야 합니다.
sudo 는 super do 를 의미합니다.



CMD 는 Window 운영체제에서 기본으로 제공하는 명령어 기반 인터페이스(CLI) 도구입니다.

CMD 는 명령 프롬프트(Command Prompt)로, 실행 파일인 cmd.exe를 의미하고, 명령어 인터페이스 도구로는 윈도우 기반의 cmd, powershell 등이 있으며, Mac 운영체제에서 사용되는 터미널(terminal) 등이 있습니다.

명령 줄 인터페이스(CLI, Command line interface) 또는 명령어 인터페이스는 텍스트 터미널을 통해 사용자와 컴퓨터가 상호 작용하는 방식을 뜻하고, 이 같은 인터페이스를 제공하는 프로그램을 명령 줄 해석기(Command Line Interpreter) 또는 셸(shell)이라고 부릅니다.

이를테면, 유닉스 셸(sh, ksh, csh, tcsh, bash 등)과 CP/M, 도스의 command.com("명령 프롬프트") 등이 있습니다.

shell 에 대한 내용은 shell, bash, zbash의 간단 개념정리 좌표를 참고하기 바랍니다.

참고로 CLI 의 명령어는 운영체제마다 다르므로 주의하시기 바랍니다.


알아두면 좋은 기본 CLI 명령어

Window 운영체제일 경우 cmd 창에서 실행되지 않는 명령어가 있기 때문에 powershell, git bash 에서 사용하길 권장드립니다.

$ cd Desktop
# 현재 위치에서 다른 디렉터리로 이동하기 위해서 cd(Change Directory) 명령어를 입력한 후 디렉터리 이름을 입력

$ cd ..
# 현재 디렉터리에서 바로 상위 디렉터리로 이동하기 위해서 cd 명령어 뒤에 이중 점(..)을 입력

$ cd ../..
# 상위에서 상위의 디렉터리로 이동하려 할때는 슬래시(/)로 구분하여 이중 점을 두번 입력

$ c:\
# c 드라이브로 이동

$ d:\
# d 드라이브로 이동

$ mkdir study
# make directory의 약어로 새로운 디렉터리를 생성하고자 할때 사용

$ mkdir css js images include
# 생성할 디렉터리 이름을 공백으로 구분하여 나열하면 여러 개의 폴더를 한 번에 생성 가능

$ ls
# ls (List의 약어) 명령어를 사용하여 현재 위치에서의 디렉터리에 들어있는 파일 목록들을 확인
# 파일 이름이나 폴더이름들은 가로 방향으로 나열되면서 출력됨

$ ls -l
# ls 명령어 뒤에 옵션 플래그인 대쉬(-)와 소문자 l 을 입력하여 실행하게 되면
# 파일 사용권한, 소유자, 그룹, 크기, 날짜, 시간등의 상세한 정보가 출력

$ ls -a
# 플래그 -a 는 숨겨진 파일까지 표시

$ ls -al
# -a, -l 옵션 플래그를 사용하면 나오는 정보가 출력

$ ls css/
$ ls js/
# 현재 디렉터리의 하위 디렉터리 파일 목록을 확인하고자 할 때 ls 명령어 뒤에 하위 디렉터리 이름을 입력

$ pwd
# pwd (print working directory) 명령어는 현재 작업 중인 디렉터리의 절대 경로를 출력

$ clear
# 의미대로 그동안 실행했던 명령어와 명령어에 따른 결과 출력들이 깨끗하게 삭제
# Window cmd 에서는 cls

$ exit
# exit 를 입력하면 CLI 도구가 종료



NPM(Node Package Manager)

앞서 설명했듯이 npm 은 패키지를 다운로드, 업데이트 그리고 실행하는 작업들을 할 수 있습니다.


  • JS 개발자들이 편하게 개발할 수 있도록 JS 라이브러리들을 모아놓은 열린 공간
  • Gulp, Grunt, Webpack 모두 node 기반으로 NPM 을 사용하여 필요 라이브러리들을 로딩
  • Front-end web apps, mobile apps, routers 라이브러들이 존재
  • 재사용 가능한 code 를 module, package 라고 호칭
  • package.json : 해당 package 에 대한 파일 정보들을 포함하고 있음

    npm 으로 다운받거나 업데이트하거나 하는 모든 패키지 정보들이 들어가 있는 구성(configuration) 파일

  • npm 공식사이트 에서 keyword 로 검색이 가능

NPM 명령어

npm 명령어 중에 자주 사용하는 명령어을 알아보겠습니다.

먼저 node -v 버전을 확인했듯이 npm 버전을 확인해 봅니다.

$ npm -v
5.6.0

package.json 생성

일반적으로 Webpack 을 구성하기 전에 프로젝트의 node modules 를 관라하기 위해 package.json 을 설정해야 합니다.

아래와 같이 작성해 봅니다.

$ npm init

NPM 명령어인 npm init 는 초기화(initial) 명령어로 사용자에게 질문하여 대답을 입력받는 형식으로 package.json 파일을 생성하게 됩니다.

package.json 은 배포(Publish)할 때 반드시 필요한 파일입니다.

package.json 파일을 직접 생성할 수도 있겠지만, 처음 사용할 때는 초기화 명령어로 생성하는 것이 일반적이고 편리합니다.

이름(name)을 시작으로 version, description(설명) 등의 여러 정보를 사용자에게 물어보는데 값을 입력할 때는 제외하고는 Enter를 눌러 넘어값니다.

마지막에 Is this ok? (yes) 라는 질문이 나타나는데, Enter 를 누르면 package.json 파일이 생성될 것입니다.

그리고 package.json 파일을 열면, 질문에 답변한 내용이 문서에 포함되어 있으며, 문서 내용 중 필요없는 부분은 삭제하여 정리할 수 있습니다.


필자는 아래와 같은 package.json 파일이 생성되어 있습니다.



위와 같은 기본(default) 정보만 필요하여 위의 일련의 과정을 생략하고 package.json 를 생성하고자 할 경우에는
플래그(flag) --yes 또는 약어인 -y 를 사용할 수 있습니다.

기존 기본 정보만을 담고 있는 package.json 을 생성하셨다면 삭제 후에 아래와 같이 다시 실행해 보세요.

$ npm init -y

위와 같이 실행하면 기존 package.json 파일과 동일하게 기본 정보만을 담고 있는 package.json 의 초기화를 좀더 쉽게 할 수 있습니다.



패키지 설치 및 업데이트

npm 으로 프로젝트에서 사용할 node modules 설치 및 package.json 업데이트를 할 수 있습니다.

예를 들어, npm install 패키지명 --save-dev 를 하게 되면 해당 패키지를 npm 저장소로부터 다운받는 역할을 하게 됩니다.

현재까지도 인기있는 라이브러리인 jquery 를 다운받아보도록 하겠습니다.

$ npm install jquery --save

npm 을 실행한 결과 package.json 의 dependencies 로 jquery 가 추가되어 있는 것을 확인하실 수 있으면, node_modules 라는 폴더가 생기고 그 하위 폴더에 jquery 관련 파일이 로드되어 있는 것을 확인하실 수 있습니다.


그리고 install 이란 명령어 대신 축약어로 i 를 사용하실 수 있습니다.

$ npm i 패키지명

위와 같이 jquery 를 다운받은 것은 지역설치를 한 것입니다.

여기서 전역(global) 설치와 로컬(local) 설치에 대해 알아볼 필요가 있습니다.


Global 설치 Vs Local 설치

위의 jquery 모듈을 설치한 것은 현재 프로젝트의 로컬 폴더 node_modules 하위 디렉토리의 로컬 설치를 하게 되는 것이지만, global 로 설치하는 것은 운영체제마다 설치되는 공간은 다르겠으나 운영체제마다의 시스템 레벨 내에서의 패키지를 전역적으로 설치하게 됩니다.

$ npm i webpack --global

위 명령을 실행하게 되면 webpack 명령어를 어느 디렉토리에서나 수행할 수 있습니다.

다른 디렉토리로 이동하여 해당 디렉토리 내에서 아래와 같은 명령어를 실행하면 webpack 버전을 확인하실 수 있습니다.

다시 말해, 전역 설치는 간혹 패키지를 현재 디렉토리 뿐만 아니라 어디서나 실행할 수 있도록 설치해야 할 경우들이 있을 수 있기 때문입니다.

$ webpack --version

즉, CLI 에서 어느 디렉토리에서나 일반적(?) 명령을 진행하고자 할 경우에는-global(-g) 로 설치하면 됩니다.


그리고 webpack.config.js 파일에서 require() 로 가져오려면 local install 로 설치하여 webpack 을 사용할 수 있습니다.

const webpack = require('webpack');

NodeJS 에서는 require 메서드를 통해 외부 모듈을 가져올 수 있습니다.



npm install --save Vs --save-dev

--save 는 애플리케이션을 구동하기 위해 필요한 모듈과 라이브러리를 설치하는 경우에 사용합니다.

다시말해, 제이쿼리를 사용한다고 했을 때 실제 서비스에서 앱을 구동하기 위해 필요한 라이브러리기 때문에 install 할 때
--save 플래그를 사용해야 합니다.

// package.json
"dependencies": {
    "jquery": "^3.4.1"
}

앞서 jquery 를 설치했다면 위와 같이 package.json 에 dependencies(의존성) 로 제이쿼리 라이브러리가 추가된 것을 확인하실 수 있습니다.


그리고 --save-dev 는 애플리케이션 개발시에만 필요한 모듈과 라이브러리를 설치하는 경우에 사용합니다.

예를 들어 live reloading, build tool 과 같이 실서비스에서 앱이 구동하는데 필요한 라이브러리가 아니라 개발 편의성을 위해 필요한 유틸리티성 도구로 개발에 도움을 받기 위해 사용하는 경우에 사용하는 것입니다.

아래에서 gulp 를 설치해 보도록 하겠습니다.

$ npm i gulp --save-dev
// package.json
"dependencies": {
    "jquery": "^3.4.1"
  },
"devDependencies": {
    "gulp": "^4.0.2"
}

package.json 을 확인해 보면 devDependencies(개발 의존성)에 gulp 가 추가된 것을 확인하실 수 있습니다.

--save-dev 플래그를 추가하면 디펜던시들을 devDependency 로써만 설치하게 되는데, 이 옵션을 주는 이유는 Gulp 와 관련 디펜던시들은 애플리케이션 개발 과정까지만 필요하기 때문입니다.

나중에 Gulp 의 플러그인들을 설치할 때에도 같은 --save-dev 옵션을 주어야 합니다.


dependency(의존성)란?

제이쿼리를 사용한다고 했을 경우 유저는 먼저 제이쿼리를 불러온 다음에 제이쿼리 문법을 사용할 것입니다.

이렇듯 내가 사용하는 스크립트가 제이쿼리에 의존하고 있다면 제이쿼리에 의존성을 가지고 있다고 할 수 있습니다.

그래서 모듈을 설치(npm install)할 때 --save-dev 명령어를 입력하면 개발할 때만 의존(devDependcies)하는 모듈로 기술됩니다.

보통 개발 당시에만 gulp 의 플러그인 패키지가 필요하고 배포(Production)시에는 gulp 패키지 모듈은 서비스를 받는 사용자에게 필요없기 때문에 개발할 때만 의존하도록 --save-dev 플래그를 사용합니다.

만약에 $ npm install gulp --save와 같이 -dev 를 생략하고 명령어를 입력하면 배포할 때도 의존하는 모듈로 기술됩니다.

--save-dev 는 -D 로 줄여서, --save 는 -S 로 줄여서 사용할 수 있습니다.


$ npm i gulp -D



Conclusion

지금까지 Webpack 에 대한 이해와 이를 사용하기 위한 기본적인 선행학습을 진행해 보았습니다.

다음 챕터부터는 Webpack 환경 구성과 개발에 필요한 모듈과 라이브러리를 단계적으로 설치하면서 Webpack 을 학습해 보도록 하겠습니다.



Jaehee's WebClub



'Web Tech > Webpack' 카테고리의 다른 글

Webpack Guide for beginner #2  (2) 2019.08.05
Webpack Guide for beginner #1  (0) 2019.08.05

댓글을 달아 주세요