๊ด€๋ฆฌ ๋ฉ”๋‰ด

JiYoung Dev ๐Ÿ–ฅ

Webpack: ๊ฐœ๋…๊ณผ ์„ค์ • ๋ณธ๋ฌธ

Study/React

Webpack: ๊ฐœ๋…๊ณผ ์„ค์ •

Shinjio 2024. 11. 27. 22:22
๋ฐ˜์‘ํ˜•

๋ถ€ํŠธ์บ ํ”„์—์„œ React๋ฅผ ์ฒ˜์Œ ์ ‘ํ–ˆ์„ ๋•Œ CRA(react-create-app)์„ ํ†ตํ•ด ์•ฑ์„ ๊ตฌ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•˜์˜€๋‹ค. ํšŒ์‚ฌ์— ์ž…์‚ฌํ•œ ํ›„ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์„ ๋งก๊ฒŒ ๋˜๋ฉด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ, CRA์˜ ๊ฒฝ์šฐ ๋‚ด์žฅ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋งŽ์•„์„œ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ธ€์„ ๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” CRA๊ฐ€ ์•„๋‹Œ ์ง์ ‘ Webpack์„ ์ ์šฉํ•˜์˜€๋Š”๋ฐ(CRA๊ฐ€ ์ž๋™์œผ๋กœ Webpack์„ ์ ์šฉ), ๊ทธ ๊ณผ์ •์—์„œ Webpack์ด ๋ฌด์—‡์ธ์ง€, ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€, ๊ฐ ์„ค์ •์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

๐Ÿ”Ž Webpack์ด๋ž€


Webpack์€ ๋ชจ๋˜ Javascript ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ์ •์  ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ์ด๋‹ค.

Javascript๋ฅผ ์œ„ํ•œ ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ Webpack๋งŒ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋‚ด๊ฐ€ ์ง์ ‘ ๋‹ค๋ค„๋ณธ Webpack๋งŒ์„ ์„ค๋ช…ํ•œ๋‹ค. 

 

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(Module Bundler)
๋ถ„๋ฆฌ๋œ ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ฐœ๋ฐœ ๋„๊ตฌ ๊ฐ๊ฐ์˜ ๋ชจ๋“ˆ๋“ค์— ๋Œ€ํ•ด ์˜์กด์„ฑ ๊ด€๊ณ„๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ๊ทธ๋ฃจํ•‘ํ•ด์ฃผ๋Š” ๊ฒƒ
์ฆ‰, Javascript ๋ชจ๋“ˆ์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์ผ Javascript ํŒŒ์ผ๋กœ ๋ฌถ๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋„๊ตฌ
CSS, ํฐํŠธ, ์ด๋ฏธ์ง€, JS๋ฅผ ์ •์ ์ธ ํŒŒ์ผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ํ•˜๋‚˜๋กœ ํ•ฉ์ณ์ฃผ๋Š”๋ฐ ์‚ฌ์šฉ

 

 

Webpack์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

๋”ํ•˜๊ธฐ์™€ ๊ณฑ์…ˆ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(.js)๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค. ์šฐ๋ฆฌ๋Š” ์œ ์ง€๊ด€๋ฆฌ๋ฅผ ๋” ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์œ„์™€ ๊ฐ™์ด ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์˜€๋‹ค.

 

index.html

<html>
<head>
    <script src="src/sum.js"></script>
    <script src="src/multiply.js"></script>
    <script src="src/index.js"></script>
</head>
</html>

 

index.js

var totalMultiply = multiply(5, 3); //multiply.js
var totalSum = sum(5, 3); //sum.js
console.log('Product of 5 and 3 = ' + totalMultiply);
console.log('Sum of 5 and 3 = ' + totalSum);

 

muliply.js

var multiply = function (a, b) {
    var total = 0;
    for (var i = 0; i < b; i++) {
        total = sum(a, total);
    }
    return total;
};

 

sum.js

var sum = function (a, b) {
    return a + b;
};

 

์œ„์˜ index.html์˜ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

Product of 5 and 3 = 15 Sum of 5 and 3 = 8

 

์œ„์˜ ์ฝ”๋“œ์—์„œ ์šฐ๋ฆฌ๋Š” multiply.js์™€ index.js ๋ชจ๋‘๊ฐ€ sum.js์— ์˜์กดํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ index.html์—์„œ index.js์˜ script ์ฝ”๋“œ๋ฅผ multiply.js ์œ„ ํ˜น์€ sum.js ์œ„์— ์œ„์น˜์‹œํ‚ค๊ฒŒ๋˜๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

๋งŒ์•ฝ ํ˜„์žฌ๋ณด๋‹ค ํ›จ์”ฌ ๋” ํ™•์žฅ๋˜๊ณ  ๋” ํฐ ํ๋ชจ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ดค์„ ๋•Œ, ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ์ˆ˜์‹ญ ๊ฐœ์˜ ์ข…์†์„ฑ์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ทธ ์ค‘ ์ผ๋ถ€๋Š” ์„œ๋กœ ์˜์กดํ•œ๋‹ค. ์ด ์งˆ์„œ๋ฅผ ์œ„์™€ ๊ฐ™์ด ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

 

๋˜ํ•œ, ์—ฌ๊ธฐ์— ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋‹ค๋ฅธ ์ฝ”๋“œ๊ฐ€ ๋ณ€์ˆ˜๋ฅผ ๋ฎ์–ด ์“ธ ์œ„ํ—˜๋„ ์žˆ๊ณ , ์ด๋กœ ์ธํ•ด ์ฐพ๊ธฐ ์–ด๋ ค์šด ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด๋ณด์ž. 

 

index.html

<!DOCTYPE html>
<html>
  <head> </head>
  <body>
    <script src="./src/math.js"></script>
    <script src="./src/app.js"></script>
  </body>
</html>

 

main.js

function sum(x, y) {
  return x + y;
}

 

app.js

sum(1, 2);

console.log(sum(1, 2)); // 3

 

sum.js

var sum = function (a, b) {
    return a + b;
};

 

์œ„์™€ ๊ฐ™์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ตฌ์„ฑ๋˜์—ˆ์„ ๋•Œ ๋ฌธ์ œ๋Š” sum์ด ์ „์—ญ ์Šค์ฝ”ํ”„์— ๋…ธ์ถœ๋˜๋ฉด ๋ฐœ์ƒํ•œ๋‹ค.

 

 

sum = 1;
sum(3,4) //Uncaught TypeError: sum is not a function;

 

๋งŒ์•ฝ ์ „์—ญ์œผ๋กœ sum์— 1์„ ์ƒˆ๋กญ๊ฒŒ ํ• ๋‹นํ•œ๋‹ค๋ฉด ์ด์ œ sum์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ๋˜์–ด๋ฒ„๋ฆฐ๋‹ค.

 

Webpack์€ ์ด๋Ÿฌํ•œ ์ข…์†์„ฑ์„ ๋ชจ๋“ˆ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ด ๋ชจ๋“ˆ์„ ๋ฒˆ๋“ค๋งํ•˜์—ฌ ๋ชจ๋“  ์ข…์†์„ฑ์„ ๋‹จ์ผ ํŒŒ์ผ๋กœ ๋Œ์–ด ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ”Ž Webpack ์„ค์ •


Webpack.config.(c/m)js

webpack.config.js ํŒŒ์ผ์€ ์ตœ์ƒ๋‹จ์— ์œ„์น˜ํ•˜์—ฌ Webpack์ด ์‹คํ–‰๋  ๋•Œ ์ฐธ์กฐํ•˜๋Š” ์„ค์ • ํŒŒ์ผ์ด๋‹ค.

 

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด์„œ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•œ ์„ค์ • ํŒŒ์ผ์ด๋‹ค. ํ˜„์žฌ ๋‚ด๊ฐ€ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ๋Š” ECMAscript ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ webpack.config.mjs ํŒŒ์ผ๋กœ ์ž‘์„ฑํ•˜์˜€๋‹ค. 

 

import Dotenv from "dotenv-webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import path from "path";

export default {
  name: "app_webpack_name",
  mode: "development",
  resolve: {
    extensions: [".js", ".jsx"],
    alias: {
      "@components": path.resolve(process.cwd(), "src/components"),
      "@pages": path.resolve(process.cwd(), "src/pages"),
    },
    fallback: {
      path: "path-browserify",
      url: "url",
    },
  },
  entry: {
    app: path.resolve(process.cwd(), "src/index.js"),
  },
  output: {
    path: path.resolve(process.cwd(), "dist"),
    filename: "bundle.js",
    publicPath: "/",
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.s[ac]ss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
    new Dotenv({
      path: "./.env.develop",
    }),
  ],
  devServer: {
    historyApiFallback: true,
    static: "./dist",
    port: 3000,
    open: true,
    hot: true,
  },
};

 

name

Webpack ์„ค์ •์˜ ์ด๋ฆ„

์ฃผ๋กœ Webpack์˜ Multi-Compiler ์„ค์ •์—์„œ ์—ฌ๋Ÿฌ ์„ค์ • ํŒŒ์ผ์„ ๊ตฌ๋ถ„ํ•˜๋Š”๋ฐ ์œ ์šฉ

 

mode

Webpack์˜ ๋ชจ๋“œ ์„ค์ •

  • development: ๋””๋ฒ„๊น…์„ ์œ„ํ•œ ์„ค์ •(์ตœ์ ํ™” ๋ฏธ์ ์šฉ, ์†Œ์Šค๋งต ์ƒ์„ฑ)
  • production: ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•ด ํŒŒ์ผ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ  ์„ฑ๋Šฅ์„ ๋†’์ž„
  • none: ๊ธฐ๋ณธ๊ฐ’, ์ตœ์ ํ™”๋‚˜ ๋””๋ฒ„๊น… ์—†์ด ๋นŒ๋“œ

 

Resolve

  • extensions: ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์ •
  • alias: ๋ชจ๋“ˆ ๊ฒฝ๋กœ๋ฅผ ๋‹จ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„์นญ ์ง€์ •
  • fallback: Node.js ๋ชจ๋“ˆ์„ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋Œ€์ฒด ๋ชจ๋“ˆ์„ ์ง€์ •
    • path-browserify: ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ Node.js์˜ path ๋ชจ๋“ˆ์„ ๋Œ€์ฒด
    • url: ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ Node.js์˜ url ๋ชจ๋“ˆ์„ ๋Œ€์ฒด

 

entry

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๋ฉฐ Webpack์ด ๋ฒˆ๋“ค๋ง์„ ์‹œ์ž‘ํ•˜๋Š” ๊ณณ

Webpack์€ entry point๊ฐ€ ์˜์กดํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“ˆ๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ฐพ์•„๋‚ธ๋‹ค.

 

output

output ์†์„ฑ์€ ๋ฒˆ๋“ค ๊ฒฐ๊ณผ๋ฌผ์˜ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ์˜ต์…˜ ๋“ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • path: ๋ฒˆ๋“ค๋ง๋œ ๊ฒฐ๊ณผ๋ฌผ์˜ ์œ„์น˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • filename:๋ฒˆ๋“ค๋ง๋œ ๊ฒฐ๊ณผ๋ฌผ์˜ ์ด๋ฆ„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • publicPath: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฆฌ์†Œ์Šค๋ฅผ ๋กœ๋“œํ•  ๊ธฐ๋ณธ URL ๊ฒฝ๋กœ

 

Module Rules

  • rules: ํŒŒ์ผ ์œ ํ˜•๋ณ„ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ์ •์˜
    • test: ์ฒ˜๋ฆฌํ•  ํŒŒ์ผ ํ™•์žฅ์ž ํŒจํ„ด
    • exclude: ์ œ์™ธํ•  ๋””๋ ‰ํ† ๋ฆฌ
    • use: ์‚ฌ์šฉํ•  ๋กœ๋” ์ง€์ •

 

loader

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ•ด์„ํ•  ๋•Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์ด ์•„๋‹Œ HTML, CSS ๋“ฑ ์›น ์ž์›๋“ค์„ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค. ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋กœ๋”๋Š” babel-loader, css-loader, style-loader, file-loader ๋“ฑ์ด ์žˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ Webpack์€ Javascript ๋ฐ JSON ํŒŒ์ผ๋งŒ ํ•ด์„์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ๋กœ๋”(loaders)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Webpack์ด ๋‹ค๋ฅธ ํฌ๋งท์˜ ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ์ด๋ฅผ ์•ฑ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“ˆ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • test: loader๋ฅผ ์ ์šฉ์‹œํ‚ฌ ํŒŒ์ผ ์œ ํ˜• ๋ช…์‹œ(์ •๊ทœํ‘œํ˜„์‹)
  • use: ํ•ด๋‹น ํŒŒ์ผ์— ์ ์šฉํ•  loader ๋ช…์‹œ
  • exclude: loader๋ฅผ ๋ฐฐ์ œ์‹œํ‚ฌ ํŒŒ์ผ ๋ช…์‹œ

 

plugin

Webpack์œผ๋กœ ๋ณ€ํ™˜ํ•œ ํŒŒ์ผ์— ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ํ•ด๋‹น ๊ฒฐ๊ณผ๋ฌผ์˜ ํ˜•ํƒœ๋ฅผ ๋ฐ”๊ฟ”์ฃผ๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • HtmlWebpackPlugin: ๋ฒˆ๋“ค๋ง๋œ JS ํŒŒ์ผ์„ ์ž๋™์œผ๋กœ HTML ํŒŒ์ผ์— ์‚ฝ์ž…
    • template: ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์‚ฌ์šฉํ•  HTML ํŒŒ์ผ ์ง€์ •
  • Dotenv: ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋กœ๋“œ

 

DevServer

Webpack ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์„ค์ •

  • historyApiFallback: SPA์—์„œ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ… ์ง€์›
  • static: ์ •์  ํŒŒ์ผ์„ ์ œ๊ณตํ•  ๋””๋ ‰ํ† ๋ฆฌ
  • port: ๊ฐœ๋ฐœ ์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉํ•  ํฌํŠธ ๋ฒˆํ˜ธ
  • open: ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰ ์‹œ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ž๋™์œผ๋กœ ์—ด๋„๋ก ์„ค์ •
  • hot: HMR(Hot Module Replacement) ํ™œ์„ฑํ™”. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒˆ๋กœ๊ณ ์นจํ•˜์ง€ ์•Š๊ณ ๋„ ๋ณ€๊ฒฝ๋œ ๋ชจ๋“ˆ์„ ์ฆ‰์‹œ ๋ฐ˜์˜

 

โค ์ฐธ๊ณ ์ž๋ฃŒ


https://ingg.dev/webpack/

https://tech.osci.kr/create-react-app-์—†์ด-๋ฐฐ์šฐ๋Š”-webpack/

https://blog.ag-grid.com/webpack-tutorial-understanding-how-it-works/

๋ฐ˜์‘ํ˜•