๐Ÿ’ป ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ธํŒ…ํ•˜๊ธฐ - Webpack

์ดํ˜œ๋ž€ยท2023๋…„ 1์›” 15์ผ
1

๊ธฐํƒ€ ์ž๋ฃŒ ๊ณต์œ 

๋ชฉ๋ก ๋ณด๊ธฐ
3/7
post-thumbnail

module bundler๋Š” ์›น๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ํŒŒ์ผ๋“ค์„ ๋ณ‘ํ•ฉ+์••์ถ•ํ•ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ํด๋” ์ƒ์„ฑ ํ›„ ํด๋”๋ฅผ ์—ด๊ณ  ํ„ฐ๋ฏธ๋„์—์„œ npm init -y ๋กœ ์‹œ์ž‘ํ•˜๋ฉด package.json ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ webpack ๊ด€๋ จ ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
npm i -D webpack webpack-cli webpack-dev-server ์—ฌ๊ธฐ์„œ -D ๋Š” devDependencies ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๊ฒ ๋‹ค๋Š” ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค. devDependencies ๋Š” ๋กœ์ปฌ ๊ฐœ๋ฐœ์ด๋‚˜ ํ…Œ์ŠคํŠธ์‹œ์— ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

webpack.config.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , ์••์ถ• ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์••์ถ•ํ•ด์ฃผ๋Š” npm i -D terser-webpack-plugin ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

npx webpack ๋ช…๋ น์–ด๋ฅผ ํ„ฐ๋ฏธ๋„์— ์ž…๋ ฅํ•˜์—ฌ ์‹คํ–‰์‹œ์ผœ ์ฃผ๋ฉด dist ํด๋” ์•ˆ์— bundle.js ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

css์™€ html ํŒŒ์ผ์„ ์„ค์ •ํ•ด ์ค„ ๋ชจ๋“ˆ์„ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด ์„ค์น˜ํ•ด์ค๋‹ˆ๋‹ค.
npm i -D html-webpack-plugin , npm i -D mini-css-extract-plugin css-loader css-minimizer-webpack-plugin

config.js ํŒŒ์ผ ์•ˆ์— ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์„ธํŒ…ํ•ด์ค๋‹ˆ๋‹ค.

const path = require("path"); // path๋ชจ๋“ˆ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
const TerserPlugin = require("terser-webpack-plugin"); //์••์ถ• ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
const HtmlWebpackPlugin = require("html-webpack-plugin"); // html ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // css ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // css ์••์ถ• ํ”Œ๋Ÿฌ๊ทธ์ธ

module.exports = {
  entry: "./src/js/index.js", // js ํŒŒ์ผ์˜ ์ง„์ž…์ 
  output: {
    //๋นŒ๋“œํ–ˆ์„ ๋•Œ ๋ฒˆ๋“คํŒŒ์ผ ๊ด€๋ จ ์†์„ฑ
    filename: "bundle.js", // ๋ฒˆ๋“คํŒŒ์ผ ์ด๋ฆ„
    path: path.resolve(__dirname, "./dist"), // ๋ฒˆ๋“คํŒŒ์ผ ์ƒ์„ฑ๋  ์ ˆ๋Œ€ ๊ฒฝ๋กœ์ง€์ •
    clean: true, // ๊ฒฝ๋กœ์— ์ด๋ฏธ ํŒŒ์ผ์ด ์žˆ๋‹ค๋ฉด ์ง€์šฐ๊ณ  ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋Š” ์†์„ฑ
  },
  devtool: "source-map", // ๋นŒ๋“œํ•œ ํŒŒ์ผ๊ณผ ์›๋ณธํŒŒ์ผ์„ ์—ฐ๊ฒฐ
  mode: "development", // ๋‚œ๋…ํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š”์ง€ ์ฐจ์ด production
  plugins: [
    new HtmlWebpackPlugin({
      title: "keyboard",
      template: "./index.html", //๋นŒ๋“œํ•  ํŒŒ์ผ, lodash ๋ฌธ๋ฒ• ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์คŒ
      inject: "body", // ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋„ฃ์–ด์ค„ ๋ถ€๋ถ„, ๊ธฐ๋ณธ์„ค์ •์€ head
      favicon: "./favicon.png",
    }),
    new MiniCssExtractPlugin({ filename: "style.css" }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/, // css ํŒŒ์ผ์„ loader๋ฅผ ํ†ตํ•ด ์ฝ์–ด๋“ค์ž„
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  optimization: {
    minimizer: [
      new TerserPlugin(), // ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ ์••์ถ•
      new CssMinimizerPlugin(), // css ํŒŒ์ผ ์••์ถ•
    ],
  },
};
  <head>
    <title>
      <!-- ๐Ÿ“Œ lodash ๋ฌธ๋ฒ• -->
      <%= htmlWebpackPlugin.options.title %>
    </title>
  </head>

package.json ํŒŒ์ผ์˜ script ๋ถ€๋ถ„์— ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ค€ ํ›„ npm run build ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์‹œ์ผœ ์ฃผ๋ฉด ๋นŒ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

"scripts": {
  "build" : "webpack --mode=production",
  "dev": "webpack-dev-server" // npm run dev
},

๋‹ค์Œ์€ dev ์„œ๋ฒ„๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ์„ค์ •์„ ํ•˜๋Š”๋ฒ• ์ž…๋‹ˆ๋‹ค.
webpack.config.js ํŒŒ์ผ์— ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค.

devServer: {
  host: "localhost",
  port: 8080,
  open: true,
  watchFiles: "index.html", // html ํŒŒ์ผ ๋ณ€ํ™” ๊ฐ์ง€, ์ž๋™ ๋ฆฌํ”„๋ ˆ์‹œ
},

ํ„ฐ๋ฏธ๋„์— npx webpack-dev-server ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๋ฉด dev server ํŽ˜์ด์ง€๊ฐ€ ์—ด๋ฆฌ๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€