🧊 Webpack

지은·2022λ…„ 11μ›” 24일
1

Node.js Library

λͺ©λ‘ 보기
14/14

λ²ˆλ“€λ§

: μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ™μž‘μ— ν•„μš”ν•œ HTML, CSS, JavaScript λ“±μ˜ νŒŒμΌλ“€μ„ λ¬Άμ–΄μ„œ μ œκ³΅ν•˜λŠ” 것

λͺ¨λ“ˆ λ²ˆλ“€λŸ¬ (Module Bundler)

: HTML, CSS, JavaScript λ“±μ˜ μžμ›μ„ μ „λΆ€ 각각의 λͺ¨λ“ˆλ‘œ 보고, 이λ₯Ό μ‘°ν•©ν•΄ ν•˜λ‚˜μ˜ 묢음으둜 λ²ˆλ“€λ§(λΉŒλ“œ)ν•΄μ£ΌλŠ” 도ꡬ

ν•˜λ‚˜μ˜ μ‹œμž‘μ (entry)μœΌλ‘œλΆ€ν„° μ‹œμž‘ν•΄μ„œ, μ˜μ‘΄μ„±μ„ κ°€μ§€λŠ” λͺ¨λ“  λͺ¨λ“ˆμ„ μΆ”μ ν•˜μ—¬ ν•˜λ‚˜μ˜ κ²°κ³Όλ¬Ό(output)을 λ§Œλ“€μ–΄μ€€λ‹€.


🧊 Webpack

: μ—¬λŸ¬ 개의 νŒŒμΌμ„ ν•˜λ‚˜μ˜ 파일둜 ν•©μ³μ£ΌλŠ” λͺ¨λ“ˆ λ²ˆλ“€λŸ¬

  • Webpackμ—μ„œμ˜ λͺ¨λ“ˆμ€ JavaScript λͺ¨λ“ˆμ—λ§Œ κ΅­ν•œλ˜λŠ” 것이 μ•„λ‹ˆλΌ, HTML, CSS파일과 .jpg, .png와 같은 이미지 νŒŒμΌλ“€λ„ μ „λΆ€ ν¬ν•¨ν•œλ‹€.

webpack 곡식 λ¬Έμ„œ

λΉŒλ“œ (Build)

: 개발이 μ™„λ£Œλœ 앱을 λ°°ν¬ν•˜κΈ° μœ„ν•΄ ν•˜λ‚˜μ˜ 폴더(directory)둜 κ΅¬μ„±ν•˜μ—¬ μ€€λΉ„ν•˜λŠ” μž‘μ—…
e.g. React μ•±μ—μ„œ npm run buildλ₯Ό μ‹€ν–‰ν•˜λ©΄, React build μž‘μ—…μ΄ μ§„ν–‰λ˜κ³ , index.html νŒŒμΌμ— μ••μΆ•λ˜μ–΄ 배포에 μ΅œμ ν™”λœ μƒνƒœλ₯Ό μ œκ³΅ν•΄μ€€λ‹€.

λ²ˆλ“€λ§ (Bundling)

: 의쑴적 관계(import, export)에 μžˆλŠ” νŒŒμΌλ“€μ„ λ¬ΆλŠ” μž‘μ—…
λΉŒλ“œ βˆ‹ λ²ˆλ“€λ§


Webpack을 μ‚¬μš©ν•˜λ©΄ 쒋은 점

1. λ„€νŠΈμ›Œν¬ λΉ„μš© κ°μ†Œ

  • Webpack이 μ—†λ‹€λ©΄, 각각의 μžμ›λ“€μ„ 일일히 μ„œλ²„μ— μš”μ²­ν•˜μ—¬ 얻어와야 ν•˜μ§€λ§Œ,
    Webpack이 μžˆλ‹€λ©΄, 같은 νƒ€μž…μ˜ νŒŒμΌλ“€μ€ λ¬Άμ–΄μ„œ μš”μ²­ν•˜μ—¬ 응닡받을 수 μžˆλ‹€.

2. λ‹€μ–‘ν•œ λ‘œλ”(loader) 제곡

  • babel-loader : 일뢀 λΈŒλΌμš°μ €μ—μ„œ μ§€μ›ν•˜μ§€ μ•ŠλŠ” JavaScript ES6 문법을 ES5둜 λ³€ν™˜ν•΄μ£ΌλŠ” λ‘œλ”
  • scss-loader : SCSS νŒŒμΌμ„ CSS 파일둜 λ³€ν™˜ν•΄μ£ΌλŠ” λ‘œλ”
  • vue-loader λ“±...
    ➑️ λ‹€μ–‘ν•œ λ‘œλ”λ₯Ό μ§€μ›ν•˜μ—¬, κ°œλ°œμžκ°€ 본인이 μ›ν•˜λŠ” λ°©μ‹μœΌλ‘œ κ°œλ°œν•  수 μžˆλ„λ‘ λ•λŠ”λ‹€.

3. Development, Production λͺ¨λ“œλ₯Ό 지원

  • Production λͺ¨λ“œλ‘œ λ²ˆλ“€λ§ν•  경우, μ½”λ“œ λ‚œλ…ν™”, μ••μΆ•, μ΅œμ ν™”(Tree Shaking) μž‘μ—…μ„ μ§€μ›ν•œλ‹€.
    즉, Webpack은 μ‚¬μš©μž κ²½ν—˜(UX)만 κ°œμ„ ν•  뿐만 μ•„λ‹ˆλΌ, 개발자 κ²½ν—˜(DX) κ°œμ„ μ—λ„ κΈ°μ—¬ν•œλ‹€

Webpack μ„€μΉ˜

npm으둜 webpackκ³Ό webpack-cliλ₯Ό μ„€μΉ˜ν•œλ‹€.

npm install -D webpack webpack-cli

webpack은 λ²ˆλ“€λ§μ„ μœ„ν•œ 라이브러리둜, μ‹€μ œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— ν•„μš”ν•œ λͺ¨λ“ˆμ€ μ•„λ‹ˆλ―€λ‘œ devDependency μ˜΅μ…˜μœΌλ‘œ μ„€μΉ˜ν•œλ‹€.


λ²ˆλ“€λ§(λΉŒλ“œ)ν•˜κΈ°

  • 터미널에 μ•„λž˜ λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•΄ λ²ˆλ“€λ§ν•  수 μžˆλ‹€.
npx webpack
  • ν˜Ήμ€ package.json νŒŒμΌμ— μ•„λž˜ 슀크립트λ₯Ό μΆ”κ°€ν•˜μ—¬ npm run build둜 λ²ˆλ“€λ§μ„ μ‹€ν–‰ν•  μˆ˜λ„ μžˆλ‹€.
"scripts": {
  "build": "npx webpack"
}

ν•˜μ§€λ§Œ, λ²ˆλ“€λ§μ„ ν•˜κΈ° 전에 λ¨Όμ € webpack.config.js νŒŒμΌμ„ λ§Œλ“€κ³  μ„€μ •ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ€˜μ•Ό ν•œλ‹€.


webpack.config.js

webpack.config.js νŒŒμΌμ—λŠ” 6가지 속성을 μž‘μ„±ν•  수 μžˆλ‹€.

module.export = {
  ...
}
  • Entry (μ‹œμž‘μ )
  • Output (κ²°κ³Ό)
  • Loaders (λ‘œλ”)
  • Plugins (ν”ŒλŸ¬κ·ΈμΈ)
  • Mode (λͺ¨λ“œ)
  • Browser Compatibility (λΈŒλΌμš°μ € ν˜Έν™˜μ„±)

μ•„λž˜μ—μ„œ 각 속성듀이 μ–΄λ–€ 역할을 ν•˜λŠ”μ§€ μ•Œμ•„λ³΄λ©°, μ°¨κ·Όμ°¨κ·Ό μž‘μ„±ν•΄λ³΄μž.


Entry

  • Entry pointλŠ” Webpack이 λ‚΄λΆ€μ˜ λ””νŽœλ˜μ‹œ κ·Έλž˜ν”„λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆμ΄λ‹€.
  • Webpack은 이 Entry pointκ°€ μ§κ°„μ ‘μ μœΌλ‘œ μ˜μ‘΄ν•˜λŠ” λ‹€λ₯Έ λͺ¨λ“ˆκ³Ό 라이브러리λ₯Ό μ°Ύμ•„λ‚Έλ‹€.
  • 기본값은 ./src/index.js μ΄μ§€λ§Œ, λ‹€λ₯Έ 파일둜 μ„€μ •ν•˜κ±°λ‚˜ λ˜λŠ” μ—¬λŸ¬ 개의 Entry pointλ₯Ό μ„€μ •ν•  수 μžˆλ‹€.
module.export = {
  entry: './src/index.js', // index.js νŒŒμΌμ„ Entry point둜 μ„€μ •ν•œλ‹€.
}

Output

  • output 속성은 μƒμ„±λœ λ²ˆλ“€μ„ 내보낼 μœ„μΉ˜μ™€ 이 λ²ˆλ“€ 파일의 이름을 지정할 수 μžˆλ‹€.
  • 기본적으둜 dist 폴더가 μƒμ„±λ˜κ³ , κ·Έ μ•ˆμ— main.js둜 μ €μž₯λœλ‹€.
const path = require('path'); // path λͺ¨λ“ˆμ„ λΆˆλŸ¬μ˜¨λ‹€.

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'), // λ²ˆλ“€μ„ 내보낼 μœ„μΉ˜(폴더)
    filename: 'app.bundle.js', // λ²ˆλ“€ 파일의 이름
  },
};

path λͺ¨λ“ˆ

: νŒŒμΌμ΄λ‚˜ ν΄λ”μ˜ 경둜λ₯Ό νŽΈλ¦¬ν•˜κ²Œ μ„€μ •ν•  수 μžˆλŠ” κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” path λͺ¨λ“ˆ
Node.js λ‚΄μž₯ λͺ¨λ“ˆμ΄κΈ° λ•Œλ¬Έμ—, λ³„λ„μ˜ μ„€μΉ˜μ—†μ΄ require() ꡬ문을 μ΄μš©ν•΄ 뢈러였면 λœλ‹€.

  • path.join()
    : μ—¬λŸ¬ 개의 λ¬Έμžμ—΄μ„ μ „λ‹¬μΈμžλ‘œ λ°›μ•„ ν•©μ³μ£ΌλŠ” λ©”μ†Œλ“œ
path.join('/foo', 'bar', 'baz/asdf');
// μ‹€ν–‰ κ²°κ³Ό : '/foo/bar/baz/asdf'
  • path.resolve()
    : path.join()κ³Ό λΉ„μŠ·ν•˜μ§€λ§Œ, /λ₯Ό λ§Œλ‚˜λ©΄ μ ˆλŒ€ 경둜둜 μΈμ‹ν•˜κ³  κ·Έ 경둜λ₯Ό λ°˜ν™˜ν•œλ‹€.
path.resolve('/foo/bar', './baz');
// μ‹€ν–‰ κ²°κ³Ό : '/foo/bar/baz'

path.resolve('/foo/bar', '/baz/asdf');
// μ‹€ν–‰ κ²°κ³Ό : '/baz/asdf'

__dirname

: fileλͺ…을 μ œμ™Έν•œ μ ˆλŒ€ 경둜

console.log(__dirname); // /Users/ano/temp

__filename

: fileλͺ…을 ν¬ν•¨ν•œ μ ˆλŒ€κ²½λ‘œ

console.log(__filename); // /Users/ano/temp/directory.js

좜처 : https://p-iknow.netlify.app/node-js/path-moudle/


Loaders

Webpack은 기본적으둜 JavaScript와 JSON 파일만 μ΄ν•΄ν•œλ‹€.
λ”°λΌμ„œ Webpack이 λ‹€λ₯Έ μœ ν˜•μ˜ νŒŒμΌμ„ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ‘œλ”κ°€ ν•„μš”ν•˜λ‹€.

λ‘œλ”λŠ” 두 κ°€μ§€μ˜ 속성을 가진닀.

  • test : λ³€ν™˜μ΄ ν•„μš”ν•œ νŒŒμΌμ„ μ‹λ³„ν•˜λŠ” μ†μ„±μœΌλ‘œ μ •κ·œμ‹μœΌλ‘œ μž‘μ„±ν•΄μ•Ό ν•œλ‹€.
  • use : νŒŒμΌμ„ λ³€ν™˜ν•˜λŠ” 데에 μ‚¬μš©λ˜λŠ” λ‘œλ”λ₯Ό κ°€λ¦¬ν‚€λŠ” 속성
  • exclude(optional) : λ°”λ²¨λ‘œ μ»΄νŒŒμΌν•˜μ§€ μ•Šμ„ νŒŒμΌμ΄λ‚˜ 폴더λ₯Ό 지정할 수 μžˆλ‹€.
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.bundle.js',
  },
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
    // .txt νŒŒμΌμ„ λ°œκ²¬ν•˜λ©΄ raw-loaderλ₯Ό μ‚¬μš©ν•΄ λ³€ν™˜ν•˜μ—¬ λ²ˆλ“€μ— μΆ”κ°€ν•œλ‹€.
  },
};

Plugins

: λ‘œλ”λŠ” νŠΉμ • μœ ν˜•μ˜ λͺ¨λ“ˆμ„ λ³€ν™˜ν•˜λŠ” 데 μ‚¬μš©λ˜μ§€λ§Œ, ν”ŒλŸ¬κ·ΈμΈμ„ ν™œμš©ν•˜μ—¬ λ²ˆλ“€μ„ μ΅œμ ν™”ν•˜κ±°λ‚˜, 에셋을 κ΄€λ¦¬ν•˜κ³ , ν™˜κ²½ λ³€μˆ˜ μ£Όμž…κ³Ό 같은 κ΄‘λ²”μœ„ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλ‹€.

  • ν”ŒλŸ¬κ·ΈμΈμ„ μ‚¬μš©ν•˜λ €λ©΄ require() ꡬ문을 μ΄μš©ν•΄ ν”ŒλŸ¬κ·ΈμΈμ„ μš”μ²­ν•˜κ³ , plugins 배열에 μΆ”κ°€ν•΄μ•Ό ν•œλ‹€.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // html-webpack-plugin을 λΆˆλŸ¬μ˜¨λ‹€.

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.bundle.js',
  },
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
  // `html-webpack-plugin`은 λ²ˆλ“€λ§ 폴더(`dist`) μ•ˆμ— μ• ν”Œλ¦¬μΌ€μ΄μ…˜μš© HTML νŒŒμΌμ„ μžλ™μœΌλ‘œ 생성해쀀닀.
};

Mode

mode νŒŒλΌλ―Έν„°λ₯Ό development, production λ˜λŠ” none으둜 μ„€μ •ν•˜λ©΄ Webpack에 λ‚΄μž₯된 ν™˜κ²½λ³„ μ΅œμ ν™”λ₯Ό ν•  수 μžˆλ‹€. 기본값은 production 이닀.

module.exports = {
  mode: 'production',
};

Browser Compatibility

Webpack은 λ‹€μ–‘ν•œ ν™˜κ²½κ³Ό target을 컴파일 ν•œλ‹€.

  • target의 기본값은 web으둜, μ μš©ν•˜μ§€ μ•ŠμœΌλ©΄ 이 기본값이 μ μš©λœλ‹€.
  • targetμ—λŠ” web 이외에도 λ‹€μ–‘ν•œ ν™˜κ²½μ„ μ»΄νŒŒμΌν•  수 μžˆλŠ”λ°, esXλ₯Ό λ„£μœΌλ©΄ μ§€μ •λœ ECMAScript λ²„μ „μœΌλ‘œ μ»΄νŒŒμΌν•  수 μžˆλ‹€.
module.exports = {
  target: ['web', 'es5'],
};

Optimization(μ΅œμ ν™”)

Webpack은 μ΅œμ ν™”λ₯Ό μœ„ν•œ λ‹€μ–‘ν•œ μ˜΅μ…˜μ΄ μ§€μ›λ˜λŠ”λ°, λŒ€ν‘œμ μœΌλ‘œ minimize와 minimizer 등을 μ‚¬μš©ν•œλ‹€.

  • optimization.minimize
    : TerserPlugin λ˜λŠ” optimization.minimize에 μ§€μ •λœ ν”ŒλŸ¬κ·ΈμΈμ„ μ‚¬μš©ν•˜μ—¬ λ²ˆλ“€μ„ μ΅œμ†Œν™”ν•œλ‹€.
module.exports = {
  ...
  optimization: {
    minimize: false,
  },
};
  • optimization.minimizer : ν•˜λ‚˜ μ΄μƒμ˜ λ‹€λ₯Έ TerserPlugin μΈμŠ€ν„΄μŠ€λ₯Ό μ œκ³΅ν•˜μ—¬ κΈ°λ³Έ μ΅œμ†Œν™” 도ꡬλ₯Ό λ‹€μ‹œ μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
module.exports = {
  optimization: {
    minimizer: [new TerserPlugin(),]
  }
};
module.exports = {
  optimization: {
    minimizer: [new CssMinimizerPlugin(),] // mini-css-extract-plugin에 κ΄€λ ¨λœ λ²ˆλ“€μ„ μ΅œμ†Œν™”μ‹œν‚¨λ‹€.
  }
};

이 글은 μ•„λž˜μ˜ 링크λ₯Ό μ°Έκ³ ν•˜μ—¬ μž‘μ„±ν•œ κΈ€μž…λ‹ˆλ‹€.
https://webpack.kr/concepts/

profile
개발 곡뢀 기둝 λΈ”λ‘œκ·Έ

0개의 λŒ“κΈ€