본문 바로가기
Dev/Webpack

[Webpack] Webpack

by dev_jsk 2020. 9. 15.
728x90
반응형

Webpack

최신 프론트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러(Module Bundler)

모듈(Module)

프로그래밍 관점에서 특정 기능을 갖는 작은 코드 단위

모듈 번들러(Module Bundler)

웹 애플리케이션을 구성하는 자원(HTML, CSS, Javascript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구

Webpack의 등장 배경

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

입문자 관점에서 고안된 자바스크립트의 변수 유효 범위는 기본적으로 전역 범위를 갖는다. 최대한 넓은 변수 범위를 갖기 때문에 어디에서도 접근하기가 편리하다.

 

전역 유효범위로 인한 문제점

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

// main.js
var num = 20;
function getNum() {
  console.log(num);
}

결과

<!-- index.html -->
<html>
  <head>
    <!-- ... -->
  </head>
  <body>
    <!-- ... -->
    <script src="./app.js"></script>
    <script src="./main.js"></script>
    <script>
      getNum(); // 20
    </script>
  </body>
</html>

결과는 20. app.js에서 선언한 num변수는 main.js에서 다시 선언하고 20을 할당했기 때문.

이러한 문제점은 실제 복잡한 애플리케이션을 개발할 때 발생한다. 변수의 이름을 모두 기억하지 않은 이상 변수를 중복 선언하거나 의도치 않은 값을 할당할 수 있다.

웹 개발 작업 자동화 도구(Web Task Manager)

프론트엔드 개발 및 웹 서비스 개발, 배포 시 하는 작업으로는

  • 코드 수정 후 저장 및 브라우저 새로고침
  • HTML, CSS, JS 압축
  • 이미지 압축
  • CSS 전처리기 변환

등이 있는데 이러한 일들을 자동화 하는 도구가 필요하기 때문. 그리하여 등장한 것이 Grunt, Gulp 같은 도구

웹 애플리케이션의 빠른 로딩 속도와 높은 성능

일반적으로 특정 웹 사이트를 접근할 때 5초 이내로 웹 사이트가 표시되지 않으면 대부분의 사용자들은 해당 사이트를 벗어나거나 집중력을 잃게 되는데 이와 같은 문제(웹 사이트의 로딩 속도 느린 현상)를 해결하기 위해 여러 방법이 있는데 대표적인 노력이 브라우저에서 서버로 요청하는 파일 숫자를 줄이는 것이다.

요청 파일 숫자를 줄이기 위해선 Web Task Manager를 이용하여 파일들을 압축, 병합하는 작업들을 진행하는 방법이나 초기 페이지 로딩 속도를 높이기 위해 나중에 필요한 자원들은 나중에 요청하는 레이지 로딩(Lazy Loading) 방법을 사용할 수 있다.

 

Webpack은 기본적으로 필요한 자원은 미리 로딩하는게 아니라 그 때 그 때 요청하자는 철학을 갖고 있다.

Webpack으로 해결하려는 문제

Webpack의 등장 배경에서 보았듯이 Webpack에서 해결하고자 하는 문제점은 다음과 같다.

  • 자바스크립트 변수 유효범위
  • 브라우저별 HTTP 요청 숫자의 제약
  • 사용하지 않는 코드의 관리
  • Dynamic Loading & Lazy Loading 미지원

자바스크립트 변수 유효 범위 문제

변수 유효 범위의 문제점을 ES6Modules 문법과 Webpack의 모듈 번들링으로 해결

브라우저별 HTTP 요청 숫자의 제약

TCP 스펙에 따라 브라우저에서 한 번에 서버로 보낼 수 있는 HTTP 요청 숫자는 제약되어 있다.

브라우저 최대 연결 횟수
Internet Explorer 7 2
Internet Explorer 8 ~ 9 6
Internet Explorer 10, 11 8, 13
Chrome 6
Safari 6
Firefox 6
Opera 6
Android, iOS 6

따라서 HTTP 요청 숫자를 줄이는 것이 웹 애플리케이션의 성능을 높여줄 뿐만 아니라 사용자가 사이트를 조작하는 시간을 앞당겨 준다.

※ 클라이언트에서 서버에 HTTP 요청을 보내기 위해서는 먼저 TCP/IP가 연결되어야 한다.

 

Webpack을 이용해 여러 개의 파일을 하나로 합치면 브라우저별 HTTP 요청 숫자 제약을 피할 수 있다.

Dynamic Loading & Lazy Loading 미지원

Require.js와 같은 라이브러리를 쓰지 않으면 동적으로 원하는 순간에 모듈을 로딩하는 것이 불가능 했다. 그러나 이젠 Webpack의 Code Splitting기능을 이용하여 원하는 모듈을 원하는 타이밍에 로딩할 수 있다.

Webpack 주요 속성

Entry

Webpack에서 웹 자원을 변환(= 빌드, 컴파일, 번들링) 하기 위해 필요한 최초 진입점이자 자바스크립트 파일 경로

module.exports = {
  entry: './src/index.js'
}

// 아래와 같이 엔트리 포인트를 분리하는 경우
// 싱글 페이지 애플리케이션이 아닌 특정 페이지로 진입했을 때
// 서버에서 해당 정보를 내려주는 형태의 멀티 페이지 애플리케이션에 적합
module.exports = {
  entry: {
    login: './src/LoginView.js',
    main: './src/MainView.js'
  }
}

Output

Webpack을 돌리고(빌드, 변환) 난 결과물의 파일 경로

var path = require('path');

module.exports = {
  output: {
    // filename은 필수
    filename: 'bundle.js',
    // path.resolve()
    // : 인자로 넘어온 경로들을 조합하여 유효한 파일 경로를 만들어 주는 Node.js API
    path: path.resolve(__dirname, './dist')
  }
}

Output filename Options

1. 결과 파일 이름에 entry 속성을 포함하는 옵션

module.exports = {
  output: {
    filename: '[name].bundle.js'
  }
};

2. 결과 파일 이름에 Webpack 내부적으로 사용하는 모듈 ID를 포함하는 옵션

module.exports = {
  output: {
    filename: '[id].bundle.js'
  }
};

3. 매 빌드시 마다 고유 해시 값을 붙이는 옵션

module.exports = {
  output: {
    filename: '[name].[hash].bundle.js'
  }
};

4. Webpack의 각 모듈 내용을 기준으로 생성된 해시 값을 붙이는 옵션

module.exports = {
  output: {
    filename: '[chunkhash].bundle.js'
  }
};

Loader

Webpack이 웹 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 자원(HTML, CSS, images, 폰트 등)들을 변환할 수 있도록 도와주는 속성

module.exports = {
  module: {
    rules: [
      // test : 변환할 파일 형식, use : 변환할 파일에 지정할 loader
      // loader는 오른쪽에서 왼쪽 순으로 적용
      {test: '', use: ''},
      {test: '', use: ''},
      ...
    ]
  }
}

자주 사용하는 Loader 종류

  • Style Loader : Webpack 안에 들어간 style 코드를 head안에 in-line 코드로 넣어준다.
  • CSS Loader : CSS가 Webpack 안으로 들어갈 수 있게 한다.
  • Babel Loader : Webpack이 모듈을 번들링 할 때 Babel을 사용하여 ES6+ 코드를 ES5 코드로 트랜스파일링 하도록 한다.
  • Sass Loader : Sass/SCSS 파일을 CSS 파일로 변환
  • File Loader : 파일 복사
  • Vue Loader : 뷰 컴포넌트를 자바스크립트 모듈로 변환
  • TS Loader : TypeScript를 컴파일 하여 JS 번들 생성

Plugin

Webpack의 기본적인 동작에 추가적인 기능을 제공하는 속성

module.exports = {
  plugins: [
    // 배열에는 생성샂 함수로 생성한 객체 인스턴스만 추가 가능
  ]
}

자주 사용하는 Plugin 종류

Loader와 Plugin 비교

Loader는 파일을 해석하고 변환하는 과정에 관여하는 반면, Plugin은 해당 결과물의 형태를 바꾸는 역할

Webpack Concepts Review

  • Entry 속성은 Webpack을 실행할 대상 파일, 진입점
  • Output 속성은 Webpack의 결과물에 대한 정보를 입력하는 속성. 일반적으로 filenamepath를 정의
  • Loader 속성은 CSS, 이미지와 같은 비 자바스크립트 파일을 Webpack이 인식할 수 있게 추가하는 속성. 오른쪽에서 왼쪽 순으로 적용
  • Plugin 속성은 Webpack으로 변환한 파일에 추가적인 기능을 더하고 싶을 때 사용하는 속성. Webpack 변환 과정 전반에 대한 제어권을 갖고 있음

참고

webpack.js.org/concepts/

 

Concepts | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

 

728x90
반응형

'Dev > Webpack' 카테고리의 다른 글

[Webpack] 설정파일 살펴보기  (0) 2020.09.17
[Webpack] Dev Server  (0) 2020.09.16
[Webpack] ES6 Modules  (0) 2020.09.16
[Webpack] NPM  (0) 2020.09.14

댓글