[개발환경] webpack(5)

BannerPlugin

번들된 결과물에 빌드 정보나 커밋 버전등의 내용을 추가 할 때 사용하는 플러그인이다.
기본적으로 webpack에서 제공하기 때문에 따로 설치할 필요가 없다.

BannerPlugin 적용 및 결과

// webpack.config.js:

const webpack = require("webpack");
const childProcess = require("child_process");

module.exports = {
  ...생략,
  plugins: [
    new webpack.BannerPlugin({
      banner:`
        Build Data: ${new Date().toLocaleString()}
        Commit Version: ${childProcess.execSync('git rev-parse --short HEAD')}
        Author: ${childProcess.execSync('git config user.name')}
      `
    })
  ]
}
  • 작성할 내용은 banner 속성에 문자열로 작성하면 된다.

  • child_process 모듈을 사용하면 터미널 명령어를 실행할 수 있다.

DefinePlugin

동일한 소스를 다른 환경(개발환경, 운영환경)에 배포하기 위해서 환경 의존적인 정보를 소스가 아닌 다른 곳에서 관리를 하는 것이 좋은데 이는 DefinePlugin을 이용하면 된다.
(DefinePlugin을 이용하면 모든 자바스크립트 코드에서 접근이 가능한 전역변수를 선언 할 수 있다.)

DefinePlugin 적용 및 결과

DefinePlugin도 BannerPlugin과 동일하게 webpack에서 기본으로 제공한다.

// webpack.config.js:
const webpack = require("webpack");
const childProcess = require("child_process");

module.exports = {
  ...생략,
  plugins: [
    new webpack.BannerPlugin({
		...생략
    }),
     new webpack.DefinePlugin({
      TWO: '1+1',
      VERSION: JSON.stringify('v.1.2.3'),
      'api.domain': JSON.stringify('http://test.domain.com'),
    })
  ]
}
// src/app.js:
console.log(TWO);
console.log(VERSION);
console.log(api.domain);

소스 내에서 console.log(process.env.NODE_ENV)를 찍어보면 "development" 값이 나오게 된다. 이는 웹팩 설정파일의 mode에 설정한 값이 development이기 때문이다.

그리고 DefinePlugin으로 선언한 전역변수는 웹팩이 빌드하는 동안에만 사용되는 점을 유의해야 한다.

HtmlWebpackPlugin

HtmlWebpackPlugin 플러그인을 이용하면 html 파일을 읽어 html 파일을 빌드 할 수 있게 해준다. (빌드 과정에서 빈칸을 제거한다던지, 주석을 제거한다던지 등의 html 내부 내용의 수정이 가능하다.)

HtmlWebpackPlugin 설치

HtmlWebpackPlugin은 서드파티라이브러리이기 때문에 설치를 해줘야 한다.

$ npm install -D html-webpack-plugin

HtmlWebpackPlugin 적용 및 결과

적용하기전에 우선 웹팩설정파일과 동일한 경로에 있는 index.html파일을 src 내부로 옮겼고 테스트 해보기 위해 html 내부 내용을 수정했다.

<!-- ./src/index.html -->

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document<%= env %></title>
</head>
<body>
    <!-- 주석을 적었습니다. -->
    <h1>webpack test</h1>
</body>
</html>
  • env(ejs 문법사용)는 HtmlWebpackPlugin에서 설정한 env 변수 값이 출력 될 것이다.

  • body 내부에 주석을 작성했다. (html 내부 내용을 변경하는 테스트를 해보기 위해서)

  • script 태그도 제거하였다. (번들된 결과물을 자동으로 로딩하는 코드를 주입해주기 때문)

// webpack.config.js:
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  ...생략,
  plugins: [
    new webpack.BannerPlugin({
		...생략
    }),
     new webpack.DefinePlugin({
       ...생략,
    }),
    new HtmlWebpackPlugin({
      template: './src/index.html', // 읽어올 템플릿 경로 지정
      templateParameters: {
        env: process.env.NODE_ENV === 'development' ? '(개발용)' : '',
      },
      minify: process.env.NODE_ENV === 'production' ? {
        collapseWhitespace: true, // 빈칸 제거
        removeComments: true, // 주석 제거
      } : false,
    })
  ]
}

1) $ NODE_ENV=production npm run build 실행 시

웹팩 설정파일의 process.env.NODE_ENV의 값에 production으로 대체되면서

  • 문서의 타이틀은 그대로

  • 빌드된 index.html파일은 빈칸과 주석이 제거

  • 자동으로 script 태그가 작성

2) $ NODE_ENV=development npm run build 실행 시

웹팩 설정파일의 process.env.NODE_ENV의 값에 development으로 대체되면서

  • 문서의 타이틀에 (개발용)이 추가 되었다.

  • 빌드된 index.html파일은 빈칸과 주석이 그대로

  • 자동으로 script 태그가 작성

여기서 명령어로 친 NODE_ENV 변수 값은 웹팩 설정파일에만 적용되고
소스내에서 console.log(process.env.NODE_ENV)의 값은 웹팩 설정파일의 mode값인 development 값으로 고정이 되는 것을 확인 할 수 있었다.

CleanWebpackPlugin

새로 빌드할 때 빌드 된 결과물을 제거하는 플러그인이다. (dist 폴더 내를 한번 삭제해주고 다시 빌드해주기 때문에 깔끔??)

CleanWebpackPlugin 설치

$ npm install -D clean-webpack-plugin

CleanWebpackPlugin 설정 및 결과

// webpack.config.js:
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  ...생략,
  plugins: [
    new webpack.BannerPlugin({
       ...생략
    }),
     new webpack.DefinePlugin({
       ...생략,
    }),
    new HtmlWebpackPlugin({
       ...생략,
    }),
    new CleanWebpackPlugin(), // dist 폴더 cleaner
  ]
}
  • 모듈을 불러올 때 default가 아니기 때문에 중괄호({})

npm run build 전

npm run build 후

dist 폴더에 임시로 만들었던 remove.js 파일이 삭제 된 것을 확인 할 수 있다.

MiniCssExtractPlugin

stylesheet가 많아질 때를 대비해 CSS 파일을 별도 파일로 추출할 수 있는 플러그인이다.

MiniCssExtractPlugin 설치

$ npm install -D mini-css-extract-plugin

MiniCssExtractPlugin 설정 및 결과

// webpack.config.js:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  ...생략,
  plugins: [
    new webpack.BannerPlugin({
       ...생략
    }),
     new webpack.DefinePlugin({
       ...생략,
    }),
    new HtmlWebpackPlugin({
       ...생략,
    }),
    new CleanWebpackPlugin(), // dist 폴더 cleaner
    ...(process.env.NODE_ENV === "production"
      ? [new MiniCssExtractPlugin({ filename: `[name].css` })]
      : []),
  ]
}
  • 개발 환경에서는 불필요하기 때문에 운영환경일때만 동작되도록 하였다.

  • 추가적으로 rules에서도 개발 환경, 운영환경에 따라 loader를 변경할 수 있도록 수정해야 한다.

// webpack.config.js:

module: {
    rules: [
      {
        test: /\.css$/, // css 확장자로 끝나는 모든 파일을 의미
        use: [
          process.env.NODE_ENV === "production"
            ? MiniCssExtractPlugin.loader
            : "style-loader",
          "css-loader",
        ],
      },
   	// 생략...
    ],
  },

$ NODE_ENV=production npm run build 실행 시

운영 환경으로 빌드 시 css파일이 분리되고 html내부에 자동으로 css파일이 추가 된 것을 확인 할 수 있다.


Reference

좋은 웹페이지 즐겨찾기