웹 공부하기/Frontend

[인프런] 프론트엔드 개발환경의 이해와 실습 (웹팩 - 최적화)

inthess 2021. 11. 19. 11:58
최적화가 필요한 상황과 웹팩에서 최적화를 적용하는 방법에 대해 알아보자.

최적화

코드가 많아지면 웹팩으로 번들링한 결과물의 크기도 커진다. 메가바이트(MB) 단위로 커질 수 있는데, 이는 브라우저 성능에 영향을 줄 수 있다. 파일을 다운로드하기까지 시간이 오래 걸리기 때문이다. 번들링한 결과물을 어떻게 최적화할지 살펴보자.

production 모드

가장 기본적인 방법은 웹팩에 내장되어 있는 최적화 방법 중, mode 값을 설정하는 것이다.

development는 디버깅 편의를 위해 아래의 플러그인을 사용한다.

  • NamedChunksPlugin
  • NamedModulesPlugin

추가로 DefinePlugin을 사용한다면 process.env.NODE_ENV 값이 development로 설정되어 애플리케이션에 전역변수로 들어간다.

반면, production으로 설정하면 자바스크립트 결과물을 최소화 하기 위해 다음의 플러그인들을 사용한다. 해당 모드는 운영환경에 적합한 번들 결과를 만들어 낼 수 있다.

  • FlagDependencyUsagePlugin
  • FlagIncludedChunksPlugin
  • ModuleConcatenationPlugin
  • NoEmitOnErrorsPlugin
  • OccurrenceOrderPlugin
  • SideEffectsFlagPlugin
  • TerserPlugin

 

추가로 DefinePlugin을 사용한다면 process.env.NODE_ENV 값이 production으로 설정되어 애플리케이션에 전역변수로 들어간다.

그럼 환경변수인 NODE_ENV 값에 따라 모드를 설정하도록 웹팩 설정 코드를 수정해보자.

webpack.config.js

const mode = process.env.NODE_ENV || "development" // 기본값을 development로 설정

module.exports = {
  mode,
}

 

빌드할 때 production 모드로 설정하여 실행되도록 스크립트를 추가하자.

package.json

{
  "scripts": {
    "start": "webpack-dev-server --progress",
    "build": "NODE_ENV=production webpack --progress"
  }
}

start는 개발 서버를 구동하기 때문에 환경변수를 설정하지 않고 기본값 development를 사용하도록 했다. 배포용으로 만들 build는 환경변수를 production으로 설정했고, 이는 웹팩 mode에 설정된다.

 

npm run build 명령어로 빌드한 뒤 결과물을 확인해 보면 development 모드일 때와 production 모드일 때의 번들링 결과가 확연히 다른 것을 볼 수 있다.

 

 

optimazation 속성으로 최적화

빌드 과정을 커스터마이징할 수 있는 optimazation 속성을 사용해보자. HtmlWebpackPlugin이 html 파일을 압축한 것처럼 css 파일도 빈칸을 없애서 압축해주는 플러그인이 있는데, 바로 optimize-css-assets-webpack-plugin이다.

 

해당 플러그인을 설치해보자.

npm install -D optimize-css-assets-webpack-plugin

 

그리고 웹팩 설정파일에 추가한다.

webpack.config.js

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")

module.exports = {
  optimization: {
    minimizer: mode === "production" ? [new OptimizeCSSAssetsPlugin()] : [],
  }
}

optimization의 minimizer 배열에 웹팩이 결과물을 압축할 때 사용하는 플러그인을 넣는다. 설치한 플러그인을 전달해서 빌드 결과물 중 css 파일을 압축하도록 설정한 것이다.

 

npm run build로 빌드하고 확인해보면 css 파일도 압축된 것을 볼 수 있다.

mode가 production일 경우 사용되는 TerserWebpackPlugin은 자바스크립트 코드를 난독화하고 디버거 구문을 제거한다. 기본 설정 외에 콘솔 로그를 제거하는 옵션도 있다. 배포 버전에는 로그를 감추는 것이 좋을 수 있기 때문이다.

설치하고 한번 사용해보자.

npm install -D terser-webpack-plugin

 

webpack.config.js

const TerserPlugin = require("terser-webpack-plugin")

module.exports = {
  optimization: {
    minimizer:
      mode === "production"
        ? [
            new TerserPlugin({
              terserOptions: {
                compress: {
                  drop_console: true, // 콘솔 로그를 제거한다
                },
              },
            }),
          ]
        : [],
  },
}

 

externals

axios 같은 Third Party 라이브러리를 최적화하는 것도 가능하다. 패키지로 제공될 때 이미 빌드 과정을 거쳤기 때문에 빌드 프로세스에서 제외하는 것이 좋다. 웹팩 설정 중 externals가 바로 이러한 기능을 제공한다.

webpack.config.js

module.exports = {
  externals: {
    axios: "axios",
  },
}

위와 같이 externals에 추가하면 코드에서 axios를 사용해도 웹팩이 번들에 포함하지 않고 빌드해준다. 대신 이를 전역 변수로 접근하도록하는데 키로 설정한 axios가 그 이름이다.

 

axios는 이미 node_modules에 위치해 있기 때문에 이를 웹팩 아웃풋 폴더에 옮기고 index.html에서 로딩해야 한다. 따라서 파일을 복사하는 플러그인을 설치해주자.

npm install -D copy-webpack-plugin

 

해당 플러그인을 웹팩 설정 파일에 넣어주자.

webpack.config.js

const CopyPlugin = require("copy-webpack-plugin")

module.exports = {
  plugins: [
    new CopyPlugin([
      {
        from: "./node_modules/axios/dist/axios.min.js",
        to: "./axios.min.js", // 목적지 파일에 들어간다
      },
    ]),
  ],
}

 

 

마지막으로 axios를 로딩하는 코드를 추가한다.

index.html

<html>
	<body>
		<script type="text/javascript" src="axios.min.js"></script>
	</body>
</html>

axios는 직접 추가했지만 번들링한 결과물은 HtmlWebpackPlugin이 자동으로 로딩해주는 것을 잊지말자.

 

이렇게 써드파티 라이브러리를 externals로 분리하면 번들링 파일의 용량을 감소할 수 있을 뿐 아니라 빌드 시간도 줄어들어 개발 환경이 가벼워질 수 있다.

 


출처: [인프런] 프론트엔드 개발환경의 이해와 실습