๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Front-end

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ์™€ Webpack

 

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ - webpack

 

JavaScript ํ”„๋ ˆ์ž„์›Œํฌ์ธ React, Vue, Svelte, Angular ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(module bundler)๋Š” ํ•„์ˆ˜์ ์œผ๋กœ ์–ธ๊ธ‰๋˜๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” JavaScript ๋ชจ๋“ˆ์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์ผ JavaScript ํŒŒ์ผ๋กœ ๋ฌถ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. 

 

 

๋ชจ๋“ˆ(Module)

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋Šฅ์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ์ž‘์„ฑํ•ด์•ผํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ํ•œ ๊ฐœ์˜ ํŒŒ์ผ์— ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹  ๊ธฐ๋Šฅ(๋ณ€์ˆ˜, ๊ฐ์ฒด, ๋ฐฐ์—ด, ํ•จ์ˆ˜, ํด๋ž˜์Šค ๋“ฑ)์— ๋”ฐ๋ผ ๋ณ„๋„์˜ ํŒŒ์ผ์— ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ธฐ์ค€์— ๋”ฐ๋ผ ํŒŒ์ผ์ด ์ƒ๋‹นํžˆ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•œ ๊ฐœ์˜ ํŒŒ์ผ์— ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ฒด๊ณ„์ ์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.

 

๊ฒฐ๊ตญ ๋ชจ๋“ˆ์€ ๋ถ„๋ฆฌ๋œ ํŒŒ์ผ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. JavaScript์—์„œ ํ˜„์žฌ ๋ชจ๋“ˆ์„ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก export ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋ถ„๋ฆฌ๋œ ๋ชจ๋“ˆ์„ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•ด import ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

 

 

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ์˜ ํ•„์š”์„ฑ

React, Angular, Vue์™€ ๊ฐ™์€ JavaScript ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋“ฑ์žฅํ•˜๊ธฐ ์ „์—๋Š” ์›น ์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด HTML, CSS, JavaScript ๋ฟ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํŒŒ์ผ ๊ด€๋ฆฌ๊ฐ€ ๋ณต์žกํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ์กฐ๊ธˆ ๋” ๋‚˜์€ ์„ฑ๋Šฅ, ์†๋„๋ฅผ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ JavaScript ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋“ฑ์žฅํ•˜์˜€์œผ๋ฉฐ, ์›น ์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ํŒŒ์ผ๋“ค์ด ์ ์  ๋งŽ์•„์ง‘๋‹ˆ๋‹ค.

 

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

 

๋ชจ๋“ˆ๊ฐ„ ์ข…์†์„ฑ์ด๋ž€ ์˜ˆ๋ฅผ ๋“ค์–ด ์„ค๋ช…ํ•˜์ž๋ฉด, A.js ํŒŒ์ผ์€ B.js๋ฅผ import ํ•˜๊ณ  B.js ํŒŒ์ผ์€ C.js ํŒŒ์ผ์„ import ํ•˜๊ณ .. ์ด๋ ‡๊ฒŒ ๋ชจ๋“ˆ๋ผ๋ฆฌ ์„œ๋กœ ์ข…์†๋˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฉฐ, ๋ชจ๋“ˆ ๊ฐ„ ์ข…์†์„ฑ์ด ๋ณต์žกํ•œ ๊ฒฝ์šฐ ์–ด๋–ค ๋ชจ๋“ˆ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์ถ”์ ํ•˜๋Š” ๊ฒƒ๋„ ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ๋ณ‘ํ•ฉํ•˜๋”๋ผ๋„ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ์ƒ๋‹นํžˆ ๋งŽ์€ ์‹œ๊ฐ„์„ ์†Œ๋ชจํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ ์ƒ๋‹นํžˆ ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

 

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(module bundler)

 

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

 

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” JS ํŒŒ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ CSS ํŒŒ์ผ๊ณผ, ์ด๋ฏธ์ง€, ๊ธ€๊ผด ๋“ฑ ์—ฌ๋Ÿฌ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด์„œ๋„ ๋ฒˆ๋“ค๋ง ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ์›นํŒฉ, ๋กค์—…์ฒ˜๋Ÿผ ๋‹ค์–‘ํ•œ ๊ฐœ๋ฐœ ๋„๊ตฌ๊ฐ€ ์กด์žฌํ•˜๋ฉฐ ๋ฒˆ๋“ค๋ง ๋™์ž‘ ๋ฐฉ์‹์€ ๊ฐœ๋ฐœ ๋„๊ตฌ๋งˆ๋‹ค ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

 

 

์›นํŒฉ์˜ ๋ฒˆ๋“ค๋ง ๋ฐฉ์‹

3๊ฐœ์˜ ํŒŒ์ผ circle.js, square.js ๋ฐ app.js๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

circle.js
const PI = 3.141;
export default function area(radius) {
  return PI * radius * radius;
}

 

square.js
export default function area(side) {
  return side * side;
}

 

app.js
import squareArea from './square';
import circleArea from './circle';
console.log('Area of square: ', squareArea(5));
console.log('Area of circle', circleArea(5));

 

์ด ํŒŒ์ผ๋“ค์„ ์›นํŒฉ์œผ๋กœ ๋ฒˆ๋“ค๋งํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

webpack-bundle.js
const modules = {
  'circle.js': function(exports, require) {
    const PI = 3.141;
    exports.default = function area(radius) {
      return PI * radius * radius;
    }
  },
  'square.js': function(exports, require) {
    exports.default = function area(side) {
      return side * side;
    }
  },
  'app.js': function(exports, require) {
    const squareArea = require('square.js').default;
    const circleArea = require('circle.js').default;
    console.log('Area of square: ', squareArea(5))
    console.log('Area of circle', circleArea(5))
  }
}

webpackStart({
  modules,
  entry: 'app.js'
});
๊ฐ€์žฅ ๋จผ์ € ๋ˆˆ์— ๋„๋Š” ๊ฒƒ์€ "๋ชจ๋“ˆ ๋งต"์ž…๋‹ˆ๋‹ค.
  • ํ•จ์ˆ˜์— ์˜ํ•ด ๋ž˜ํ•‘๋œ ๋ชจ๋“ˆ ์ž์ฒด์— ๋ชจ๋“ˆ ์ด๋ฆ„์„ ๋งคํ•‘ํ•˜๋Š” ๋”•์…”๋„ˆ๋ฆฌ ์ž…๋‹ˆ๋‹ค.
  • "๋ชจ๋“ˆ ๋งต"์€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์™€ ๊ฐ™์œผ๋ฉฐ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ชจ๋“ˆ์„ ์‰ฝ๊ฒŒ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋‘˜์งธ, ๊ฐ ๋ชจ๋“ˆ์€ ํ•จ์ˆ˜๋กœ ๋ž˜ํ•‘๋ฉ๋‹ˆ๋‹ค.
  • ์ด ํ•จ์ˆ˜๋Š” ๋ชจ๋“ˆ ์Šค์ฝ”ํ”„๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ•ฉ๋‹ˆ๋‹ค
  • ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ "๋ชจ๋“ˆ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜"๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“ˆ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ export ํ•˜๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ requireํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ช‡ ๊ฐ€์ง€ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์…‹์งธ, ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ๋ชจ๋“  ๊ฒƒ์„ ํ•จ๊ป˜ ๋ถ™์ด๋Š” ํ•จ์ˆ˜์ธ webpackStart๋ฅผ ํ†ตํ•ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
  • ์ข…์ข… "๋Ÿฐํƒ€์ž„"์ด๋ผ๊ณ  ํ•˜๋Š” ํ•จ์ˆ˜์ด๋ฉฐ, ๋ฒˆ๋“ค์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.
  • "๋ชจ๋“ˆ ๋งต"๊ณผ ์—”ํŠธ๋ฆฌ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

webpack-bundle.js

function webpackStart({ modules, entry }) {
  const moduleCache = {};
  const require = moduleName => {
    // if in cache, return the cached version
    if (moduleCache[moduleName]) {
      return moduleCache[moduleName];
    }
    const exports = {};
    // this will prevent infinite "require" loop
    // from circular dependencies
    moduleCache[moduleName] = exports;

    // "require"-ing the module,
    // exported stuff will assigned to "exports"
    modules[moduleName](exports, require);
    return moduleCache[moduleName];
  };

  // start the program
  require(entry);
}
  • webpackStart๋Š” "require" ํ•จ์ˆ˜์™€ ๋ชจ๋“ˆ ์บ์‹œ๋ผ๋Š” ๋‘ ๊ฐ€์ง€๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • "require" ํ•จ์ˆ˜๋Š” CommonJS์˜ require์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
    • "require"๋Š” ๋ชจ๋“ˆ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜ค๊ณ  ๋ชจ๋“ˆ์—์„œ ๋‚ด๋ณด๋‚ธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: circle.js์˜ ๊ฒฝ์šฐ { default: function area(radius){ ... } }์ž…๋‹ˆ๋‹ค.
  • ๋‚ด๋ณด๋‚ธ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ชจ๋“ˆ ์บ์‹œ์— ์บ์‹œ๋ฉ๋‹ˆ๋‹ค.
    • ๋™์ผํ•œ ๋ชจ๋“ˆ ์ด๋ฆ„์˜ "require"๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ํ˜ธ์ถœํ•˜๋ฉด "๋ชจ๋“ˆ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜"๊ฐ€ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • "require"๊ฐ€ ์ •์˜๋œ ์ƒํƒœ์—์„œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‹œ์ž‘ํ•˜๋ฉด ์—”ํŠธ๋ฆฌ ๋ชจ๋“ˆ์„ "require"ํ•ฉ๋‹ˆ๋‹ค.

 

๋กœ๋”๋ž‘ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๋ฒˆ๋“ค๋ง ์ด์ „ ํŒŒ์ผ๋‹จ์œ„, ์ดํ›„ ์ „์ฒด ๊ฒฐ๊ณผ๋ฌผ์— ๋Œ€ํ•œ ์ „์ฒ˜๋ฆฌ ํ›„์ฒ˜๋ฆฌ๋งŒ ์‹œํ–‰ํ•จ

 

๋‹ค์Œ ๊ธ€์€ ๋กœ๋”๋ž‘ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋Œ€ํ•ด ์จ์•ผ๊ฒ ๋‹ค

 


์ •๋ฆฌ

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

 

 

 

 

 

์ถœ์ฒ˜:

 

๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(module bundler)๋ž€?

JavaScript ํ”„๋ ˆ์ž„์›Œํฌ์ธ React, Vue, Svelte, Angular ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ(module bundler)๋Š” ํ•„์ˆ˜์ ์œผ๋กœ ์–ธ๊ธ‰๋˜๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ๊ฐœ๋…์ ์œผ๋กœ ์ƒ๊ฐ๋ณด๋‹ค ์‰ฌ์šด ๋‚ด์šฉ์ด์ง€๋งŒ ์›นํŒฉ, ๋กค์—…,

developer-talk.tistory.com

 

 

[๋ฒˆ์—ญ]๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ๋ฌด์—‡์ด๋ฉฐ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”๊ฐ€?

ํ•ด๋‹น ๊ธ€์˜ ๋ฒˆ์—ญ์ž…๋‹ˆ๋‹ค : https://lihautan.com/what-is-module-bundler-and-how-does-it-work/ What is module bundler and how does it work? | Tan Li Hau What is module bundler and how does it work? August 30, 2019 (Last updated August 30, 2019) Series:

itchallenger.tistory.com