Webpack

Webpack

  • ํ”„๋ก ํŠธ์—”๋“œ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ์˜ค๋ž˜์ „๋ถ€ํ„ฐ ์‚ฌ์šฉ๋œ ๋ฒˆ๋“ค๋Ÿฌ์ด์ž ํ˜„์žฌ๊นŒ์ง€๋„ ๊ฐ€์žฅ ์•ˆ์ •์ ์ธ ๋ฒˆ๋“ค๋Ÿฌ

  • ๋‹ค๋ฅธ ์‹ ๊ทœ ๋ฒˆ๋“ค๋Ÿฌ๋“ค๋„ ์›นํŒฉ์„ ๊ธฐ์ค€์œผ๋กœ ํ•จ, ๊ฑฐ์˜ ์Šคํƒ ๋‹ค๋“œ

  • ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ์˜ ์„ฑ๋Šฅ ๋ฌธ์ œ๋กœ ์ธํ•ด ๋งŽ์€ ๋‹ค๋ฅธ ๋ฒˆ๋“ค๋Ÿฌ์˜ ๋„์ „์„ ๋ฐ›๊ณ ์žˆ์Œ

    • ์‹ค์ œ ํ”„๋กœ๋•์…˜์˜ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์€ ๋Š๋ฆฌ์ง€ ์•Š๊ณ  ์•ˆ์ •์ ์ž„

  • ์›นํŒฉํŒ€์ด Vercel์— ํ•ฉ๋ฅ˜ํ•˜๋ฉด์„œ Rust ๊ธฐ๋ฐ˜์œผ๋กœ turbopack์ด๋ผ๋Š” ์›นํŒฉ ๋Œ€์ฒดํ’ˆ์„ ๋งŒ๋“ค๊ณ  ์žˆ์Œ

  • Module Federation ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด MFA๋ฅผ ๋„์ž…ํ•œ ํšŒ์‚ฌ๋“ค์€ Webpack์„ ์‚ฌ์šฉํ•จ

Why webpack

๋ธŒ๋ผ์šฐ์ €์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด <script> ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์ง€๋ฉด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ , <script> ํƒœ๊ทธ๋ฅผ ์ ์ ˆํ•œ ์ˆœ์„œ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŒŒ์ผ์ด ๋งŽ์•„์ง€๋ฉด ๋„คํŠธ์›Œํฌ ๋ณ‘๋ชฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์€ ํŒŒ์ผ์„ ํ•ฉ์ณ์„œ ํฐ ํ•˜๋‚˜์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์œ ํšจ ๋ฒ”์œ„, ํฌ๊ธฐ, ๊ฐ€๋…์„ฑ, ์œ ์ง€๋ณด์ˆ˜ ๋“ฑ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด IIFE (Immediately Invoked Function Expression), ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„๋กœ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํŒŒ์ผ์„ ํ•ฉ์น  ๋•Œ ์œ ํšจ ๋ฒ”์œ„์— ๋Œ€ํ•œ ๊ฑฑ์ • ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฐฉ์‹์€ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ์ตœ์ ํ™”ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Node.js์—์„œ๋Š” CommonJS๋ฅผ ์ฑ„ํƒํ•˜์—ฌ ๋ชจ๋“ˆ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ CommonJS์—๋Š” ๋ผ์ด๋ธŒ ๋ฐ”์ธ๋”ฉ ์ง€์›์ด ์—†์œผ๋ฉฐ, ์ˆœํ™˜ ์ฐธ์กฐ, ๋™๊ธฐ์ ์ธ ๋ชจ๋“ˆ ํ•ด์„, ๋Š๋ฆฐ ๋กœ๋”ฉ ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Browserify, RequireJS, SystemJS ๋“ฑ์˜ ๋ฒˆ๋“ค๋Ÿฌ์™€ ํˆด์ด ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

ES Module์ด ECMAScript ํ‘œ์ค€์—์„œ ๊ณต์‹ ๊ธฐ๋Šฅ์ด ๋˜์—ˆ์ง€๋งŒ, ์ดˆ๊ธฐ์—๋Š” ๋ธŒ๋ผ์šฐ์ € ์ง€์›์ด ๋ถˆ์™„์ „ํ•˜๊ณ  ๋ฒˆ๋“ค๋ง์ด ์—ฌ์ „ํžˆ ๋” ๋น ๋ฅธ ์ƒํ™ฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์•ฑ์„ ๋ฒˆ๋“ค๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ๋Š” (ESM, CommonJS ๋ชจ๋‘ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ) ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. webpack์€ ์„ฑ๋Šฅ๊ณผ ๋กœ๋”ฉ ์‹œ๊ฐ„์„ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๋กœ ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

Entry

๋ฒˆ๋“ค๋ง์„ ์‹œ์ž‘ํ•  ์ง„์ž…์ 

์—”ํŠธ๋ฆฌํฌ์ธํŠธ๋Š” ์›นํŒฉ์ด ๋‚ด๋ถ€์˜ ๋””ํŽœ๋˜์‹œ ๊ทธ๋ž˜ํ”„๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๋ชจ๋“ˆ

  • ์›นํŒฉ์€ ์—”ํŠธ๋ฆฌํฌ์ธํŠธ๊ฐ€ ์ง๊ฐ„์ ‘์ ์œผ๋กœ ์˜์กดํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“ˆ๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐพ์•„๋‚ธ๋‹ค.

  • ๊ธฐ๋ณธ๊ฐ’์€ src/index ์ด์ง€๋งŒ webpack ์„ค์ •์œผ๋กœ entry ์†์„ฑ์œผ๋กœ ์ปค์Šคํ…€ ๊ฐ€๋Šฅ

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
}

Output

์ƒ์„ฑ๋œ ๋ฒˆ๋“ค์„ ๋‚ด๋ณด๋‚ผ ์œ„์น˜์™€ ์ด ํŒŒ์ผ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์›นํŒฉ์— ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• 

  • ๊ธฐ๋ณธ ์ถœ๋ ฅ ํŒŒ์ผ์€ ./dist/main.js, ๋กœ ์ƒ์„ฑ๋˜๊ณ  ๊ธฐํƒ€ ํŒŒ์ผ์€ ./dist ๋‚ด๋ถ€์— ์ƒ์„ฑ๋˜๋„๋ก ์„ค์ •๋จ

const path = require('path');

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'name.js'
  }
}

__dirname ์ด๋ž€?

  • ๋…ธ๋“œ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์ •๋œ ๊ฐ’

  • webpack.config.js์ด ๋†“์—ฌ์žˆ๋Š” ์œ„์น˜์— ํด๋”๋ฅผ ์˜๋ฏธ

Loaders

  • ์›นํŒฉ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ JSON, JS ํŒŒ์ผ๋งŒ ์ดํ•ดํ•œ๋‹ค.

    • ๊ทธ ์™ธ์— ํŒŒ์ผ ์œ ํ˜•๋“ค์˜ ์ฒ˜๋ฆฌ๋ฅผ ๋กœ๋”์—๊ฒŒ ์œ„์ž„

  • ๋กœ๋”๋ฅผ ์ด์šฉํ•˜๋ฉด ์›นํŒฉ์ด ๋‹ค๋ฅธ ์œ ํ˜•์˜ ํŒŒ์ผ๋“ค์„ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ์›นํŒฉ์ด ์ดํ•ดํ• ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“ˆ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์‚ฌ์šฉ

  • ๋กœ๋”๋Š” ์›นํŒฉ ์„ค์ •์— ๋‘ ๊ฐ€์ง€ ์†์„ฑ์„ ๊ฐ–๋Š”๋‹ค.

    • ๋ณ€ํ™˜์ด ํ•„์š”ํ•œ ์†์„ฑ๋“ค์„ ํŒ๋ณ„ํ•˜๋Š” test (์–ด๋–ค ์ข…๋ฅ˜์˜ ํŒŒ์ผ์„ ์ž„ํฌํŠธํ–ˆ์„ ๋•Œ ์‚ฌ์šฉํ•  ๋กœ๋”์ธ์ง€ ์„ค์ •)

    • ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋กœ๋”๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” use

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'name.js'
  },
  module: {
  // 'require(), import()๋ฌธ ๋‚ด์—์„œ '.txt'ํŒŒ์ผ๋กœ ํ™•์ธ๋˜๋Š” ๊ฒฝ๋กœ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด 
  // ๋ฒˆ๋“ค์— ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „ raw-loader๋ฅผ ์‚ฌ์šฉํ•ด ๋ณ€ํ™˜
    rules: [{ test: /\.txt$/, use: 'row-loader'}]
  }
}

Plugins

  • ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ํ™œ์šฉํ•˜์—ฌ ๋ฒˆ๋“ค์„ ์ตœ์ ํ™”ํ•˜๊ฑฐ๋‚˜, ์—์…‹์„ ๊ด€๋ฆฌ, ๋˜๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ฃผ์ž… ๋“ฑ ๊ด‘๋ฒ”์œ„ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰

  • ํ”Œ๋Ÿฌ๊ทธ์ธ์€ require()๋ฅผ ํ†ตํ•ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์š”์ฒญํ•˜๊ณ  "plugins" ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

  • ๋Œ€๋ถ€๋ถ„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์˜ต์…˜์„ ํ†ตํ•ด ์ปค์Šคํ…€ ๊ฐ€๋Šฅ

  • ๋‹ค๋ฅธ ๋ชฉ์ ์œผ๋กœ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์—ฌ๋Ÿฌ๋ฒˆ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ new ์—ฐ์‚ฐ์ž๋กœ ํ˜ธ์ถœํ•˜์—ฌ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•จ

  • html-webpack-plugin ์€ ์ƒ์„ฑ๋œ ๋ชจ๋“  ๋ฒˆ๋“ค์„ ์ž๋™์œผ๋กœ ์‚ฝ์ž…ํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์šฉ HTML์„ ์ƒ์„ฑ

const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // ๋‚ด์žฅ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์ ‘๊ทผํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋จ

module.exports = {
  module: {
    rules: [{ test: /\.txt$/, use: 'row-loader'}]
  },
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })]
}

Mode

  • mode ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ development, production, ๋˜๋Š” none์„ ์„ค์ •ํ•˜๋ฉด ์›นํŒฉ์— ๋‚ด์žฅ๋œ ํ™˜๊ฒฝ ๋ณ„ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™”ํ•จ

  • ๊ธฐ๋ณธ๊ฐ’์€ production

  • development

    • DefinePlugin์˜ process.env.NODE_ENV๋ฅผ development๋กœ ์„ค์ •

    • ๋ชจ๋“ˆ๊ณผ ์ฒญํฌ์— ์œ ์šฉํ•œ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•จ

  • production

    • process.env.NODE_ENV ๋ฅผ production์œผ๋กœ ์„ค์ •

    • ๋ชจ๋“ˆ๊ณผ ์ฒญํฌ, FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, TerserPlugin ๋“ฑ์— ๋Œ€ํ•ด ๊ฒฐ์ •์  ๋ง๊ธ€์ด๋ฆ„ (mangled name)์„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  • none

    • ๊ธฐ๋ณธ ์ตœ์ ํ™” ์˜ต์…˜์—์„œ ์ œ์™ธ

module.exports = {
  mode: 'proudction'
}

Tree shaking

  • ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ฅผ ๋ฒˆ๋“ค๋ง์—์„œ ์ œ๊ฑฐ

  • ES Module ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋ฉด ๊ฐ„ํŽธํ•˜๊ฒŒ Tree Shaking ์„ค์ • ๊ฐ€๋Šฅ

  • lodash๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ require๋ฅผ ์‚ฌ์šฉํ•œ ํŒจํ‚ค์ง€๋กœ Tree shaking์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.

    • lodash-es๋Š” ES Module ๋ฐฉ์‹์œผ๋กœ ์ œ๊ณต

Transpiler

  • ์›นํŒฉ์€ ๋ฒˆ๋“ค๋งํ•˜๋Š”๋ฐ ์ง‘์ค‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋žœ์ŠคํŒŒ์ผ์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • ๋ฒˆ๋“ค๋ง ์ „ ์ „์ฒ˜๋ฆฌ ์ž‘์—…์œผ๋กœ ๋กœ๋”๋ฅผ ํ†ตํ•ด ํŠธ๋žœ์ŠคํŒŒ์ผ ์ž‘์—…์„ ์ง„ํ–‰

DevServer

  • ์ผ๋ จ์˜ ๋ช…๋ น์–ด๋“ค๋กœ ์ผ์ผ์ด ์ปค๋งจ๋“œ ์ž…๋ ฅํ•˜์—ฌ ์ˆ˜์ •์‚ฌํ•ญ์„ ๋ฐ˜์˜ํ•˜๋Š”๊ฑฐ ๊ท€์ฐฎ์Œ

  • devServer ์„ค์ •์„ ํ†ตํ•ด ์ˆ˜์ •์‚ฌํ•ญ์„ ์•Œ์•„์„œ ๋ฐ˜์˜ํ•˜๋„๋ก ์„ค์ •

    • hot reload replacement

  • webpack-dev-server

  • pnpm exec webpack serve

module.exports = {
  devServer: {
    port: 3000,
    static: {
      directory: path.join(__dirname, "public"),
    },
    compress: true,
  },
}

SourceMap

  • ๋””๋ฒ„๊น…์„ ํ•  ๋•Œ ๋ฒˆ๋“ค๋ง ๊ฒฐ๊ณผ๋ฌผ๋กœ ์•Œ๋ ค์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์‰ฝ์ง€ ์•Š๋‹ค.

  • ์ด๋Ÿด ๋•Œ ์†Œ์Šค๋งต์„ ์„ค์ •ํ•˜์—ฌ ๊ฐœ๋ฐœํ™˜๊ฒฝ์˜ ์ฝ”๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ฒดํฌ ๊ฐ€๋Šฅ

  • Production Mode์ธ ๊ฒฝ์šฐ๋Š” X

module.exports = {
  devtool: "inline-source-map",
}

Serve

// package.json
"script": {
  "dev": "webpack serve",
  "build": "webpack --mode production",
  "start" :"serve dist -p 4000",
}
  • ๊ฐœ๋ฐœ ์„œ๋ฒ„๋Š” public/๊ณผ dist/ ๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•ด์ฃผ์ง€๋งŒ ๋นŒ๋“œํ•  ๋•Œ๋Š” X

  • ๊ทธ๋ž˜์„œ public/ ํŒŒ์ผ๋“ค์„ dist/๋กœ ์˜ฎ๊ฒจ์ฃผ๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.

  • ์œ„ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ด copy-webpack-plugin

const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = {
  plugins: [
    new CopyWebpackPlugin({
      patterns: [{ from: "./public", to: "./" filter: (resourcePath) => {
            return !resourcePath.endsWith("index.html");
          },
       }],
    }),
  ],
};

to ์†์„ฑ์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด output์œผ๋กœ ์ง€์ •๋œ path๋กœ ์นดํ”ผ๋œ๋‹ค.

Env

  • ํ™˜๊ฒฝ๋งˆ๋‹ค ๋‹ค๋ฅธ ์˜ต์…˜์„ ์ง€์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ๊ฐ์ฒด๋ฅผ ์ต์ŠคํฌํŠธ ํ•˜์ง€๋ง๊ณ  ์„ค์ • ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์ž.

  • ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ env, ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ mode ๊ฐ€ ๋“ค์–ด์˜จ๋‹ค.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = (env, { mode }) => ({
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "main.js",
  },
  mode: "development",
  module: {
    rules: [
      // {
      //   test: /\.(?:js|mjs|cjs)$/,
      //   use: {
      //     loader: "babel-loader",
      //     options: {
      //       presets: ["@babel/preset-env"],
      //     },
      //   },
      //   exclude: /node_modules/,
      // },
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "swc-loader",
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: "./public",
          to: "./",
          filter: (resourcePath) => {
            return !resourcePath.endsWith("index.html");
          },
        },
      ],
    }),
  ],
  devServer: {
    static: {
      directory: path.join(__dirname, "public"),
    },
    port: 3000,
    compress: true,
  },
  // ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์„ค์ • ๋ถ„๊ธฐ
  devtool: mode === 'production' ? false : "inline-source-map",
});
 

Last updated