# 8. 웹팩

## 8 웹팩

정적자원을 묶어서 하나의 파일또는 여러개의 파일로 번들링해주는 도구

* 초기로딩 타임을 줄여준다
* 정적자원들까지 모듈화가 가능
* Babel, TS 같은 트랜스파일러와 손쉽게 통합

  로더 기능 활용
* HMR (Hot Module Replacement)

  변경사항을 자동으로 번들링 및 페이지 자동갱신
* 댜앙한 로더 지원

  번들링전 전처리기 기능 제공, 정적자원 변환, ES6 트랜스파일링 등
* 다양한 플러그인 제공

  ex)UglifyJsPlugin -> 코드 난독화 및 미니파이(축소)

### Webpack 구성

4가지 설정이 필요.

1. **entry**

   `진입점`, 단일 : 문자열, 복수 : 객체타입으로 `파일 경로 지정`
2. **output**

   번들링된 결과물,&#x20;

   * `path옵션` : output 경로
   * `filename` : 결과물의 파일명
   * `publicPath` : 웹서버에서 이용될 때의 사용 경로 지정
3. **module**

   프로젝트 내부에서 사용하는 모듈의 수행방법 명시&#x20;

   1. rules : 룰을 하나하나 지정
      1. test : /.js$/ -> js 끝나는 파일명에 대해 테스트 수행
      2. loader : 'babel-loader' -> 바벨을 이용해 트랜스파일 하도록 지정
      3. exclude : /node\_modules/  -> 트랜스파일링에서 node\_modules는 제외
4. **plugins**

   빌드에서 추가작업을 하기 위함

   ex) UglifyJsPlugin : 코드 난독화 및 사이즈 축소 작업 실행

### 구성예제

#### 모듈 설치

* Webpack 전역 설치

  ```bash
  sudo npm i -g webpack
  ```
* Webpack 개발 의존성 설치

  ```bash
  npm i --save-dev webpack
  ```
* Babel 설치

  ```bash
  npm i --save-dev babel babel-core babel-loader babel-preset-es2015
  ```

  **Webpack 설정**
* webpack.config.js

  ```javascript
  var webpack = require('webpack');
  module.exports = {
    entry: {
      main: __dirname + '/src/index/js'
    },
    output: {
      path: __dirname + '/public/dist/',
      filename: '[name].js',
      publicPath: '/dist'
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          loader: 'babel-loader',
          exclude: /node_modules/
        }
      ]
    },
    plugins: [
      new webpack.optimize.UglifyJsPlugin()
    ]
  };
  ```
* package.json

  ```javascript
  {
    ...
    "scripts": {
      "build": "webpack",

    },
    ...
  }
  ```

#### 예제 코드

* JS

  ```javascript
  // index.js
  // import calc from "./util/utility";
  const calc = require('./util/utility');
  let x = 5;
  let y = 10;
  let str = `<h2>${x}+${y} = ${calc.add(x, y)}</h2>`;
  document.getElementById('app').innerHTML = str;
  console.log(str);  

  // util/utility.js
  let cacl = {
    add(x, y) {
      return x + y;
    },
    multiply(x, y) {
      return x * y;
    }
  };

  module.exports = cacl;  
  //export default calc
  ```
* HTML

  \`\`\`html \<!DOCTYPE html>

  Title

  &#x20;\</body>

  &#x20;\</html>\
  \`\`
* **build**

  ```bash
  $ npm run build  # 첨에하니 에러남
  ```

  * webpack-cli

    ```bash
    npm i -D webpack-cli # -D 개발환경에서만 실행, 필요하다해서 깔음
    ```
  * **new webpack.optimize.UglifyJsPlugin() 삭제됨... 실행안됨..**

    참고 : <https://webpack.js.org/configuration/optimization/> &#x20;
  * **mode 설정** `Webpack 버전4부터` 조금 바뀐거 같아서 공식문서 ㄱ, `mode 설정이 필수` 참고 : <https://webpack.js.org/configuration/mode/> 1. development 2. production 3. none

    ```javascript
    // webpack.config.js 추가 설정 
    module.exports = {
      ...
      optimization :{
        minimize: true
      },
      mode: 'none'

      ...
    }
    ```

    * 수정한 webpack.config.js

      ```javascript
      var webpack = require('webpack');
      module.exports = {
      entry: {
        main: __dirname + '/src/index.js'
      },
      output: {
        path: __dirname + '/public/dist/',
        filename: '[name].js',
        publicPath: '/dist'
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/
          }
        ]
      },
      plugins: [],
      mode: 'none',
      optimization: {
        minimize: true
      }
      };
      ```
  * **bable 버전 6.x -> babel-loader 7.x 필요..** `8.x로하니 에러남` `babel-loader 버전 8.x -> 7.x로 변경`

    ```javascript
    {
      ...
      "devDependencies": {
        "babel": "^6.23.0",
        "babel-core": "^6.26.3",
        "babel-loader": "^7.1.5",
        "babel-preset-es2015": "^6.24.1",
        "webpack": "^4.39.2",
        "webpack-cli": "^3.3.7"
      }
      ...
    }
    ```
* build 결과물 (main.js)\
  [main.js](https://app.gitbook.com/s/-M1ciKJvsGgeAKQBeHlJ/javascript/vue.js/main.js)
* **변경사항 자동 갱신**\
  **Node, Express 기반 개발용서버**, `HMR` 기능 자체 제공 -> 빠른 개발, **수정 및 npm run build 작업x**
  * **webpack-dev-server 설치** &#x20;

    ```bash
    $ npm i --save-dev webpack-dev-server
    ```
  * **package.json 스크립트 추가** &#x20;

    ```javascript
    "scripts":{
    "start": "node_modules/.bin/webpack-dev-server --open --hot",
    }
    ```
  * **webpack.config.js devServer 옵션추가** &#x20;
    1. contentBase : 웹서버 루트 설정. 생략 : 프로젝트 디렉터리
    2. port : 포트 번호설정. 기본 8080
    3. historyApiFallback : 브라우저 이전상태로 이동할 때, URI 존재x `404에러 -> 기본페이지로 이동 시킬지 여부설정`&#x20;

       ```javascript
       module.exports = {
       ...
       devServer:{
        contentBase:'./public/',
        port:3000, 
        historyApiFallback: true
       }
       ...
       }
       ```
  * 주의  &#x20;

    **public에 빌드되서 배포가 되지는 않음. 배포시에는 build 작업이 필요해 보임**
* 실행&#x20;

  ```bash
  # node node_modules/.bin/webpack-dev-server --open --hot
  $ npm run start
  ```

#### Vue-cli 보일러플레이트

**보일러플레이트(boilerplate)란**

* 최소한의 변경으로 재사용할 수 있는 것
* 적은 수정으로 여러곳 활용 가능한 코드
* 문서에서 반복적으로 인용되는 문석의 한 부분 &#x20;

  **핵심은 반복되고 자주쓰이는 것을 자동화.**
