webpack plugin

fe_sw·2022년 8월 24일
0

Webpack

목록 보기
3/4
post-thumbnail

플러그인(plugin)은 웹팩의 기본적인 동작에 추가적인 기능을 제공하는 속성이다.

로더랑 비교하면 로더는 파일을 해석하고 변환하는 과정에 관여하는 반면,

플러그인은 번들된 결과물을 처리한다. 번들된 자바스크립트를 난독화 한다거나 특정 텍스트를 추출하는 용도로 사용한다

BannerPlugin

결과물에 빌드 정보나 커밋 버전같은 걸 추가할 수 있다.

//webpack.config.js
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.BannerPlugin({
      banner: '이것은 배너 입니다',
    })
  ]

생성자 함수에 전달하는 옵션 객체의 banner 속성에 문자열을 전달한다.

웹팩 컴파일 타임에 얻을 수 있는 정보, 가령 빌드 시간이나 커밋정보를 전달하기위해 함수로 전달할 수도 있다.

new webpack.BannerPlugin({
  banner: () => `빌드 날짜: ${new Date().toLocaleString()}`,
})

배너 정보가 많다면 별로 파일로 분리하자.

const banner = require("./banner.js")

new webpack.BannerPlugin(banner)

빌드 날짜 외에서 커밋 해쉬와 빌드한 유저 정보까지 추가해 보자.

//banner.js:
const childProcess = require("child_process")

module.exports = function banner() {
  const commit = childProcess.execSync("git rev-parse --short HEAD")
  const user = childProcess.execSync("git config user.name")
  const date = new Date().toLocaleString()

  return (
    `commitVersion: ${commit}` + `Build Date: ${date}\n` + `Author: ${user}`
  )
}

DefinePlugin

어플리케이션은 개발환경과 운영환경으로 나눠서 운영한다. 가령 환경에 따라 API 서버 주소가 다를 수 있다.

같은 소스 코드를 두 환경에 배포하기 위해서는 이러한 환경 의존적인 정보를 소스가 아닌 곳에서 관리하는 것이 좋다.

배포할 때마다 코드를 수정하는 것은 곤란하기 때문이다. 웹팩은 이러한 환경 정보를 제공하기 위해 DefinePlugin을 제공한다

//webpack.config.js
const webpack = require("webpack")

export default {
  plugins: [new webpack.DefinePlugin({})],
}

빈 객체를 전달해도 기본적으로 넣어주는 값이 있다. 노드 환경정보인 process.env.NODE_ENV 인데 웹팩 설정의 mode에 설정한 값이 여기에 들어간다. "development"를 설정했기 때문에 어플리케이션 코드에서 process.env.NODE_ENV 변수로 접근하면 "development" 값을 얻을 수 있다.

//app.js
console.log(process.env.NODE_ENV) // "development"

이 외에도 웹팩 컴파일 시간에 결정되는 값을 전역 상수 문자열로 어플리케이션에 주입할 수 있다.

new webpack.DefinePlugin({
  TWO: "1+1",
})

TWO라는 전역 변수에 1+1 이란 코드 조각을 넣었다. 실제 어플리케이션 코드에서 이것을 출력해보면 2가 나올 것이다.

//app.js
console.log(TWO) // 2

코드가 아닌 값을 입력하려면 문자열화 한 뒤 넘긴다.

new webpack.DefinePlugin({
  VERSION: JSON.stringify("v.1.2.3"),
  PRODUCTION: JSON.stringify(false),
  MAX_COUNT: JSON.stringify(999),
  "api.domain": JSON.stringify("http://dev.api.domain.com"),
})
//app.js
console.log(VERSION) // 'v.1.2.3'
console.log(PRODUCTION) // true
console.log(MAX_COUNT) // 999
console.log(api.domain) // 'http://dev.api.domain.com'

빌드 타임에 결정된 값을 어플리이션에 전달할 때는 이 플러그인을 사용하면 된다

HtmlWebpackPlugin

HtmlWebpackPlugin은 HTML 파일을 후처리하는데 사용한다. 빌드 타임의 값을 넣거나 코드를 압축할수 있다. 이 플러그인으로 빌드하면 HTML파일로 아웃풋에 생성될 것이다.

//설치
$ npm install -D html-webpack-plugin
//src/index.html:
<!DOCTYPE html>
<html>
  <head>
    <title>타이틀<%= env %></title>
  </head>
  <body>
    <!-- 로딩 스크립트 제거 -->
    <!-- <script src="dist/main.js"></script> -->
  </body>
</html>

타이틀 부분에 ejs 문법을 이용하는데 <%= env %> 는 전달받은 env 변수 값을 출력한다. HtmlWebpackPlugin은 이 변수에 데이터를 주입시켜 동적으로 HTML 코드를 생성한다.

또한 웹팩으로 빌드한 결과물을 자동으로 로딩하는 코드를 주입해 준다. 때문에 스크립트 로딩 코드도 제거했다.

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

module.exports {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html', // 템플릿 경로를 지정
      templateParameters: { // 템플릿에 주입할 파라매터 변수 지정
        env: process.env.NODE_ENV === 'development' ? '(개발용)' : '',
      },
    })
  ]
}

환경 변수에 따라 타이틀 명 뒤에 "(개발용)" 문자열을 붙이거나 떼거나 하도록 했다.
NODE_ENV=development 로 설정해서 빌드하면 빌드결과 "타이틀(개발용)"으로 나온다.
NODE_ENV=production 으로 설정해서 빌드하면 빌드결과 "타이틀"로 나온다.

//webpack.config.js:
new HtmlWebpackPlugin({
  minify: process.env.NODE_ENV === 'production' ? {
    collapseWhitespace: true, // 빈칸 제거
    removeComments: true, // 주석 제거
  } : false,
}

환경변수에 따라 minify 옵션을 켰다. NODE_ENV=production npm run build로 빌드하면 아래처럼 코드가 압축된다. 물론 주석도 제거 되었다.

정적파일을 배포하면 즉각 브라우져에 반영되지 않는 경우가 있다. 브라우져 캐쉬가 원인일 경우가 있는데 이를 위한 예방 옵션도 있다.

//webpack.config.js:
new HtmlWebpackPlugin({
  hash: true, // 정적 파일을 불러올때 쿼리문자열에 웹팩 해쉬값을 추가한다
})

hash: true 옵션을 추가하면 빌드할 시 생성하는 해쉬값을 정적파일 로딩 주소의 쿼리 문자열로 붙여서 HTML을 생성한다.

CleanWebpackPlugin

CleanWebpackPlugin은 빌드 이전 결과물을 제거하는 플러그인이다.

//설치
$ npm install -D clean-webpack-plugin
//webpack.config.js:
const { CleanWebpackPlugin } = require("clean-webpack-plugin")

module.exports = {
  plugins: [new CleanWebpackPlugin()],
}

MiniCssExtractPlugin

스타일시트가 점점 많아지면 하나의 자바스크립트 결과물로 만드는 것이 부담일 수 있다.
번들 결과에서 스트일시트 코드만 뽑아서 별도의 CSS 파일로 만들어 역할에 따라 파일을 분리하는 것이 좋다.

브라우져에서 큰 파일 하나를 내려받는 것 보다, 여러 개의 작은 파일을 동시에 다운로드하는 것이 더 빠르다.

개발 환경에서는 CSS를 하나의 모듈로 처리해도 상관없지만 프로덕션 환경에서는 분리하는 것이 효과적이다. MiniCssExtractPlugin은 CSS를 별로 파일로 뽑아내는 플러그인이다.

//설치
$ npm install -D mini-css-extract-plugin
// webpack.config.js:
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

module.exports = {
  plugins: [
    ...(process.env.NODE_ENV === "production"
      ? [new MiniCssExtractPlugin({ filename: `[name].css` })]
      : []),
  ],
}

프로덕션 환경일 경우만 이 플러그인을 추가했다. filename에 설정한 값으로 아웃풋 경로에 CSS 파일이 생성될 것이다.

// webpack.config.js:
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          process.env.NODE_ENV === "production"
            ? MiniCssExtractPlugin.loader // 프로덕션 환경
            : "style-loader", // 개발 환경
          "css-loader",
        ],
      },
    ],
  },
}

플러그인에서 제공하는 MiniCssExtractPlugin.loader 로더를 추가한다.
NODE_ENV=production npm run build로 결과를 확인해보자.
dist/main.css가 생성되었고 index.html에 이 파일을 로딩하는 코드가 추가되었다.

0개의 댓글