본문 바로가기

JavaScript

moment.js 최적화 - 불필요한 locale파일 빌드 시 제외시키기(with webpack)

현재 회사 프로젝트에서 moment.js를 사용중인데, 실제로 사용하고 있는 local 파일은 ko뿐인데 어마어마하게 많은 모든 local파일을 포함해서 빌드하는것을 발견하였다. 웹팩 번들 애널라이즈로 보면 moment가 차지하는 사이즈가 꽤 크다.

 

파일의 크기가 크면 클수록 페이지를 로드하는 시간이 길어지기 때문에 되도록이면 사용하지않는 라이브러리는 빌드에 포함시키지 않고 번들링 사이즈를 작게 관리하는 것이 중요하다.

 

따라서 webpack을 사용하여 번들링 할 때 ko locale만을 번들링파일에 포함시켜 파일 사이즈를 줄여보도록 하겠다.

 

불필요한 locale 파일들 왜 모두 번들되나요?

function loadLocale(name) {
    var oldLocale = null;
    // TODO: Find a better way to register and load all the locales in Node
    if (!locales[name] && (typeof module !== 'undefined') &&
            module && module.exports) {
        try {
            oldLocale = globalLocale._abbr;
            require('./locale/' + name);
            // because defineLocale currently also sets the global locale, we
            // want to undo that for lazy loaded locales
            locale_locales__getSetGlobalLocale(oldLocale);
        } catch (e) { }
    }
    return locales[name];
}

위의 moment.js 내  일부 코드를 보자. 동적 require를 사용하여 require('./locale/'+name);로 파일을 가져오는데, 이때 webpack은 어떤 locale 파일이 불러올지 컴파일 시점에는 알수 없기 때문에 locale 디렉토리 아래에서 /^.*$/에 매칭되는 모든 파일들을 번들링한다. 

 

ContextReplacementPlugin으로 줄이기

이러한 디렉토리와 정규식의 조합을 컨텍스트라고 보는데, 아래 플러그인을 통해 webpack이 매칭할 파일 정규식을 지정해줄 수 있다. 

const webpack = require('webpack');
module.exports = {
  //...
  plugins: [
    new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /ko/),
  ],
};

moment.js 사이즈 654.75KB → 172.7KB로 어마어마하게 줄어들었다.

node_modules 9.6MB → 9.13MB

그러나 아직 전체 번들용량 11.65MB → 11.18MB에서는 살짝 줄어든 정도이다...또르르 천리길도 한걸음 부터이니 조금씩 줄여나가야겠다 🥲🥲

 

이 외에 `IgnorePlugin`을 사용하여 특정 디렉토리에 대한 require을 무시하는 방법도 있다.

 

참고링크

https://webpack.js.org/plugins/context-replacement-plugin/

github.com/jmblog/how-to-optimize-momentjs-with-webpack