본문 바로가기

JavaScript

20210722 JavaSciprt DeepDive 18 : 모듈, Babel, Webpack

JavaScript Deep Dive 18



📄 용어 및 중요사항 정리


모듈


  • 모듈 : 애플리케이션을 구성하는 개별적 요소로서 재사용 가능한 코드 조각
    • 개별 파일, 모듈 스코프 기능이 있어야 함
    • export : 모듈을 필요한 자산에 선택적으로 공개 하는 것
    • import : 모듈이 공개한 자산 중 일부 또는 전체를 선택해 자신의 스코프 내로 불러들여 재사용 가능
  • CommonJS : 자바스크립트 모듈 시스템의 표준
  • Node.js 환경에서는 모듈 시스템을 지원
  • ESM : 클라이언드 사이드 JS에서 지원하는 모듈 시스템
    • script 태그의 type 어트리뷰트에 module 값을 주면 동작함
    • ESM을 사용하면 파일 확장자 mjs 사용 권장
    • 모듈 스코프 : 전역에서 선언해도 전역 변수가 되지 않음, 모듈내 선언한 식별자는 모듈 외부에서 참조 불가함



Babel, Webpack


Babel


  • Babel : 트랜스파일러로 최신 사양의 ES를 지원하지 않는 브라우저를 위해 ES5 사양의 소스코드로 변환
    • Babel -> @babel/cli, @babel/core
      • @babel/cli : babel의 cli를 할 수 있게 함
        • 'babel src/js -w -d dist/js' 스크립트 설정
        • src/js 폴더에 있는 모든 JS 파일들을 트랜스파일링한 후 결과를 dist/js 폴더에 저장함
        • -w : 타깃 폴더에 있는 모든 JS 파일들의 변경 감지하여 자동으로 트랜스파일 함
        • -d : 트랜스파일링된 결과물이 저장될 폴더를 지정함, 지정 폴더가 없으면 생성함
    • Babel 프리셋 : Babel 플러그인을 모아둔 것으로 필요한 플러그인들을 프로젝트 지원 환경에 맞춰 동적으로 결정 해줌
      • -> @babel/preset-env
        • babel.config.json 설정 파일 필요
    • Babel 플러그인 : 제안 단계에 있는 사양을 트랜스파일링하려면 별도 플러그인 필요
      • -> 예) @babel/plugin-proposal-class-properties, @babel/polyfill



Webpack


  • webpack : 의존 관계에 있는 JS, CSS, image 등의 리소스들을 하나의 파일로 번들링 하는 모듈 번들러
    • webpack, webpack-cli
    • babel-loader : Webpack이 모듈을 번들링할 때 Babel을 사용하여 트랜스 파일링 시킴
      • webpack에서 번들링시 babel을 실행시키도록 함
    • webpack.config.js 파일 생성

  • babel-polyfill : ES5 사양에 대체할 기능이 없어 트랜스파일링되지 못하는 기능을 구현해 줌

    • npm i @babel/polyfill
    • 직접적으로 사용되기 때문에, dev 디벤던스로 설치하면 안됨
    • webpack config 파일의 entry에 '@babel/polyfill'을 넣어주어야 함
  • html-webpack-plugin : 생성된 모든 번들을 자동으로 삽입하여 애플리케이션용 HTML 파일 생성하는 플러그 인

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

module.exports = {
  entry: ["@babel/polyfill", "./src/js/main.js"],
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    clean: true,
  },
  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"],
          },
        },
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
    }),
  ],
  devServer: {
    contentBase: path.join(__dirname, "dist"),
    port: 9000,
  },
  devtool: "source-map",
  mode: "development",
};