Webpack 3에서 CommonsChunkPlugin 제대로 활용하기

문제 상황

회사 프로젝트의 번들 크기가 2MB를 넘어가면서 초기 로딩이 눈에 띄게 느려졌다. React, Lodash, Moment 등 라이브러리 코드가 애플리케이션 코드와 함께 번들링되어 있어서, 코드 한 줄만 수정해도 전체 번들을 다시 다운로드해야 했다.

CommonsChunkPlugin 적용

Webpack 설정에서 vendor와 manifest를 분리했다.

module.exports = {
  entry: {
    app: './src/index.js',
    vendor: ['react', 'react-dom', 'lodash', 'moment']
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: Infinity
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    })
  ]
};

manifest 청크를 별도로 분리한 이유는 webpack 런타임 코드가 vendor에 포함되면 빌드할 때마다 vendor 해시가 바뀌기 때문이다.

결과

  • app.js: 450KB (기존 2.1MB)
  • vendor.js: 1.5MB (변경 없으면 캐시 사용)
  • manifest.js: 5KB

배포 후 재방문 사용자의 로딩 속도가 체감상 3배 정도 빨라졌다. vendor 번들은 라이브러리 버전을 올리지 않는 이상 캐시에서 계속 사용되니 효과가 확실했다.

추가 고려사항

node_modules의 모든 패키지를 자동으로 vendor로 분리하려면 minChunks 옵션을 활용할 수 있다.

minChunks: (module) => {
  return module.context && module.context.includes('node_modules');
}

다만 이 경우 불필요한 패키지까지 포함될 수 있어서, 프로젝트 규모에 따라 명시적으로 나열하는 게 나을 수도 있다.