[WEB] Webpack

web

0. Index

  1. Node.js์™€ NPM
  2. Webpack
  3. Babel๊ณผ ES6 ๋ชจ๋“ˆ ๋ฌธ๋ฒ•
  4. webpack.config.js ์„ค์ • ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ธฐ
  5. Webpack Dev Server

1. Node.js์™€ NPM

1. Node.js / NPM ์„ค์น˜

  • ๋จผ์ € Node.js๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค.

    • https://nodejs.org/ko/ (LTS ๋ฒ„์ „ ์„ค์น˜)
    • Node.js๋ฅผ ์„ค์น˜ํ•˜๋ฉด npm์ด ํ•จ๊ป˜ ์„ค์น˜๋œ๋‹ค.
  • ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋กœ node.js์™€ npm์ด ์ž˜ ์„ค์น˜๋˜์—ˆ๋Š”์ง€ version์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

    $ node -v
    $ npm -v

2. NPM ์ดˆ๊ธฐํ™”

  • ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋กœ npm์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

    $ npm init -y
  • ๊ทธ๋Ÿฌ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ํฌํ•จํ•œ package.json ํŒŒ์ผ์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

    {
      "name": "ํ”„๋กœ์ ํŠธ ์ด๋ฆ„",
      "version": "1.0.0",
      "description": "",
      "main": "main.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC"
    }

3. NPM ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ ๋ช…๋ น์–ด

  • ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋กœ npm ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

    $ npm install {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„}
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด node_modules๋ผ๋Š” ํด๋”๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ๊ทธ ์•ˆ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์„ค์น˜๋œ๋‹ค.

    package.json ์— ์•„๋ž˜์˜ ๋‚ด์šฉ์ด ์ถ”๊ฐ€๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด jquery ๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ–ˆ์„ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด dependencies ์†์„ฑ์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„๊ณผ ์„ค์น˜๋œ ๋ฒ„์ „์ด ์ถ”๊ฐ€๋œ๋‹ค.

    "dependencies": {
      "jquery": "^3.6.0"
    }

    ๋งŒ์•ฝ ๋ช…๋ น์–ด ๋’ค์— --save-dev ๋ฅผ ํ•จ๊ป˜ ๋ถ™์—ฌ์„œ ์„ค์น˜ํ•œ๋‹ค๋ฉด dependencies๊ฐ€ ์•„๋‹ˆ๋ผ devDependencies ์†์„ฑ์œผ๋กœ ์ถ”๊ฐ€๋œ๋‹ค.


4. NPM์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์™€ ์žฅ์ 

  • NPM์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํŒจํ‚ค์ง€(๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ) ๋งค๋‹ˆ์ €๋กœ, ์ „ ์„ธ๊ณ„ JS ๊ฐœ๋ฐœ์ž๋“ค์ด ๋ชจ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ณต๊ฐœ๋œ ์ €์žฅ์†Œ์— ์˜ฌ๋ ค๋†“๊ณ  npm ๋ช…๋ น์–ด๋กœ ํŽธํ•˜๊ฒŒ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์˜ ๋ฒ„์ „๊ณผ ์˜์กด์„ฑ์ด ํŽธํ•˜๊ฒŒ ๊ด€๋ฆฌ๋œ๋‹ค.
  • cdn์„ ์ผ์ผ์ด ๋“ค๊ณ ์˜ค๋Š” ๊ฒƒ๋ณด๋‹ค npm install๋กœ ์„ค์น˜ํ•˜๋ฉด ํŽธ๋ฆฌํ•˜๊ฒŒ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

5. NPM ๋ช…๋ น์–ด

  • ์„ค์น˜

    • dependencies

      $ npm install {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„}
      # or
      $ npm i {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„}
    • devDependencies

      $ npm install {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„} --save-dev
      # or
      $ npm i {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„} -D
  • ์ œ๊ฑฐ

    $ npm uninstall {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„}
  • ์ „์—ญ ์„ค์น˜

    $ npm install {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„} --global
    # or
    $ npm install {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„} -g
    • ํ•ด๋‹น ํ”„๋กœ์ ํŠธ node_modules ํด๋” ์•ˆ์— ์„ค์น˜ ๋˜์ง€ ์•Š๋Š”๋‹ค.
    • ์–ด๋Š ์œ„์น˜์—์„œ ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋“  ๊ทธ ์œ„์น˜์— ์„ค์น˜๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์•„๋ž˜์˜ ํด๋”์— ์„ค์น˜๋œ๋‹ค. (์‹œ์Šคํ…œ ๋ ˆ๋ฒจ์˜ ์ „์—ญ์œผ๋กœ ์„ค์น˜๋˜๋Š” ๊ฒƒ)

      # windows
      %USERPROFILE%\AppData\Roaming\npm\node_modules
      
      # macOS
      /usr/local/lib/node_modules

6. dependencies์™€ devDependencies์˜ ์ฐจ์ด์ 

  • dependencies

    • npm i {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„}
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง๊ณผ ์—ฐ๊ด€์ด ์žˆ๋Š” ๋ฐฐํฌ์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • ์˜ˆ๋ฅผ ๋“ค์–ด, jQuery๋Š” ํ™”๋ฉด์˜ DOM์„ ์กฐ์ž‘ํ•˜๊ธฐ ์œ„ํ•œ ์œ ํ‹ธ์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐํฌ์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.
    • ex) react, angular, chart
  • devDependencies

    • npm i {๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„} -D
    • ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ ๋„์›€์„ ์ฃผ๋Š” ๊ฐœ๋ฐœ์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • ex) webpack, js-compression, sass

2. Webpack

1. ๋ชจ๋“ˆ๊ณผ ์›นํŒฉ ๊ทธ๋ฆฌ๊ณ  ๋ฒˆ๋“ค๋ง

  • ๋ชจ๋“ˆ : ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€์ ์—์„œ ํŠน์ • ๊ธฐ๋Šฅ์„ ๊ฐ–๋Š” ์ž‘์€ ์ฝ”๋“œ ๋‹จ์œ„
  • ์›นํŒฉ : ์ตœ์‹  FE ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ
  • ์›นํŒฉ์—์„œ์˜ ๋ชจ๋“ˆ : ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ชจ๋“  ์ž์› (HTML, CSS, JS, Images, Font ๋“ฑ.. ํŒŒ์ผ ํ•˜๋‚˜ํ•˜๋‚˜๊ฐ€ ๋ชจ๋‘ ๋ชจ๋“ˆ์ด๋‹ค.)
  • ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ : ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•˜๋Š” ์ž์›(HTML, CSS, JS, Images ๋“ฑ)์„ ๋ชจ๋‘ ๊ฐ๊ฐ์˜ ๋ชจ๋“ˆ๋กœ ๋ณด๊ณ  ์ด๋ฅผ ์กฐํ•ฉํ•ด์„œ ๋ณ‘ํ•ฉ๋œ ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“œ๋Š” ๋„๊ตฌ
  • ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋ง : ๋ช‡์‹ญ, ๋ช‡๋ฐฑ๊ฐœ์˜ ์ž์›๋“ค์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ํ•ฉ์ณ์ค€๋‹ค.

    webpack


2. ์›นํŒฉ ํŠœํ† ๋ฆฌ์–ผ

  1. npm ์ดˆ๊ธฐํ™”

    $ npm init -y
  2. webpack ์„ค์น˜

    $ npm i webpack webpack-cli -D
  3. lodash ์„ค์น˜ (JS ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)

    $ npm i lodash
  4. index.html ์ƒ์„ฑ

    <html>
    <head>
      <title>Webpack Demo</title>
      <script src="https://unpkg.com/lodash@4.16.6"></script>
    </head>
    <body>
      <script src="src/index.js"></script>
    </body>
    </html>
  5. src/index.js ์ƒ์„ฑ

    function component() {
      var element = document.createElement('div');
    
      /* lodash is required for the next line to work */
      element.innerHTML = _.join(['Hello','webpack'], ' ');
    
      return element;
    }
    
    document.body.appendChild(component());
  6. ์›นํŒฉ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ๋กœ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •

    • index.html

      <html>
        <head>
          <title>Webpack Demo</title>
        </head>
        <body>
          <script src="dist/main.js"></script>
        </body>
      </html>
    • src/index.js ์— lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ import ๋ฌธ ์ถ”๊ฐ€

      import _ from 'lodash';
      
      //...
  7. ์›นํŒฉ ๋นŒ๋“œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด package.json ํŒŒ์ผ์— ์ปค์Šคํ…€ ๋ช…๋ น์–ด ์ถ”๊ฐ€

    "scripts": {
    	//...
    	"build": "webpack"
    }
  8. ๋งˆ์ง€๋ง‰์œผ๋กœ npm run build ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด dist ํด๋”์— ๋ฒˆ๋“ค๋ง ๊ฒฐ๊ณผ๋ฌผ์ด ์ƒ์„ฑ๋œ๋‹ค.

3. ์›นํŒฉ ์„ค์ •

  • ๋ฃจํŠธ ๊ฒฝ๋กœ์— webpack.config.js ์ถ”๊ฐ€

    // `webpack` command will pick up this config setup by default
    var path = require('path');
    
    module.exports = {
      mode: 'none',
      entry: './src/index.js',
      output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
      }
    };
    • var path = require('path'); : node.js์˜ ๋ชจ๋“ˆ ๋ฌธ๋ฒ•์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. path ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋“ค๊ณ  ์™€์„œ path๋ผ๋Š” ๋ณ€์ˆ˜์— ๋‹ด๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ด path์˜ resolve๋ผ๋Š” api ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.
    • ๋นŒ๋“œ ๋ชจ๋“œ๋Š” development, production, none ์ด 3๊ฐ€์ง€๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. none์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์ด ๋‚œ๋…ํ™” ๋˜์–ด ๋‚˜์˜จ๋‹ค.
  • ๋นŒ๋“œ(๋ฒˆ๋“ค๋ง) ๊ฒฐ๊ณผ๋ฌผ ๊ฒฝ๋กœ ๋ณ€๊ฒฝ ๋ฐฉ๋ฒ•

    • ์•„๋ฌด๋Ÿฐ ์„ค์ •์„ ํ•˜์ง€ ์•Š์œผ๋ฉด src/index.js ํŒŒ์ผ ๋ฒˆ๋“ค๋ง ๋œ ๊ฒฐ๊ณผ๋ฌผ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ dist ํด๋” ๋ฐ‘์— main.js ํŒŒ์ผ๋ช…์œผ๋กœ ์ถ”๊ฐ€๋œ๋‹ค. (dist/main.js)
    • ๋งŒ์•ฝ ์ด ํด๋” ๊ฒฝ๋กœ์™€ ํŒŒ์ผ๋ช…์„ public/output.js ์™€ ๊ฐ™์ด ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด webpack.config.js ํŒŒ์ผ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

      //..
      module.exports = {
        //..
        output: {
          filename: 'output.js',
          path: path.resolve(__dirname, 'public')
        }
      };

4. ์›นํŒฉ ์†Œ๊ฐœ ์ถ”์ฒœ ์˜์ƒ


5. ์›นํŒฉ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

  • ํŒŒ์ผ ๋‹จ์œ„์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ชจ๋“ˆ ๊ด€๋ฆฌ

    • ๋ชจ๋“ˆ ๊ฐœ๋…์ด ์—†์—ˆ์„ ๋•Œ๋Š” ํŒŒ์ผ ๋‹จ์œ„๋กœ ์Šค์ฝ”ํ”„๊ฐ€ ์ •ํ•ด์ง€์ง€ ์•Š์•„์„œ a.js ์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋ฅผ b.js ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค.
    • ํŒŒ์ผ ๋‹จ์œ„๋กœ ๊ธฐ๋Šฅ์ด ๊ตฌ๋ถ„๋˜์–ด์•ผ ํ•˜๋Š” ํ•„์š”์„ฑ ๋•Œ๋ฌธ์— ES6+์— modules๋ผ๋Š” ๋ฌธ๋ฒ•์œผ๋กœ import, export ๊ฐœ๋…์ด ์–ธ์–ด ๋ ˆ๋ฒจ๊นŒ์ง€ ๋“ค์–ด์˜ค๊ฒŒ ๋˜์—ˆ๋‹ค.
  • ์›น ๊ฐœ๋ฐœ ์ž‘์—… ์ž๋™ํ™” ๋„๊ตฌ

    • ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์ €์žฅํ•œ๋’ค ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•ด์•ผ ํ™”๋ฉด์—์„œ ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
    • ์›น ์„œ๋ฒ„์— ๋ฐฐํฌํ•  ๋•Œ HTML, CSS, JS, ์ด๋ฏธ์ง€ ์••์ถ•, CSS ์ „์ฒ˜๋ฆฌ๊ธฐ ๋ณ€ํ™˜์„ ํ•ด์ค˜์•ผ ํ–ˆ๋Š”๋ฐ ์ด๋Ÿฌํ•œ ์ผ์„ ์ž๋™ํ™” ํ•ด์ฃผ๋Š” ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค.
  • ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋น ๋ฅธ ๋กœ๋”ฉ ์†๋„์™€ ๋†’์€ ์„ฑ๋Šฅ

    • ๋กœ๋”ฉ ์†๋„๋ฅผ ๋†’์ด๋ ค๊ณ  ์„œ๋ฒ„๋กœ ์š”์ฒญํ•˜๋Š” ํŒŒ์ผ ์ˆ˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด์„œ ์›น ํƒœ์Šคํฌ ๋งค๋‹ˆ์ €๋ฅผ ์ด์šฉํ•ด ํŒŒ์ผ์„ ์••์ถ•ํ•˜๊ณ  ๋ณ‘ํ•ฉํ•˜๋Š” ์ž‘์—…์„ ํ–ˆ์—ˆ๋‹ค.
    • ์›นํŒฉ์€ ํŒŒ์ผ์„ ์••์ถ•ํ•˜๋Š” ์ž‘์—…์„ ํ•ด์ค„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ดˆ๊ธฐ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ๋‚˜์ค‘์— ํ•„์š”ํ•œ ์ž์›๋“ค์€ ํ•„์š”ํ•  ๋•Œ ์š”์ฒญํ•˜๋Š” ๋ ˆ์ด์ง€ ๋กœ๋”ฉ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

3. Babel๊ณผ ES6 ๋ชจ๋“ˆ ๋ฌธ๋ฒ•

1. Babel

  • https://babeljs.io/docs/en/learn
  • JS์˜ ์ตœ์‹  ๋ฌธ๋ฒ•๋“ค์„ ์ตœ๋Œ€ํ•œ ๋งŽ์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ˜ธํ™˜๋  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๋„๊ตฌ
  • Babel ์„ค์น˜

    $ npm i @babel/core @babel/preset-env babel-loader -D

2. ES6 Modules

  • export

    • ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ๊ฐ€์ ธ๋‹ค ์“ธ ๋ณ€์ˆ˜๋‚˜ ํ•จ์ˆ˜ ์•ž์— export ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ธ๋‹ค.

      export var name = 'Jessie';
      export function sum(a, b) {
        return a + b;
      }
  • import

    • export๋œ ๋ณ€์ˆ˜๋‚˜ ํ•จ์ˆ˜๋ฅผ { } ์•ˆ์— ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

      import { name, sum } from 'ํŒŒ์ผ ๊ฒฝ๋กœ';
      
      console.log(name); // Jessie
      console.log(sum(10, 20)); // 30

3. sourcemap - ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ ๋ถ„์„

  • webpack.config.js ํŒŒ์ผ์— devtool: 'source-map' ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋นŒ๋“œ๋˜๊ธฐ ์ „์˜ ์›๋ณธ ํŒŒ์ผ์„ ๊ฐœ๋ฐœ์ž๋„๊ตฌ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋นŒ๋“œ(๋ฒˆ๋“ค๋ง)๋œ ํŒŒ์ผ๋กœ ๋™์ž‘ํ•˜์ง€๋งŒ, ๊ฐœ๋ฐœ์ž๋„๊ตฌ Sources ํƒญ์—์„œ ๋นŒ๋“œํ•˜๊ธฐ ์ „์˜ ์›๋ณธ ํŒŒ์ผ์„ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค. (sourcemap)
  • ์ด ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๊ฐ€ ๋””๋ฒ„๊น…์ด ํ•„์š”ํ•  ๋•Œ ๊ฐœ๋ฐœ์ž๋„๊ตฌ์—์„œ ์›๋ณธ ํŒŒ์ผ์„ ๋ณผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŽธ๋ฆฌํ•˜๋‹ค.
  • ํ•˜์ง€๋งŒ ์ด ์†Œ์Šค ๋งต์ด ์ผœ์ ธ ์žˆ์œผ๋ฉด ํ”„๋กœ์ ํŠธ ์ „์ฒด ์†Œ์Šค๊ฐ€ ๋‹ค ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์„œ๋ฒ„์— ์‹ค์ œ ๋ฐฐํฌํ•  ๋•Œ๋Š” ๋„๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

4. webpack.config.js ์„ค์ • ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ธฐ

var path = require('path');

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.bundle.js'
  },
  module: {
    rules: [{
      test: /\.m?js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }, {
			test: /\.css$/,
			use: ['style-loader', 'css-loader']
		}]
  },
  stats: {
    colors: true
  },
  devtool: 'source-map'
};

1. mode

  • ์›นํŒฉ ๋ฒ„์ „ 4๋ถ€ํ„ฐ mode ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.
  • ์‹คํ–‰ ๋ชจ๋“œ 3๊ฐ€์ง€ : production, development, none
  • development : ๊ฐœ๋ฐœ์ž๋“ค์ด ์ข€ ๋” ๋ณด๊ธฐ ํŽธํ•˜๊ฒŒ ์›นํŒฉ ๋กœ๊ทธ๋‚˜ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ณด์—ฌ์ง„๋‹ค.
  • production : ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์ธ ํŒŒ์ผ ์••์ถ• ๋“ฑ์˜ ๋นŒ๋“œ ๊ณผ์ •์ด ์ถ”๊ฐ€๋œ๋‹ค.
  • none : ๋‚œ๋…ํ™” ๋˜์ง€ ์•Š๊ณ  ๋ฒˆ๋“ค๋ง๋œ๋‹ค.
  • mode ๊ฐ’์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด production์œผ๋กœ ์ž๋™ ์„ค์ •๋œ๋‹ค.

2. entry

  • ๋นŒ๋“œ๋ฅผ ํ•  ๋Œ€์ƒ ํŒŒ์ผ(์ตœ์ดˆ ์ง„์ž…์ ) ์ง€์ •

3. output

  • ๋นŒ๋“œ๋ฅผ ํ•˜๊ณ  ๋‚œ ๊ฒฐ๊ณผ๋ฌผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ •์˜
  • filename: ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ ํŒŒ์ผ ์ด๋ฆ„ ์ง€์ •
  • ํŒŒ์ผ ๋‚ด๋ถ€ ๋‚ด์šฉ์ด ๋ณ€ํ•˜๋”๋ผ๋„ ์ด filename์ด ๋™์ผํ•˜๋ฉด, ๋ธŒ๋ผ์šฐ์ € ์บ์‹ฑ ๋•Œ๋ฌธ์— ๊ฐ™์€ ํŒŒ์ผ์„ ํ™”๋ฉด์— ๋ฟŒ๋ ค์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ•์ œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•ด์•ผ ํ•œ๋‹ค.
  • filename์„ '[name].[hash].bundle.js' ์™€ ๊ฐ™์ด ์ •์˜ํ•˜๋ฉด, ์›นํŒฉ์ด ํ•ด์‹œ ๊ฐ’์„ ์ด์šฉํ•ด์„œ ๋นŒ๋“œ๋ฅผ ํ•  ๋•Œ๋งˆ๋‹ค ๊ณ ์œ  ๊ฐ’๋“ค์„ ๋ถ™์—ฌ์ค€๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด filename์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ € ์บ์‹ฑ์ด ๋˜์ง€ ์•Š๊ณ  ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

    output: {
      //...
      filename: '[name].[hash].bundle.js'
    },

4. module

  • entry์—์„œ output์œผ๋กœ ๋ณ€ํ™˜์„ ํ•  ๋•Œ ์ค‘๊ฐ„์— ๊ฐœ์ž…ํ•˜๋Š” Loader.
  • ์›นํŒฉ์ด ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด ํŒŒ์ผ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ํ•ด์„ํ•  ๋•Œ JS ํŒŒ์ผ์ด ์•„๋‹Œ ์›น ์ž์›(HTML, CSS, Images, Font, โ€ฆ)๋“ค์„ ๋ณ€ํ™˜ํ•ด์ฃผ์–ด ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ ์•ˆ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.
  • rules: ์›นํŒฉ์œผ๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ ์ ์šฉ๋  ๋กœ๋”๋“ค์„ ๋ฐฐ์—ด ์•ˆ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • test: ๋กœ๋”๋ฅผ ์ ์šฉํ•  ํŒŒ์ผ์˜ ํ™•์žฅ์ž ์ง€์ •
  • use: ๋กœ๋” ์ง€์ •
  • example

    module: {
      rules: [{
    		test: /\.css$/,
    		use: ['style-loader', 'css-loader']
    	}]
    },
    • .css ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ํŒŒ์ผ์„ ๋Œ€์ƒ์œผ๋กœ style-loader,css-loader ๋กœ๋”๋ฅผ ์ ์šฉ
  • ๋งŒ์•ฝ index.js ์— base.css ๋ผ๋Š” ํŒŒ์ผ์„ importํ•œ ์ƒํƒœ์—์„œ ์œ„์˜ ์„ค์ •์ฒ˜๋Ÿผ ํ•„์š”ํ•œ ๋กœ๋”๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š๊ณ  ๋นŒ๋“œ๋ฅผ ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

    • ์—๋Ÿฌ ๋ฐœ์ƒ!
    • ์ฒ˜์Œ์— index.js ๋ฅผ ๊ฐ€์ง€๊ณ  ํ•ด์„์„ ์‹œ์ž‘ํ•˜๋Š”๋ฐ index.js ์•ˆ์— ์žˆ๋Š” base.css ๋ฅผ ๋ณด๊ณ  ์ด๊ฑธ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์— css ์ฝ”๋“œ๋ฅผ ๋„ฃ์œผ๋ ค๊ณ  ํ•  ๋•Œ fail ์ด ๋œฌ๋‹ค.
    • ์‚ฌ์‹ค ์›๋ž˜ JS ํŒŒ์ผ ์•ˆ์— CSS๋ฅผ ๋„ฃ์„ ์ˆ˜ ์—†๋‹ค. ๊ทธ๋ž˜์„œ ๋กœ๋”๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ.

      ERROR in ./base.css Module parse failed: Unexpected token You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.

  • ์•„๋ž˜์™€ ๊ฐ™์ด css-loader ๋งŒ ๋กœ๋”๋กœ ์ง€์ •ํ•ด์ฃผ๊ณ  ๋นŒ๋“œ๋ฅผ ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

    module: {
      rules: [{
    		test: /\.css$/,
    		use: ['css-loader']
    	}]
    },
    • ์—๋Ÿฌ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค!
    • ํ•˜์ง€๋งŒ base.css ํŒŒ์ผ์—์„œ ์ง€์ •ํ•œ ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค!
  • ๋งŒ์•ฝ ์•„๋ž˜์™€ ๊ฐ™์ด css-loader๋ฅผ ๋จผ์ € ๋กœ๋”๋กœ ์ง€์ •ํ•ด์ฃผ๊ณ , style-loader๋ฅผ ๊ทธ ๋‹ค์Œ์— ๋กœ๋”๋กœ ์ง€์ •ํ•ด์ฃผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

    module: {
      rules: [{
    		test: /\.css$/,
    		use: ['css-loader', 'style-loader']
    	}]
    },
    • ์—๋Ÿฌ ๋ฐœ์ƒ! ERROR in ./base.css Module build failed (from ./node_modules/css-loader/dist/cjs.js): CssSyntaxError
    • ๋กœ๋”๋Š” ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ ์ˆœ์„œ๋กœ ๊ฑฐ๊พธ๋กœ ์ ์šฉ๋œ๋‹ค!!!
  • ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆœ์„œ๋ฅผ ๊ผญ ์ง€์ผœ์ค˜์•ผ ํ•œ๋‹ค.

    module: {
      rules: [{
    		test: /\.css$/,
    		use: ['style-loader', 'css-loader']
    	}]
    },
    1. css-loader: ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์— css ์ฝ”๋“œ๋ฅผ ํฌํ•จ์‹œ์ผœ์ค€๋‹ค.
    2. style-loader: ์Šคํƒ€์ผ ์ฝ”๋“œ๋ฅผ <head> ํƒœ๊ทธ ์•ˆ์— ์ธ๋ผ์ธ ์Šคํƒ€์ผ๋กœ ๋„ฃ์–ด ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
  • scss๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

    module: {
      rules: [{
    		test: /\.scss$/,
    		use: ['style-loader', 'css-loader', 'sass-loader']
    	}]
    },
    1. sass-loader: sass ๋ฅผ ๋จผ์ € css ํŒŒ์ผ๋กœ ๋ฐ”๊พธ๊ณ 
    2. css-loader: ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์— css ์ฝ”๋“œ๋ฅผ ํฌํ•จ์‹œ์ผœ์ฃผ๊ณ 
    3. style-loader: ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ ๋‚ด ์Šคํƒ€์ผ ์ฝ”๋“œ๋ฅผ ํƒœ๊ทธ ์•ˆ์— ์ธ๋ผ์ธ์œผ๋กœ ๋„ฃ์–ด์ค€๋‹ค

5. plugins

  • ์›นํŒฉ ๊ธฐ๋ณธ ๋™์ž‘์— ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์†์„ฑ
  • ๋กœ๋”๋Š” ํŒŒ์ผ์„ ํ•ด์„ํ•˜๊ณ  ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •์— ๊ด€์—ฌํ•˜์ง€๋งŒ, ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ํ•ด๋‹น ๊ฒฐ๊ณผ๋ฌผ์˜ ํ˜•ํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ์—ญํ• 
  • example : html-webpack-plugin

    // webpack.config.js
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    //...
    module.exports = {
    	//...
    	plugins: [
    	  new HtmlWebpackPlugin({
    	    template: 'index.html',
    	  })
    	],
    	//...
    }
    • index.html template ๊ธฐ๋ฐ˜์œผ๋กœ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
    • ๋งŒ์•ฝ์— template ์ง€์ •์„ ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์›นํŒฉ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์— ๋Œ€ํ•ด์„œ html ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ๊ทธ ๋‹ค์Œ์— ๊ทธ ์•ˆ์— ๋นŒ๋“œ ๋‚ด์šฉ๋ฌผ๋“ค์„ ๋‹ด๋Š”๋‹ค.

6. ๊ธฐํƒ€ Loader/Plugin๋“ค ์‚ฌ์šฉํ•  ๋•Œ ์ฐธ๊ณ ํ•  ์ˆ˜ ์žˆ๋Š” ๋งํฌ

  • ํ•„์š”ํ•œ ๋กœ๋”/ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์€ ์•„๋ž˜์˜ ๋งํฌ์—์„œ ํ™•์ธํ•˜๊ณ  ๊ฐ€์ ธ๋‹ค๊ฐ€ ์“ธ ์ˆ˜ ์žˆ๋‹ค. ์–ด๋–ค์‹์œผ๋กœ ์“ฐ๋ฉด ๋˜๋Š”์ง€ ๋‹ค ๋ฌธ์„œํ™”๊ฐ€ ๋˜์–ด ์žˆ๋‹ค.
  • https://webpack.js.org/loaders/
  • https://webpack.js.org/plugins/

5. Webpack Dev Server

1. ์›นํŒฉ ๋ฐ๋ธŒ ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

  • ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์„ ํ™”๋ฉด์—์„œ ๋ณด๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์‹œ ๋นŒ๋“œ๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค.
  • ์›นํŒฉ ๋ฐ๋ธŒ ์„œ๋ฒ„๋Š” ์ด๋Ÿฌํ•œ ๋ฒˆ๊ฑฐ๋กœ์›€์„ ํ•ด๊ฒฐํ•ด์ค€๋‹ค.
  • ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๋Š” ๊ณผ์ •์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ธ๋‹ค.
  • ์›นํŒฉ์˜ ๋นŒ๋“œ ๋Œ€์ƒ ํŒŒ์ผ์ด ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋•Œ ๋งค๋ฒˆ ์›นํŒฉ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
  • ์ฝ”๋“œ๋งŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์ €์žฅํ•˜๋ฉด ์›นํŒฉ์œผ๋กœ ๋นŒ๋“œํ•œ ํ›„ ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด์„ ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ํ•ด์ค€๋‹ค.

2. ์›นํŒฉ ๋ฐ๋ธŒ ์„œ๋ฒ„ ๋นŒ๋“œ

  • ์›นํŒฉ ๋ฐ๋ธŒ ์„œ๋ฒ„๋Š” ์ผ๋ฐ˜ ์›นํŒฉ ๋นŒ๋“œ์™€ ๋‹ค๋ฅด๋‹ค.
  • package.json์— ์•„๋ž˜์™€ ๊ฐ™์ด dev ๋ช…๋ น์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

    "scripts": {
    	//...
    	"dev": "webpack-dev-server",
    	"build": "webpack"
    }
  • ์›นํŒฉ ๋ฐ๋ธŒ ์„œ๋ฒ„๋กœ ๋นŒ๋“œํ•œ ๊ฒฐ๊ณผ๋ฌผ์€ ๋ณ„๋„ ํŒŒ์ผ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š๊ณ  โ€œ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ๋‹คโ€
  • ๋”ฐ๋ผ์„œ ์ปดํ“จํ„ฐ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‚ฌ๋žŒ์ด ์ง์ ‘ ํŒŒ์ผ์„ ์กฐ์ž‘ํ•  ์ˆ˜๋Š” ์—†๋‹ค.

3. ์›นํŒฉ ๋ฐ๋ธŒ ์„œ๋ฒ„ ๋นŒ๋“œ๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

$ npm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D

Reference



๐Ÿ‘‹@Jess2
๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ปFrontend Developer

GitHubFacebookLinkedIn