개발노트

webpack설정 - 개발시 유용했던 플러그인들 본문

FrontEnd environment/webpack babel lint

webpack설정 - 개발시 유용했던 플러그인들

aloha2jh 2021. 6. 22. 15:35

webpack plugin

로더가 파일단위(모듈하나파일 하나하나)로 처리한다면

플러그인은 번들된 결과물을 처리한다

난독화, 특정텍스트 추출등

 

웹팩 사용버전 4

npm i -d webpack@4 webpack-cli

 

js난독화 처리

UglifyJsPlugin

-js난독화 처리하는 플러그인

웹팩설정 플러그인 배열에 추가한다

(new 로 생성하는 이유가, 플러그인이 class로 선언되어 있어서 )

 

sass파일 분리

ExtractTextPlugin

sass 파일이 너무 커진다면 분리하는게 효율적이고

bundle.js 파일이 아닌 style.css파일로 번들링 하는것

extract-text-webpack-plugin

 

플러그인이 번들된 결과물에 접근하는 방법

https://webpack.js.org/plugins/banner-plugin/

웹팩의 내장 플러그인인 BannerPlugin의 코드를 살펴보면

class MyPlugin {
  apply(compiler) {
  
  	//컴파일이 종료했을때 사용되는 코드
    compiler.hooks.done.tap("My Plugin", stats => {
      console.log("MyPlugin: done")
    })

    // compiler.plugin() 함수로 후처리한다
    compiler.plugin("emit", (compilation, callback) => {
      const source = compilation.assets["main.js"].source()
      console.log(source)
      callback()
    })
  }
}

emit이란 문자열 전달하고, callback이 실행될때 번들링된 결과물에 접근하는 방식

compilation, callback 인자 두개를 받는데

compilation이라는 인자를 통해 웹팩이 빌드한 결과물에 접근할수 있음(코드는 main.js라는 소스코드를 가져옴)

console.log(source)를 통해 번들링된결과물이 나오는걸확인가능**

 

 

class MyPlugin {
  apply(compiler) {
    compiler.plugin('emit', (compilation, callback) => {
      const source = compilation.assets['main.js'].source();
      compilation.assets['main.js'].source = () => {
        const banner = [
          '/**',
          ' * 이것은 BannerPlugin이 처리한 결과입니다.',
          ' * Build Date: 2019-10-10',
          ' */'
          ''
        ].join('\n');
        return banner + '\n' + source;
      }

      callback();
    })
  }
}

compilation.assets['main.js'].source() 부분이 웹팩이 main.js를 번들링한 파일을 가져오는 method?인데

그걸 오버라이딩(재정의)해서 main.js를 번들링한 파일부분 상단에 banner문자열을 추가했다.

 


자주사용되는 webpack plugin , third party library

 

번들파일에 빌드정보 주석추가

BannerPlugin

위에서 사용한 플러그인- 빌드정보, 커밋버전 같은 주석 추가 가능

웹팩이 기본제공하는 플러그인

const webpack = require('webpack');

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

1) 웹팩이 기본으로 제공하는 플러그인이니까 웹팩을 불러온다

2) 생성자 함수 옵션값Banner:에, 빌드결과물에 입력하고자 하는 텍스트를 입력

 

node module 중에 childProcess 를 사용하면 Terminal 명령어를 입력해서 결과값을 가져올수 있다..

그래서 빌드날짜, 커밋해쉬, 빌드한 유저정보 추가 가능

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}`
  )
}
//banner.js

 

환경의존적 정보관리

DefinePlugin

프론트엔드개발환경의 경우 development, production과 같이 개발, 운영환경을 나눠서 관리한다

환경 의존적인 정보를 (ex-환경에따라 API주소가 다르다거나) 소스가 아닌곳에서 관리하기 위함

배포할때마다 코드수정은 비효율적이고 휴먼에러가능성이 높기때문

웹팩이 기본제공하는 플러그인

const webpack = require("webpack")

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

빈객체로 생성해도

노드 환경정보인 process.env.NODE_ENV // development 를 반환한다

현재 webpack.config.js의 mode 설정값을 반환

 

 

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"), //
})

 

//api.js 에서 바로

api.domain 으로 접근해서 사용이 가능

 

Q1)

그렇다면 api.domain :   JSON.stringify("http://dev.api.domain.com"),

이부분을

api.domain :   process.env.NODE_ENV == 'production' ?

JSON.stringify("http://pro.api.domain.com")

: JSON.stringify("http://dev.api.domain.com") 

이런식으로 사용가능해야 배포할때마다 코드수정 줄일수 있지않나

 

cross-env 라이브러리 같은경우는 

Q2)

그리고 webpack config 같은경우는 git에 올라가서 공개될지 모르는데

.env로 관리하는게 보안적으로 더 안전하지 않나?

 

 

index.html -script 로딩 의존성 제거

HtmlTemplatePlugin

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html', // 템플릿 경로를 지정
    })
  ]
}

 

1) index.html 파일을 src 폴더안으로 옮김

html도 (웹팩)소스로 관리하겠다는 의미 웹팩이 src하위폴더를 다루니까

 

2) template을 전달할수 있음 - template 으로 사용할 html의 경로값지정

(script를 지정해준 코드가 없는 html 파일 - 로딩스크립트 제거)

 

3) npm run build 하면 dist폴더에 html파일이 생김

 

4) 실행시킬때 dist/index.html로

output js파일이 자동으로 index.html파일의 script 로드 경로로 잡힌다.

 

 

ejs(html template engine) 사용해 html파일에 파라미터 보내는게 가능

 templateParameters: { // 템플릿에 주입할 파라매터 변수 지정
        env: process.env.NODE_ENV === 'development' ? '(개발용)' : '',
      },

HtmlWebpackPlugin 설정시 (현재 개발환경 판단해서) 해당값을 파라미터를 던져서

 

<!DOCTYPE html>
<html>
  <head>
    <title>타이틀<%= env %></title>
  </head>
  <body>
    <!-- 로딩 스크립트 제거 -->
    <!-- <script src="dist/main.js"></script> -->
  </body>
</html>

html template engine들인  pug, ejs, hbs 중

ejs를 사용해서 html파일에 개발인지 운영인지 표시해주는것도 가능

 

NODE_ENV=development npm run build

 

 

주석제거, 빈칸제거 옵션설정이 가능

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

production일때만 주석제거와 빈칸제거

 

 

이전빌드결과물 제거

CleanWebpackPlugin

const { CleanWebpackPlugin } = require("clean-webpack-plugin")

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

default export 되지 않아서 {}로 가져온다

빌드할때마다 dist폴더를 비우고 다시 저장할수있다

 

 

번들링된 js에서 css분리

MiniCssExtractPlugin

css가 길어질 경우, css를 javascript로 만들어서

javascript 파일 하나를 다운받는것보다

javascript 하나 css 하나 파일이 나오는게 브라우저 성능에 더 나은방법

그러나 개발환경에서는 파일하나로 만드는게 더 효율적이라서

production일때만 사용하도록 설정

 

const MiniCssExtractPlugin = require("mini-css-extract-plugin")

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

**로더설정도 추가해야한다

 

 

 

 

 

 

 

 

 

 

 

 

 


출처 - 김정환

https://jeonghwan-kim.github.io/series/2019/12/10/frontend-dev-env-webpack-basic.html

 

 

.env cross-env  node환경변수 관리

https://velog.io/@public_danuel/process-env-on-node-js

'FrontEnd environment > webpack babel lint' 카테고리의 다른 글

webpack - env  (0) 2021.06.25
webpack - 기술공유  (0) 2021.06.23
webpack - module 종류, webpack 기본구조  (0) 2021.06.22
ESlint, Prettier  (0) 2021.06.14
webpack - scss 적용하기  (0) 2021.06.10