번들링과 웹팩

omegle·2022년 11월 23일
0

번들링 (Bundling)

정의 : 여러 개로 흩어져 있는 코드, 프로그램들을 압축, 난독화 등을 하여 하나의 패키지로 묶어서 제공하는 행위

필요성 : 소프트웨어를 잘 만들어도 사용자에게 배포하기 위해서는 번들링이 꼭 필요하다. 번들링을 해주지 않으면 아래와 같은 문제점들이 발생할 수 있다.

  • 여러 개의 .js 파일에서 같은 변수를 사용하고 있으면 변수 간 충돌이 일어날 수 있다.
  • 딱 한 번 불러오는 프레임워크 코드가 8MB라서 인터넷 속도가 느린 국가의 모바일 환경에서 불편할 수 있다.
  • 번들 파일 사이즈를 줄이기 위해서 파일의 공백을 모두 지웠는데, 가독성이 너무 떨어져서 코딩하기기 어려워 결국 공백을 되돌려서 코딩해야 함.
  • 배포 코드가 너무 읽기 쉬워 개발을 할 줄 아는 사용자가 프론트엔드 애플리케이션을 임의로 조작하여 피해 발생 가능.

웹팩 (Webpack)

  • 정의 : 여러 개의 파일을 하나의 파일로 합쳐주는 모듈 번들러.
    - HTML, CSS, JavaScript, 이미지 파일 등의 자원을 전부 각각의 모듈로 보고 이를 조합해 하나의 묶음으로 번들링(빌드)하는 도구.
    - 프론트엔드 애플리케이션을 대규모 유저에게 배포하기 위해 현재 가장 많이 사용하는 방법이다. (이제는 Node.js 백엔드 개발자도 배포를 위해서도 많이 사용)

유명 JavaScript 번들러와 webpack npm trends

  • 빌드 : 개발이 완료된 앱을 배포하기 위해 하나의 폴더(directory)로 구성하여 준비하는 작업
    - React 앱을 기준으로 예를 들면, npm run build를 실행하면 React build 작업이 진행되고, index.html 파일에 압축되어 배포에 최적화된 상태를 제공
  • 필요성 : 웹팩이 필요한 가장 큰 이유는 웹 애플리케이션의 빠른 로딩 속도와 높은 성능을 위해서이다.
    - 웹페이지를 구성하는 코드의 양이 많은 것을 “무겁다”라고 표현하는데, 이것이 무거우면 무거울수록 웹 페이지의 로딩 속도와 성능은 저하된다.
    - 일반적으로 유저는 하나의 웹사이트에 접근하는 순간부터 3초 이내에 웹페이지가 뜨지 않으면 굉장히 많은 수 이탈을 선택
    - Webpack이 없다면 각 자원들을 일일히 서버에 요청해 얻어와야 하지만, Webpack이 있다면 같은 타입의 파일들은 묶어서 요청 및 응답을 받을 수 있기 때문에 네트워크 코스트가 획기적으로 감소.
    - Webpack loader를 사용하면 일부 브라우저에서 지원하지 않는 JavaScript ES6의 문법들을 ES5로 번환해주는 babel-loader를 사용할 수 있게 됨
    - Webpack4 버전 이상부터는 Develoment, Production 두 가지의 모드를 지원합니다. 여기서 Production 모드로 번들링을 진행할 경우, 코드 난독화, 압축, 최적화(Tree Shaking) 작업을 지원

웹팩의 핵심 컨셉

  • Target : webpack은 다양한 환경과 target을 컴파일한다. target의 기본값은 web, esX를 넣으면 지정된 ECMAScript 버전으로 컴파일할 수 있다.
module.exports = {
  target: ["web", "es5"],
};
  • Entry : webpack에서의 entry는 프론트엔드 개발자가 작성한 코드의 “시작점"이다. React도 index.js에서 HTML 엘리먼트 하나에 React 코드를 적용하는 것 부터 시작한다. (실제 webpack을 사용함) Entry point라고도 하며, webpack이 내부의 디펜던시 그래프를 생성하기 위해 사용해야 하는 모듈이다.
    Entry point를 기반으로 직간접적으로 의존하는 다른 모듈과 라이브러리를 찾아낼 수 있다.
//기본 값
module.exports = {
    ...
  entry: "./src/index.js",
};

//지정 값
module.exports = {
    ...
  entry: "./src/script.js",
};
  • Output : 생성된 번들을 내보낼 위치와 파일의 이름을 지정하는 방법을 webpack에 알려주는 역할
const path = require('path');

module.exports = {
    ...
  output: {
    path: path.resolve(__dirname, "docs"), // 절대 경로로 설정을 해야 합니다. 
    filename: "app.bundle.js",
    clean: true
  },
};
  • Loaders : Webpack은 기본적으로 JavaScript와 JSON 파일만 이해한다. 그러나 loader를 사용하면 Webpack이 다른 유형의 파일을 처리하거나, 유효한 모듈로 변환해 애플리케이션에 사용하거나 디펜던시 그래프에 추가할 수 있다.
    - *test : 변환이 필요한 파일들을 식별하기 위한 속성
    - *use : 변환을 수행하는데 사용되는 로더를 가리키는 속성
    - exclude : 바벨로 컴파일하지 않을 파일이나 폴더를 지정 (반대로 include 속성을 이용해 반드시 컴파일해야 할 파일이나 폴더 지정 가능)
    (* : 필수 속성)
module.exports = {
    ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
        exclude: /node_modules/,
      },
    ],
  },
};
  • Plugins : Plugins를 사용하면 번들을 최적화하거나 에셋을 관리하고, 또는 환경변수 주입 등의 광범위한 작업을 수행할 수 있게 된다.
    - 플러그인을 사용하기 위해서는 require()를 통해 플러그인을 먼저 요청해야 함
    - plugins 배열에 사용하고자 하는 플러그인을 추가해야 함
    - 플러그인을 여러 번 사용하도록 설정할 수 있기 때문에 new 연산자를 사용해 호출하여 플러그인의 인스턴스를 생성
    - html-webpack-plugin : 생성된 모든 번들을 자동으로 삽입하여 애플리케이션용 HTML 파일 생성
    - mini-css-extract-plugin : CSS를 별도의 파일로 추출해 CSS를 포함하는 JS 파일 당 CSS 파일을 작성해주게끔 지원
const webpack = require('webpack');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html"),
    }),
    new MiniCssExtractPlugin(),
  ],
};
  • Optimization : Webpack 버전 4부터 선택한 항목에 따라 최적화를 실행
    - minimize : TerserPlugin 또는 optimization.minimize에 명시된 plugins로 bundle 파일을 최소화(=압축)시키는 작업 여부를 결정
    - minimizer : defualt minimizer을 커스텀된 TerserPlugin 인스턴스를 제공해서 재정의할 수 있음
module.exports = {
  ...
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ]
  }
};
  • Mode

  • Browser Compatibility

// 전체 webpack config 파일
module.exports = {
  target: ["web", "es5"],
  entry: "./src/script.js",
  output: {
    path: path.resolve(__dirname, "docs"),
    filename: "app.bundle.js",
    clean: true
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src", "index.html"),
    }),
    new MiniCssExtractPlugin(),
  ],
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ]
  }
};

참고자료

profile
JANG EUN JI | 장은지

0개의 댓글