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

๐Ÿ–ฅ dev-ruby

[๊ฐœ๋ฐœํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ] babel๊ณผ Webpack ๋ณธ๋ฌธ

๊ฐœ๋ฐœํ™˜๊ฒฝ๊ตฌ์ถ•

[๊ฐœ๋ฐœํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ] babel๊ณผ Webpack

ruby_s 2022. 1. 25. 15:49
728x90
๋ฐ˜์‘ํ˜•
SMALL

์›น ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กœ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฐ›์•„์™€ ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๋Š” ์ผ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.
์ฒ˜์Œ์—๋Š” CRA(create-react-app)์œผ๋กœ ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ–ˆ์ง€๋งŒ "CRA ์—†์ด ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•ด๋ณด๊ธฐ" ๊ณต๋ถ€๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ•ด๋ณธ๋‹ค.

1. package.json ์ƒ์„ฑ

์ฒซ ๋ฒˆ์งธ๋Š” package.json ํŒŒ์ผ๋ถ€ํ„ฐ ์ƒ์„ฑํ•ด์•ผํ•œ๋‹ค.

npm init -y ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ package.json๋ฅผ ์ƒ์„ฑํ•˜์ž. yarn init -y ์„ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค. 

npm init ๋งŒ ์ž…๋ ฅํ•˜๊ฒŒ ๋˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ package.jsonํŒŒ์ผ์˜ name์ด๋‚˜ version, license๋“ฑ์„ ๋ฌป๋Š”๋ฐ, -y ๋ช…๋ น์„ ๋ถ™์ด๋ฉด npm์˜ package.json ๊ธฐ๋ณธ๊ฐ’์— ๋”ฐ๋ผ ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ npm init docs์—์„œ ํ™•์ธํ•˜์ž.

npm init -y ๋กœ ์ƒ์„ฑ๋œ ํŒŒ์ผ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

//package.json

{
  "name": "babel-webpack-practice",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

์ด์ œ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถ™์—ฌ๋‚˜๊ฐ€๋ฉด ๋œ๋‹ค.


2. babel ์„ค์น˜

babel ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ npm install [์„ค์น˜ํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ] ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์ž.

์šฐ์„  ์„ค์น˜ํ•ด์•ผ ํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” @babel/core, @babel/cli์ด๋‹ค.
@babel/core ๋Š” babel์ด ํŠธ๋žœ์ŠคํŒŒ์ผ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์—ญํ• ์ด๊ณ ,
@babel/cli ๋Š” CLI(Command Line Interface, git bash๋‚˜ cmd ๊ฐ™์€ ๊ฑฐ์ž„)์—์„œ babel์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์—ญํ• ์ด๋‹ค.

๋‚˜๋Š”
npm install --save-dev @babel/core @babel/cli ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

--save-dev(์ค„์—ฌ์„œ -D) ๋ช…๋ น์–ด๋Š” ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๊ฐœ๋ฐœ๋‹จ๊ณ„์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค.


-D ๋ช…๋ น์–ด๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๋ฉด package.json์˜ dependencies ๊ฐ์ฒด์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ด๋ฆ„์ด ์ถ”๊ฐ€๋œ๋‹ค. ์ด ํŒจํ‚ค์ง€๊ฐ€ ๋ฐฐํฌ๋˜์–ด์„œ ์„ค์น˜๋์„ ๋•Œ dependencies ๊ฐ์ฒด์— ํฌํ•จ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ๊ฐ™์ด ์„ค์น˜๋œ๋‹ค.


-D ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๋ฉด devDependencies ๊ฐ์ฒด์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋˜๊ณ , ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ๋ฐฐํฌ๋œ ํŒจํ‚ค์ง€์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค.

babel์€ ์ƒ์œ„ ES ๋ฌธ๋ฒ•์ด ์‚ฌ์šฉ๋œ jsํŒŒ์ผ์„ ํ•˜์œ„ ES ๋ฌธ๋ฒ•์ธ jsํŒŒ์ผ๋กœ ๋ณ€ํ™˜์‹œ์ผœ์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ๋‹จ๊ณ„์—์„œ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— -D ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ค์น˜ํ•˜์ž.

// pacakage.json

{
  "name": "babel-webpack-practice",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/cli": "^7.16.8",
    "@babel/core": "^7.16.12"
  }
}

์ด๋ ‡๊ฒŒ devDependencies์— ์„ค์น˜ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋งŒ์œผ๋กœ babel์„ ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์—†๊ณ  plugin์ด ํ•„์š”ํ•˜๋‹ค.


2-1. plugin๊ณผ preset

babel์˜ plugin์€ ์‹ค์ œ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜์‹œํ‚ค๋Š” ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•œ๋‹ค.
babel plugin Docs๋ฅผ ๋ณด๋ฉด plugin์ด ์„ธ์„ธํ•˜๊ฒŒ ๋‚˜๋‰˜์–ด์ ธ ์žˆ์–ด ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ด ๋ฒˆ๊ฑฐ๋กญ๊ณ , ๋‚ด๊ฐ€ ํ•„์š”ํ•œ plugin์„ ํ•˜๋‚˜ํ•˜๋‚˜ ์ฐพ๋Š” ๊ฒƒ๋„ ํž˜๋“ค๋‹ค.
(์˜ˆ๋ฅผ ๋“ค๋ฉด, ๋‚ด๊ฐ€ ES6์˜ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, ์ด๋ฅผ ๋ณ€ํ™˜์‹œํ‚ค๊ธฐ ์œ„ํ•ด @babel/plugin-transform-arrow-functions ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์„ค์น˜๊ฐ€ ํ•„์š”ํ•˜๊ณ ,

๋ธ”๋Ÿญ ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด @babel/plugin-transform-block-scoping ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์„ค์น˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.)


๊ทธ๋ž˜์„œ preset์ด ๋“ฑ์žฅํ•˜๊ฒŒ ๋œ๋‹ค.
preset์€ ๋ชฉ์ ์— ๋”ฐ๋ผ plugin๋“ค์„ ๋ชจ์•„๋†“์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.


preset๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ ์ค‘์—์„œ๋„ @babel/preset-env ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ targets ์˜ต์…˜์„ ์ด์šฉํ•ด์„œ ์–ด๋–ค ๋ธŒ๋ผ์šฐ์ €์—๋„ ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ์ž์ฃผ ์“ฐ์ธ๋‹ค.
๊ทธ๋Ÿผ @babel/preset-env์„ ์„ค์น˜ํ•ด์„œ ์‚ฌ์šฉํ•ด๋ณด์ž!

npm install -D @babel/preset-env ๋กœ ์„ค์น˜ํ•œ๋‹ค. ๊ทธ ๋‹ค์Œ babel.config.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ๋‚ด๊ฐ€ preset์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์„ ์„ ์–ธํ•˜์ž.
// babel.config.js

const presets = [
  [
    "@babel/preset-env",
    {
      targets: {
        chrome: "87",
      },
      useBuiltIns: "usage",
      corejs: "3.6.4",
    },
  ],
];

module.exports = { presets };

์˜ต์…˜ ์ค‘, useBuiltIns๋Š” polyfill์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ด๋‹ค.
useBuiltIns ์˜ต์…˜์€ "usage" | "entry" | false ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ณ  default๋Š” false๋‹ค.

"usage"๋Š” ๋‚ด ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด์„œ ํ•„์š”ํ•œ polyfill plugin๋งŒ์„ ์ ์šฉ์‹œํ‚จ๋‹ค.
"entry"๋Š” targets ๋ธŒ๋ผ์šฐ์ €์— ํ•„์š”ํ•œ polyfill plugin์„ ๋ชจ๋‘ ์ ์šฉ์‹œํ‚จ๋‹ค.
false๋Š” polyfill์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋œป์ด๋‹ค.


corejs ์˜ต์…˜์€ polyfill์„ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฝ์ž…๋˜๋Š” corejs์˜ ๋ฒ„์ „์„ ์„ ํƒํ•˜๋Š” ์˜ต์…˜์ด๋‹ค.
useBuiltIns ์˜ต์…˜์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์„ ๋•Œ ์ ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.
2, 3 ํ˜น์€ { version: 2 | 3, proposals: boolean } ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ณ  default๋Š” 2๋‹ค.
2๋Š” ์—…๋ฐ์ดํŠธ๊ฐ€ ์ค‘๋‹จ๋˜์–ด์„œ 3์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

@babel/preset-env์˜ ์˜ต์…˜๋“ค๊ณผ ์ž์„ธํ•œ ์ •๋ณด๋Š” @babel/preset-env Docs์—์„œ ํ™•์ธํ•˜์ž.

์ด๋ ‡๊ฒŒ preset ์˜ต์…˜ ๋ฐฐ์—ด์„ module.exports ํ•ด์ฃผ๋ฉด preset ์ ์šฉ์ด ์™„๋ฃŒ๋œ๋‹ค.


3. webpack

webpack์€ entryํŒŒ์ผ์„ ์ง€์ •ํ•ด์„œ entryํŒŒ์ผ์ด ์˜์กด์„ฑ์„ ๋„๊ณ  ์žˆ๋Š” ๋ชจ๋“ˆ๋“ค์„ ๋ชจ๋‘ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด๋‚ด๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค.

npm install -D webpack webpack-cli ๋ช…๋ น์–ด๋กœ webpack๊ณผ webpack-cli๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

์ด์ œ ๋ฒˆ๋“ค๋งํ•  jsํŒŒ์ผ์„ ๋งŒ๋“ ๋‹ค.

// src/index.js

const pow = function (a) {
  const result = a * a;
  return result;
};

console.log(pow(3));

๊ทธ๋ฆฌ๊ณ  webpack.config.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ์˜ต์…˜์„ ์„ค์ •ํ•œ๋‹ค.

// webpack.config.js

const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist/js"),
    filename: "bundle.js",
  },
  devtool: "inline-source-map",
  mode: "development",
};

entry ์˜ต์…˜์€ ๋ฒˆ๋“ค๋ง์˜ ์‹œ์ž‘์ ์ด ๋  ํŒŒ์ผ์„ ์„ค์ •ํ•˜๋Š” ์˜ต์…˜์ด๋‹ค. ๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด์˜ ํ˜•ํƒœ๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ entry๋ฅผ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.


output ์˜ต์…˜์€ ๋ฒˆ๋“ค๋ง์ด ์™„๋ฃŒ๋œ ํŒŒ์ผ์— ๋Œ€ํ•œ ์˜ต์…˜์ด๋‹ค.
output.path๋Š” ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ์ด ์ €์žฅ๋  ์œ„์น˜์ด๊ณ , output.filename์€ ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ์˜ ์ด๋ฆ„์ด๋‹ค.
(์œ„์˜ ์˜ˆ์‹œ์—์„œ๋Š” dist/js/bundle.js ๊ฒฝ๋กœ๋กœ ํŒŒ์ผ์ด ์ƒ์„ฑ๋  ๊ฒƒ์ด๋‹ค.)


devtool ์˜ต์…˜์—๋Š” ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ source-map ์ค‘ ํ•˜๋‚˜๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค. source-map์€ ๋ฒˆ๋“ค๋ง ๋œ ์ฝ”๋“œ์˜ ์›๋ณธ ์œ„์น˜๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
์•„๋ž˜ ์‚ฌ์ง„์˜ ๋งจ ์˜ค๋ฅธ์ชฝ์„ ๋ณด๋ฉด index.js:6์ด๋ผ๊ณ  ์จ์žˆ๋Š”๋ฐ, index.js ํŒŒ์ผ์˜ 6๋ฒˆ์งธ ์ค„์—์„œ ์ฝ˜์†”์— ์‹คํ–‰๋์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
๋ญ .. ์ด๋Ÿฐ ์—ญํ• ์„ ํ•œ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ฃผ๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๋งŽ์ด ์ฐธ๊ณ ํ–ˆ๋˜ ๊ฒƒ๋“ค์ธ๋ฐ, ์ด๋ ‡๊ฒŒ ํ™˜๊ฒฝ ๊ตฌ์ถ•์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜๋„ ์žˆ์Œ์„ ๋Š๋‚€๋‹ค.


mode์˜ต์…˜์€ "production" | "development"  ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ๋‹ค. ๋ชฉ์ ์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ตœ์ ํ™”์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

์ด์ œ npx webpack ๋ช…๋ น์–ด๋กœ webpack์„ ์‹คํ–‰ํ•˜์ž.

๊ทธ๋Ÿผ dist/js/bundle.js ์ด ์ƒ์„ฑ๋œ๋‹ค.
bundle.js๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด index.html ์„ ๋งŒ๋“ค์–ด์„œ bundle.js๋ฅผ script๋กœ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.

// index.html

<!DOCTYPE html>
<html>
<body>
  <script src="./dist/js/bundle.js"></script>
</body>
</html>

๊ทธ๋ฆฌ๊ณ  index.html์„ ๋ธŒ๋ผ์šฐ์ €์— ๋„์›Œ ๋ณด๋ฉด (๊ทธ๋ƒฅ ํด๋ฆญํ•ด์„œ ๋„์›€) ์œ„์˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์ฝ˜์†”์— 9๊ฐ€ ์ฐํžˆ๊ฒŒ ๋œ๋‹ค.
source-map ๋•๋ถ„์— ์ด console.log๊ฐ€ index.js:6์—์„œ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ๊ฒƒ๋„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ webpack์˜ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ์ด๋‹ค. ์ด์ œ webpack์˜ ์—„์ฒญ๋‚œ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.


3-1. loader

webpack์€ entry ํŒŒ์ผ์ด ์˜์กด์„ฑ์„ ๋„๊ณ  ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ๋ชจ๋“ˆ๋กœ ๋ฐ›์•„๋“ค์—ฌ ๋ฌถ์–ด๋‚ธ๋‹ค.
๋‚ด๊ฐ€ React๋ฅผ ์“ฐ๊ณ  ์žˆ๊ณ , app ์ปดํฌ๋„ŒํŠธ๊ฐ€ css๋‚˜ scss๋ฅผ importํ•˜๊ฑฐ๋‚˜ ํ˜น์€ TypeScript๋ฅผ ์‚ฌ์šฉํ•ด์„œ js๊ฐ€ ์•„๋‹Œ ts๋‚˜ tsx๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด?

๊ถ๊ธˆํ•ด์กŒ์œผ๋‹ˆ css ํŒŒ์ผ์„ entry๋กœ ์ง€์ •ํ•ด์„œ webpack์„ ์‚ฌ์šฉํ•ด๋ณด์ž.

/* src/css/main.css */

@import url("./background.css");

/* src/css/background.css */

body {
  background-color: thistle;
}

์•„๋ž˜๋Š” webpack.config.js ์„ค์ •์ด๋‹ค. entry์— ./src/css/main.css ๋ฅผ ์ถ”๊ฐ€ํ•ด์คฌ๋‹ค.

// webpack.config.js

const path = require("path");

module.exports = {
  entry: ["./src/js/main.js", "./src/css/main.css"],
  output: {
    path: path.resolve(__dirname, "dist/js"),
    filename: "bundle.js",
  },
  devtool: "source-map",
  mode: "development",
};

์ด ์ƒํƒœ์—์„œ webpack์„ ์ž‘๋™์‹œํ‚ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค. ์ด ์œ ํ˜•์˜ ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด loader๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ์ด๋ฉฐ, ํ˜„์žฌ ์ด ํŒŒ์ผ์— ๋Œ€ํ•œ loader๊ฐ€ ์„ค์ •๋˜์–ด์žˆ์ง€ ์•Š๋‹ค๋Š” ์„ค๋ช…๊ณผ ํ•จ๊ป˜.


3-1-1. css loader

๊ทธ๋Ÿผ css์—๋Š” ์–ด๋–ค loader๊ฐ€ ํ•„์š”ํ• ๊นŒ? css๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” css-loader์™€ style-loader๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

npm install -D css-loader style-loader ๋กœ ์„ค์น˜ํ•œ ๋’ค ์ ์šฉํ•ด๋ณด์ž.

// webpack.config.js

const path = require("path");

module.exports = {
  entry: ["./src/js/main.js", "./src/css/main.css"],
  output: {
    path: path.resolve(__dirname, "dist/js"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  devtool: "source-map",
  mode: "development",
};

loader๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด module ๊ฐ์ฒด์•ˆ์— rules ๋ฐฐ์—ด์„ ๋‘์–ด์•ผํ•œ๋‹ค. rules ๋ฐฐ์—ด ์•ˆ์—๋Š” ๊ฐ์ฒด๋“ค์ด ๋“ค์–ด์žˆ๊ณ , ๊ฐ์ฒด๋Š” ํ•„์ˆ˜์ ์œผ๋กœ test์™€ use๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.
test๋Š” loader๋ฅผ ์ ์šฉ์‹œํ‚ฌ ํŒŒ์ผ ํ™•์žฅ์ž์˜ ์ •๊ทœํ‘œํ˜„์‹์ด๊ณ ,
use๋Š” test ํ™•์žฅ์ž๋ช…์„ ๊ฐ€์ง„ ํŒŒ์ผ์— ์ ์šฉ์‹œํ‚ฌ loader๋‹ค.
use๋Š” ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ด์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ loader๋ฅผ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ณ , ๋ฐฐ์—ด์˜ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” loader๋ถ€ํ„ฐ ์ ์šฉ๋œ๋‹ค.
๊ฒฐ๊ตญ, ์ด ์˜ต์…˜์€ .css๋กœ ๋๋‚˜๋Š” ํŒŒ์ผ์— 1. css-loader 2. style-loader ์ˆœ์„œ๋กœ loader๋ฅผ ์ ์šฉ์‹œํ‚ค๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค.
css-loader๋Š” css ์Šคํƒ€์ผ์‹œํŠธ๋ฅผ JS๋กœ ๋ณ€ํ™˜์‹œ์ผœ์ฃผ๊ณ , style-loader๋Š” JS๋กœ ๋ณ€ํ™˜๋œ css ์Šคํƒ€์ผ์‹œํŠธ๋ฅผ DOM์— ๋™์ ์œผ๋กœ ์ถ”๊ฐ€์‹œ์ผœ์ค€๋‹ค.

์ด์ œ ๋‹ค์‹œ webpack์„ ์‹คํ–‰์‹œํ‚จ๋‹ค. (npx webpack)
๊ทธ๋Ÿผ ๋ฐฐ๊ฒฝํ™”๋ฉด ์ƒ‰์ƒ์ด ๋ฐ”๋€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


3-1-2. babel loader

์ด์ œ webpack์œผ๋กœ ๋ฌถ์–ด๋‚ผ ๋•Œ js์— babel์„ ์ ์šฉ์‹œํ‚ค๊ธฐ ์œ„ํ•ด babel-loader๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค.

npm install -D babel-loader ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  webpack.config.js์—์„œ babel-loader๋ฅผ ์ ์šฉ์‹œํ‚ค์ž.
// webpack.config.js

const path = require("path");

module.exports = {
  entry: ["./src/index.js", "./src/css/main.css"],
  output: {
    path: path.resolve(__dirname, "dist/js"),
    filename: "bundle.js",
  },
  module: {
    rules: [{
        test: /\.js$/,
        use: [
            {
                loader: "babel-loader",
                options: {
                    presets: [
                        [
                            "@babel/preset-env",
                            {
                                useBuiltIns: "usage",
                                corejs: "3.6.4",
                                targets: {
                                chrome: "87",
                                },
                            },
                        ],
                    ],
                },
            },
        ],
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  devtool: "inline-source-map",
  mode: "development",
};


rules ๋ฐฐ์—ด์— ์ƒˆ ๊ฐ์ฒด๊ฐ€ ์ƒ๊ฒผ๋‹ค.
1. ๋จผ์ € test๋Š” .js ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง„ ํŒŒ์ผ๋“ค์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๊ณ  ์žˆ๋‹ค.
2. use๋Š” css-loader๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์™€๋Š” ๋‹ค๋ฅธ ํ˜•ํƒœ๋‹ค. use ๋ฐฐ์—ด์•ˆ์— ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด์žˆ๋‹ค. ์ด๊ฒƒ์€ babel-loader์˜ option์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋‹ค.

์ด ๊ฐ์ฒด๋ฅผ ์‚ดํŽด๋ณด๋ฉด,
3. loader์—๋Š” ์ ์šฉํ•  loader์ธ "babel-loader"๊ฐ€ ๋“ค์–ด์žˆ๋‹ค.
4. options๋Š” babel-loader์˜ ์˜ต์…˜์„ ๋‹ด๋Š” ๊ฐ์ฒด๋‹ค. presets ๋ฐฐ์—ด์— ์‚ฌ์šฉํ•  preset๋“ค์„ ์ž…๋ ฅํ•œ๋‹ค.
๋‚˜๋Š” @babel/preset-env๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

์ด์™ธ์—๋„ plugin๊ณผ preset-env์˜ polyfill ๊ธฐ๋Šฅ๋„ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
5. exclude๋Š” webpack์˜ ๋ฒˆ๋“ค์—์„œ ์ œ์™ธํ•  ํด๋”๋‚˜ ํŒŒ์ผ์ด๋‹ค.
node_modules ํด๋”์—๋Š” ์ˆ˜ ์‹ญ ์ˆ˜ ๋ฐฑ๊ฐœ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ๋“ค์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํ†ต node_modules๋Š” .js ํ™•์žฅ์ž์— ์ ์šฉ์‹œํ‚ฌ loader์—์„œ ์ œ์™ธ์‹œํ‚จ๋‹ค.

webpack loaders Docs์—์„œ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ๋‹ค.


3-2. plugin

plugin์€ webpack์˜ ํŽธ์˜์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค. ๊ทธ ์ค‘์—์„œ ํŽธ๋ฆฌํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋Š” ๊ฒƒ ๋ช‡ ๊ฐœ๋งŒ ์ ์šฉ์‹œ์ผœ ๋ณด์ž.

3-2-1. HtmlWebpackPlugin

HtmlWebpackPlugin์€ webpack์„ ์‹คํ–‰ํ•œ ๋’ค ๋ฒˆ๋“ค๋ง ๋œ jsํŒŒ์ผ์„ ํฌํ•จํ•œ html์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.
์ด์ „์— bundle.js ํŒŒ์ผ์„ webpack์œผ๋กœ ์ƒ์„ฑํ•œ ๋’ค, index.html ํŒŒ์ผ์„ ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ bundle.js๋ฅผ ํฌํ•จ์‹œ์ผฐ๋‹ค. ์ด ๊ณผ์ •์„ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

npm install -D html-webpack-plugin ๋ช…๋ น์–ด๋กœ ์„ค์น˜ํ•œ ๋’ค ์ ์šฉ์‹œํ‚จ๋‹ค.

// webpack.config.js

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

module.exports = {
  entry: ["./src/index.js", "./src/css/main.css"],
  output: {
    path: path.resolve(__dirname, "dist/js"),
    filename: "bundle.js",
  },
  module: {
    rules: [{
        test: /\.js$/,
        use: [
            {
                loader: "babel-loader",
                options: {
                    presets: [
                        [
                            "@babel/preset-env",
                            {
                                useBuiltIns: "usage",
                                corejs: "3.6.4",
                                targets: {
                                chrome: "87",
                                },
                            },
                        ],
                    ],
                },
            },
        ],
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  plugins: [new HtmlWebpackPlugin()],
  devtool: "inline-source-map",
  mode: "development",
};

๋‘๋ฒˆ์งธ ์ค„์˜

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

๊ณผ plugins ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

plugins: [new HtmlWebpackPlugin()],

์ด์ œ ๋˜ npx webpack์„ ์‹คํ–‰์‹œ์ผœ์ฃผ๋ฉด, output ๊ฒฝ๋กœ ์•ˆ์— index.htm ์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.
HtmlWebpackPlugin Docs์—์„œ ์˜ต์…˜์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

3-2-2 CleanWebpackPlugin

webpack์„ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ์ด์ „์— ๋ฒˆ๋“ค๋งํ–ˆ๋˜ ๊ฒฐ๊ณผ๋ฌผ์ด ๊ณ„์† ๋‚จ์•„์žˆ์–ด ๋ถˆํŽธํ•œ ๋•Œ๊ฐ€ ์žˆ๋‹ค.
CleanWebpacPlugin์€ ์ƒˆ๋กœ ๋ฒˆ๋“ค๋งํ–ˆ์„ ๋•Œ ์ด์ „์— ๋ฒˆ๋“ค๋งํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ์—†์• ์ค€๋‹ค.


3-3. WebpackDevServer

๋ฐฉ๊ธˆ webpack์œผ๋กœ ์‹ค์Šต์„ ํ•˜๋ฉด์„œ ๊ณ„์† ๋ฐ˜๋ณต์ค‘์ธ ๊ฒƒ์ด ์žˆ๋‹ค.

  1. webpack.config.js ์„ค์ • ์ˆ˜์ •
  2. webpack์„ ์‹คํ–‰
  3. ๋ฒˆ๋“ค๋œ jsํŒŒ์ผ์„ index.html์— ์ ์šฉ์‹œํ‚จ ํ›„ ํ™•์ธ

์ด ๊ณผ์ •์„ ๊ณ„์† ๋ฐ˜๋ณต์ค‘์ด๋‹ค.
๋ถˆํŽธํ•จ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด webpack ์ž์ฒด์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ์„ ๋ฐ˜์˜ํ•ด์ฃผ๋Š” WebpackDevServer๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.

npm install -D webpack-dev-server ๋ช…๋ น์–ด๋กœ webpack-dev-server ๋ฅผ ์„ค์น˜ ํ›„, npx webpack serve ๋ช…๋ น์–ด๋กœ webpack์„ ์‹คํ–‰ํ•˜๋ฉด ๋ฒˆ๋“ค๋œ js ํŒŒ์ผ์ด ์ž๋™์œผ๋กœ index.html์— ์‚ฝ์ž…๋˜์–ด localhost์—์„œ ์‹คํ–‰๋œ๋‹ค.

WebpackDevServer Docs์—์„œ ์ž์„ธํ•œ ์„ค๋ช…์„ ๋ณด๋„๋ก ํ•˜์ž!



์—ฌ๊ธฐ๊นŒ์ง€ babel, webpack ์— ๋Œ€ํ•ด ์•Œ์•„๋ดค๋‹ค.
์ •๋ง ๊ฐœ๋ฐœ์€ ์‰ฝ์ง€์•Š๋‹ค..ใ…Ž ์ด๋Ÿฐ๊ฑฐ ํ•˜๋‚˜ ํ•˜๋‚˜ ๊ณต๋ถ€ํ• ๊ฒŒ ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒƒ ๊ฐ™๋‹ค.
728x90
๋ฐ˜์‘ํ˜•
LIST