node.JS

자주 사용되는 webpack plugins 정리.

jdy8739 2022. 11. 7. 23:08

webpack module의 plugins 속성은 loader들로 번들링된 js 파일의 후처리를 담당합니다.

전 글에서 plugin들은 클래스의 인스턴스를 호출하여 해당 plugin이 제공하는 후처리 로직을 번들링할 때마다 적용한다고 작성했습니다.

 

사실 loader나 plugins 모두 프론트엔드 개발 패키지를 다운 받을 때 필요한 요소들이 모두 함께 받아지지만, 무엇이 어떤 방식을 사용해 완성된 번들링 파일을 만드는지 궁금했기 때문에 여기에 정리를 하려고 합니다.

 

참고로 공부한 webpack의 설정 기준은 현재의 5버전이 아닌 4버전 기준입니다.

 

1. BannerPlugin

new webpack.BannerPlugin({
  banner: `
    Build time: ${new Date().toLocaleString()}
    Commit Version: ${childProcess.execSync('git rev-parse --short HEAD')}
    Author: ${childProcess.execSync('git config user.name')}
  `
})

이 plugin은 추가로 webpack에서 기본적으로 제공하는 플러그인입니다.

따라서 npm으로 추가적인 설치가 필요 없으며 위처럼 webpack 객체에서 바로 호출이 가능합니다.

 

이 때, 생성자를 호출할 때 안에 객체를 인자로서 넣습니다.

이 객체는 banner라는 속성을 가지는데 값으로 문자열을 넣어줄 수 있습니다.

여기서 childProcess의 exeSync 함수는 터미널 명령을 문자열로 받아 결과를 반환합니다.

 

위처럼 속성을 지정해준다면,

이런 주석을 통해 번들링 결과물의 상단에 위치해 정보를 나타내줄 수 있습니다.

 

2. DefinePlugin

new webpack.DefinePlugin({
  CODING: JSON.stringify("funny")
})

다음은 환경변수를 지정해줄 수 있는 plugin입니다.

역시 생성자 안에 객체 속성에 원하는 환경 정보를 주입해줄 수 있습니다.

주의할 점은 JSON.stringify 함수를 사용하지 않고 문자열을 값으로 지정하면 에러가 발생할 수 있습니다.

 

이 객체가 아무 속성이 없는 빈 객체라도 webpack module의 mode 속성 값이 자동으로 주입되며

이는 process.env.NODE_ENV를 통해 접근할 수 있습니다.

console.log(process.env.NODE_ENV);
console.log(CODING);

entry js파일에서 이 콘솔 출력 명령을 입력하면

이렇게 환경 변수들이 잘 출력됩니다.

 

만약 위에서 JSON.stringify 함수를 사용하지 않았다면,

위와 같이 문자열을 변수 식별자로 인식하여 에러가 발생합니다.

 

3. HtmlWebpackPlugin

new HtmlWebpackPlugin({
  template: './src/index.html',
  templateParameters: {
    env: process.env.NODE_ENV === 'development' ? '(dev)' : '(pro)'
  },
  minify: process.env.NODE_ENV === 'production' ? {
    collapseWhitespace: true,
    removeComments: true
  } : false
})

목표 html 파일을 후처리하는 plugin입니다.

template 속성은 목표 html을 정의하며 templateParameters는 해당 html 파일에서 사용할 환경변수를 정의합니다.

 

이 plugin부터 npm으로 별도의 패키지 설치가 필요하며 현재의 webpack 버전과 맞지 않아 에러가 발생할 경우,

npm i -D HtmlWebpackPlugin@4

이런 식으로 버전을 낮추어 설치해줘야 합니다.

 

참고로 환경변수라는 단어가 다시 나와서 헷갈릴 수 있습니다.

위의 DefinePlugin이 지정하는 환경변수는 빌드된 js 파일에서 사용될 환경변수이고,

여기서의 환경변수는 html 파일 내부에서 사용됩니다.

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>검색<%= env %></title>
</head>

그 예시로 위처럼 templateParameters에 주입되는 환경 변수에 따라 동적으로 html 노드들을 다뤄줄 수 있습니다.

따라서, 위 코드는 ejs문법으로 webpack의 mode에 따라 동적으로 문서의 title을 변경합니다.

 

또한, minify 속성을 통해 html 문서를 축소하는 옵션을 지정해줄 수 있습니다.

minify 속성의 값으로 지정되는 객체는 대표적으로 두 속성을 가집니다.

 

collapseWhiteSpace는 html 문서의 모든 공백을 제거합니다.

가끔 프로젝트를 빌드하고 페이지 소스를 보면 우리가 일반적으로 보는 중첩된 노드 형식의 html 문서가 아닌,

이런식의 html 문서를 확인할 수 있습니다.

이는 collapseWhiteSpace 속성이 참으로 지정되어 빌드되었기 때문입니다.

 

또한, removeComments 속성은 html 문서 내의 모든 주석을 제거합니다.

 

4. CleanWebpackPlugin

new CleanWebpackPlugin()

빌드 시마다 매번 이전에 빌드된 파일을 삭제하는 plugin입니다.

 

5. MiniCssExtractPlugin

...(process.env.NODE_ENV === 'production' ? 
[new MiniCssExtractPlugin({
  filename: '[name].css'
})] : [])

이름 그대로 번들링된 js 파일에서 css 파일을 추출하는 plugin입니다.

생성자 안의 객체에 filename 속성은 생성할 css파일의 이름을 지정할 수 있습니다.

 

이 플러그인을 사용할 때 유의해야할 점은,

{
    test: /\.css$/,
    use: [
      process.env.NODE_ENV === 'production' ?
      MiniCssExtractPlugin.loader :
      'style-loader',
      'css-loader'
    ]
}

css 파일을 해석하는 loader를 style-loader가 아닌 이 플러그인이 자체적으로 제공하는 메소드인

MiniCssExtractPlugin.loader를 사용해야 한다는 것입니다.

 

이 plugin을 사용하지 않았다면 빌드된 js 파일에서 css 속성까지 모두 담고 있기 때문에,

해당 파일 안에서 css style 정보를 찾아볼 수 있습니다.

 

😐😐😐...

보기만 봐도 어지럽고 이 상태로 클라이언트에 파일을 전송한다면 브라우저가 이를 해석하는데 시간이 증가해 부정적인 영향을 줄 것 같습니다.

 

반면, 이 플러그인을 적용해 빌드를 한다면 이 css style 정보들이 css 파일로 분리되어 js 파일의 크기를 줄일 수 있습니다.