Frontend

[Webpack] Webpack 플러그인(Plugin)

w00se 2022. 3. 2. 01:55

플러그인(Plugin)

  • 플러그인은 로더가 할 수 없는 다르 작업을 수행할 목적으로 제공됩니다.
  • 플러그인은 번들된 파일에 후처리 작업을 할 때 사용된다.
    • ex. 번들된 파일 맨 위에 build 시간을 주석으로 삽입하는 작업
  • 플러그인을 만들면 플러그인의 동작 원리를 이해하는데 도움이 됩니다.

 

플러그인 설정 방법

  • 플러그인은 webpack.config.js 파일에 plugins 속성에 배열로 등록합니다.
  • 예제 코드
const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js',
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, './dist'),
  },
  // plugin을 설정하는 부분
  // plugins의 배열에 사용할 plugin의 인스턴스를 저장한다.
  plugins: [
    new webpack.BannerPlugin({
      banner: () => `Build Time: ${new Date().toLocaleString()}`,
    }),
  ],
};

 

자주 사용되는 플러그인

  • 자주 사용되는 플러그인 목록은 김정환님 블로그를 참고해서 정리했으며, 이 게시글에 더욱 상세히 정리되어 있습니다.
  1. BannerPlugin
  • webpack이 기본적으로 제공하는 플러그인입니다.
  • 해당 플러그인은 빌드 파일 맨 위에 빌드 시간 또는 커밋 정보를 주석으로 삽입하는 경우에 활용할 수 있습니다.
  • 예제 코드
const webpack = require('webpack');

module.exports = {
  ...
  plugins: [
    ...
    new webpack.BannerPlugin({
      banner: () => `Build Time: ${new Date().toLocaleString()}`,
    }),
    ...
  ],
};
  1. DefinePlugin
  • webpack이 기본적으로 제공하는 플러그인입니다.
  • 환경 변수 등록과 관려해서 같이 읽으면 좋은 문서
  • DefinePlugin을 활용하면 전역 상수 문자열을 전달할 수 있습니다.
    • 단, 전달한 문자열은 코드로 해석되기 때문에 문자열 값을 전달하고 싶다면 JSON.stringify()를 활용해야 합니다.
    • 기본적으로 process.env.NODE_ENV 값은 전달이 됩니다.
  • 예제 코드
    • NODE_ENV에 따라 API를 호출할 url 값을 전역 상수로 관리할 수 있습니다.
// package.json
{
  ...
  "scripts": {
    ...
    // NODE_ENV 값에 현재 번들을 수행할 환경에 대한 정보를 전달합니다.
    // NODE_ENV=developmenet는 개발환경을 의미합니다.
    // NODE_ENV=production은 배포환경을 의미합니다.
    "bundle": "NODE_ENV=development webpack --progress",
    "watch": "NODE_ENV=development webpack -w --progress",
    "build": "NODE_ENV=production webpack --progress"
    ...
  },
  ...
}
// webpack.config.js
const webpack = require('webpack');

module.exports = {
  mode: process.env.NODE_ENV,
  entry: {
    main: './src/index.js',
  },
  ...
  plugins: [
    ...
    new webpack.DefinePlugin({
      API_HOST:
        process.env.NODE_ENV === 'development'
          ? JSON.stringify('https://test.co.kr:8001')
          : JSON.stringify('https://test.co.kr:8000'),
    }),
    ...
  ],
};
// ./src/index.js
export const testVal = true;

// NODE_ENV에 따라 API_HOST의 값이 달라집니다.
// NODE_ENV === 'production' 이면 API_HOST = https://test.co.kr:8000
// NODE_ENV === 'development' 이면 API_HOST = https://test.co.kr:8001
console.log('현재 실행 환경: ', process.env.NODE_ENV);
console.log('현재 api host 주소: ', API_HOST);
  1. HtmlWebpackPlugin
  • 써드 파티 플로그인입니다.
    • 따라서 별도의 설치가 필요합니다.
  • output.path 경로에 html 파일을 생성하고, 번들된 js 파일이 script 태그로 삽입됩니다.
    • 엔트리 포인트가 여러 개 존재해도, 여러 개의 script 태그를 삽입합니다.
  1. CleanWebpackPlugin
  • 써드 파티 플러그인입니다.
    • 따라서 별도의 설치가 필요합니다.
  • 빌드를 성골 할 때마다 output.path의 경로에 있는 사용되지 않는 파일을 모두 제거합니다.
    • 혹시나 output.path에 중요한 파일이 있는지 확인하고 플러그인을 설정하는 것을 권장합니다..!
      (output path를 잘못 설정해서 .git 디렉터리를 날린 슬픈 이야기가 전해 들었습니다... 물론 제 이야기는 절대 아닙니다. 하하)
  1. MiniCssExtractPlugin
  • 써드 파티 플로그인입니다.
    • 따라서 별도의 설치가 필요합니다.
  • 번들된 js파일에서 css 파일은 따로 분리하는 역할을 합니다.
    • 브라우저에서 하나의 큰 파일을 다운로드하는 것보다, 여러 개의 작은 파일을 동시에 다운로드하는 것이 더 빠르다고 합니다.
    • 따라서, 스타일 시트가 많아졌을 때 해당 플러그인을 사용면 성능 향상에 도움이 될 거 같습니다.
  • 해당 플로 그 인은 production 환경일 경우에만 활용하는 경향이 있습니다.
    • production 환경일 때만 플러그인을 지정하는 방법은 이 게시글에 자세히 정리되어 있습니다.
  • 예제 코드
    • 해당 플러그인을 사용하면 style-loader 대신 플러그인에서 제공하는 loader를 사용해야 합니다.
const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  mode: process.env.NODE_ENV,
  entry: {
    main: './src/index.js',
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, './dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'], // style-loder 대신 plugin에서 제공하는 loader 사용
      },
    ],
  },
  plugins: [
    new webpack.BannerPlugin({
      banner: () => `Build Time: ${new Date().toLocaleString()}`,
    }),
    new webpack.DefinePlugin({
      API_HOST:
        process.env.NODE_ENV === 'development'
          ? JSON.stringify('https://test.co.kr:8001')
          : JSON.stringify('https://test.co.kr:8000'),
    }),
    new CleanWebpackPlugin(),
    // MiniCssExtractPlugin 설정
    new MiniCssExtractPlugin({ filename: '[name].css' }),
  ],
};

 


참고 자료

'Frontend' 카테고리의 다른 글

[Webpack] Webpack 로더(Loaders)  (0) 2022.02.26
[Webpack] Webpack 기초부터 정리  (0) 2022.02.25