λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
javascript/πŸ“– study

[11μ£Όμ°¨ μŠ€ν„°λ””]49μž₯-Babelκ³Ό Webpack μ΄μš”ν•œ ES6+/ES.NEXT κ°œλ°œν™˜κ²½ ꡬ좕

by HomieKim 2022. 4. 8.

Babelκ³Ό WebPack을 μ΄μš©ν•œ ES6+/ES.NEXT 개발 ν™˜κ²½ ꡬ좕

  • 맀년 μƒˆλ‘­κ²Œ λ„μž…λ˜λŠ” ES6μ΄μƒμ˜ 버전(ES6+)κ³Ό μ œμ•ˆ 단계에 μžˆλŠ” ES μ œμ•ˆ 사양(ES.NEXT)은 λΈŒλΌμš°μ €μ— 따라 μ§€μ›μœ¨μ΄ 제각각
  • λ”°λΌμ„œ μ΅œμ‹  μ‚¬μ–‘μœΌλ‘œ ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν•˜λ €λ©΄ κ΅¬ν˜• λΈŒλΌμš°μ €μ—μ„œ 문제 없이 λ™μž‘ μ‹œν‚€κΈ° μœ„ν•œ κ°œλ°œν™˜κ²½μ„ κ΅¬μΆ•ν•˜λŠ” 것이 ν•„μš”ν•˜λ‹€.
  • λŒ€λΆ€λΆ„μ˜ ν”„λ‘œμ νŠΈκ°€ λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜λ―€λ‘œ λͺ¨λ“ˆ λ‘œλ”λ„ ν•„μš”ν•˜λ‹€.
  • λ‹€μŒκ³Ό 같은 이유둜 ESM 보닀 λ³„λ„μ˜ λͺ¨λ“ˆ λ‘œλ”λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 일반적
    1. IEλ₯Ό ν¬ν•¨ν•œ κ΅¬ν˜„ λΈŒλΌμš°μ €λŠ” ESM을 μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.
    2. ESM을 μ‚¬μš©ν•˜λ”λΌλ„ 트랜슀 νŒŒμΌλ§μ΄λ‚˜ λ²ˆλ“€λ§μ΄ ν•„μš”ν•œ 것은 변함 μ—†μŒ
    3. ESM이 아직 μ§€μ›ν•˜μ§€ μ•ŠλŠ” κΈ°λŠ₯(bare import λ“±..)이 쑴재

Babel

  • Babel은 트랜슀 파일링 λ„κ΅¬λ‘œ μ΅œμ‹  μ‚¬μ–‘μ˜ μ†ŒμŠ€μ½”λ“œλ₯Ό κ΅¬ν˜• λΈŒλΌμš°μ €μ—μ„œλ„ λ™μž‘ν•˜λŠ” ES5μ‚¬μ–‘μ˜ μ½”λ“œλ‘œ λ³€ν™˜ ν•΄μ£ΌλŠ” 도ꡬ μž…λ‹ˆλ‹€.

μ„€μΉ˜

npm install --save-dev @bable/core @babel/cli

Babel 프리셋 μ„€μΉ˜μ™€ babel.config.json μ„€μ •

  • @babel/preset-env μ„€μΉ˜ : ν•¨κ»˜ μ‚¬μš©λ˜μ–΄μ•Ό ν•˜λŠ” ν”ŒλŸ¬κ·ΈμΈμ„ λͺ¨μ•„ λ‘” 것
  • Babel이 μ œκ³΅ν•˜λŠ” 곡식 프리셋(official preset)
    • @babel/preset-env
    • @babel/preset-flow
    • @babel/preset-react
    • @babel/preset-typescript
npm install --save-dev @babel/preset-env
  • μ„€μΉ˜ν›„ babel.config.json 파일 생성
{
  "presets": ["@babel/preset-env"]
}

트랜슀파일링

  • 트랜슀파일링 λͺ…λ Ήμ–΄ package.json에 등둝
"scripts":  {
    "bulid":  "babel src/js -w -d dist/js"
},
  • src/js νƒ€κ²Ÿ 폴더에 μžˆλŠ” λͺ¨λ“  jsνŒŒμΌμ„ νŠΈλžœμŠ€νŒŒμΌλ§ν•˜μ—¬ dist/js폴더에 μ €μž₯ν•˜λŠ” λͺ…λ Ήμ–΄
    • -w μ˜΅μ…˜ : --watch μ˜΅μ…˜μ˜ μΆ•μ•½, 타깃폴더에 μžˆλŠ” λͺ¨λ“  js νŒŒμΌλ“€μ˜ 변경을 κ°μ§€ν•˜μ—¬ μžλ™μœΌλ‘œ 트랜슀파일
    • -d μ˜΅μ…˜ : --out-dir μ˜΅μ…˜μ˜ μΆ•μ•½, 트랜슀파일링 결과물이 μ €μž₯될 폴더λ₯Ό 지정, μ§€μ •λœ 폴더가 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ μžλ™μœΌλ‘œ 생성

Babel ν”ŒλŸ¬κ·ΈμΈ μ„€μΉ˜

  • 바벨 ν™ˆνŽ˜μ΄μ§€μ—μ„œ ν”ŒλŸ¬κ·ΈμΈ 검색 κ°€λŠ₯
  • @babel/plugin-proposal-class-properties: public/private 클래슀 ν•„λ“œλ₯Ό μ§€μ›ν•˜λŠ” ν”ŒλŸ¬κ·ΈμΈ μΆ”κ°€λ‘œ μ„€μΉ˜ν•΄μ€Œ

λΈŒλΌμš°μ €μ—μ„œ λͺ¨λ“ˆ λ‘œλ”© ν…ŒμŠ€νŠΈ

  • λΈŒλΌμš°μ €λŠ” CommonJS λ°©μ‹μ˜ require ν•¨μˆ˜λ₯Ό μ§€μ›ν•˜μ§€ μ•ŠμŒμœΌλ‘œ λ³„λ„μ˜ 섀정없이 μ‹€ν–‰ν•˜λ©΄ μ—λŸ¬λ‚¨
  • λ…Έλ“œ λͺ¨λ“ˆμ΄ μ•„λ‹ˆλΌ λΈŒλΌμš°μ €μ˜ ES6 λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜λ„λ‘ Babel을 μ„€μ •ν•  μˆ˜λ„ μžˆμœΌλ‚˜ Webpack을 톡해 ν•΄κ²°ν•˜λŠ” 것이 μ’‹μŒ

Webpack

  • Webpack은 의쑴 관계에 μžˆλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ, CSS, 이미지 λ“±μ˜ λ¦¬μ†ŒμŠ€λ“€μ„ ν•˜λ‚˜μ˜ 파일둜 λ²ˆλ“€λ§ ν•˜λŠ” λͺ¨λ“ˆ λ²ˆλ“€λŸ¬
  • Webpack을 μ‚¬μš©ν•˜λ©΄ 의쑴 λͺ¨λ“ˆμ΄ ν•˜λ‚˜μ˜ 파일둜 λ²ˆλ“€λ§ λ˜λ―€λ‘œ λ³„λ„μ˜ λͺ¨λ“ˆλ‘œλ”κ°€ ν•„μš” μ—†λ‹€.
  • HTML νŒŒμΌμ—μ„œ μ—¬λŸ¬κ°œμ˜ script νƒœκ·Έλ‘œ μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌμ„ λ‘œλ“œν•΄μ•Όν•˜λŠ” λ²ˆκ±°λ‘œμ›€λ„ 사라진닀.

babel-loader μ„€μΉ˜

  • Webpack이 λͺ¨λ“ˆμ„ λ²ˆλ“€λ§ν•  λ•Œ Babel을 μ‚¬μš©ν•˜μ—¬ ES6+/ES.NEXT μ‚¬μ–‘μ˜ μ†ŒμŠ€μ½”λ“œλ₯Ό ES5 μ‚¬μ–‘μ˜ μ†ŒμŠ€μ½”λ“œλ‘œ νŠΈλžœμŠ€νŒŒμΌλ§ν•˜λ„λ‘ babel-loader μ„€μΉ˜.
npm install --save-dev babel-loader

webpack.config.js μ„€μ • 파일 μž‘μ„±

const path = require('path');

module.exports = {
  entry: './src/js/main.js',
  output:{
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: [path.resolve(__dirname, "src/js")],
        exclude: /node_modules/,
        use:{
          loader: "babel-loader",
          options: {
            presets: ['@babel/preset-env'],
            plugins: ['@babel/plugin-proposal-class-properties']
          }
        }
      }
    ]
  },
  devtool: 'source-map',
  mode: 'development'
}

babel-polyfill μ„€μΉ˜

  • Babel을 μ‚¬μš©ν•˜μ—¬ μ΅œμ‹  μ‚¬μ–‘μ˜ μ½”λ“œλ₯Ό ES5 μ‚¬μ–‘μ˜ μ½”λ“œλ‘œ νŠΈλžœμŠ€νŒŒμΌλ§ν•΄λ„ λΈŒλΌμš°μ €κ°€ μ§€μ›ν•˜μ§€ μ•ŠλŠ” μ½”λ“œκ°€ λ‚¨μ•„μžˆμ„ 수 μžˆλ‹€.
  • Promise, Object.assign, Array.from λ“±κ³Ό 같이 ES5 μ‚¬μ–‘μœΌλ‘œ λŒ€μ²΄ν•  수 μ—†λŠ” κΈ°λŠ₯은 트랜슀파일링 λ˜μ§€ μ•ŠμŒ.
  • IE 같은 κ΅¬ν˜• λΈŒλΌμš°μ €μ—μ„œλ„ μœ„μ™€ 같은 κ°μ²΄λ‚˜ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œ @babel/polyfill μ„€μΉ˜.

@babel-polyfill은 개발 ν™˜κ²½μ—μ„œλ§Œ μ‚¬μš©ν•˜λŠ” 것이라 μ‹€μ œ 운영 ν™˜κ²½ μ—μ„œλ„ μ‚¬μš©ν•΄μ•Ό ν•˜λ―€λ‘œ --save-dev μ˜΅μ…˜ μ§€μ •ν•˜μ§€ μ•ŠμŒ

  • ES6의 importλ₯Ό μ‚¬μš©ν•˜λŠ” 경우 μ§„μž…μ μ˜ μ„ λ‘μ—μ„œ 폴리필을 λ‘œλ“œ
import "@babel/polyfill";
import { pi, power, Foo } from "./lib";
  • Webpack을 μ‚¬μš©ν•˜λŠ” 경우 webpack.config.js 파일의 entry 배열에 폴리필을 μΆ”κ°€.
module.exports = {
    entry: ["@babel/polyfill", "./src/js/main.js"],
};

λŒ“κΈ€