Search code examples
angularwebpackwebpack-2

Optimize Angular vendor output


In trying to optimize the vendor bundle when building with webpack, I'm using the NgcWebpackPlugin.

This is the vendor bundle visually presented: enter image description here

What surprises me is the presence of the angular compiler module even tho we are utilizing AOT.

Do I need to somehow explicitly declare that I don't need the compiler in the bundle? Or am I missing something else?


Here's the vendor.ts:

import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
import '@angular/forms'
import '@angular/animations'
import 'rxjs';
import '@ngrx/core';
import '@ngrx/store';
import 'platform';
import 'underscore';
import 'typed-immutable-record';
import 'toastr';
import 'socket.io-client';
import 'moment';
import 'moment-timezone';
import 'jquery';
import 'immutable';
import 'humanize-duration';
import 'fuzzy';
import 'bricklayer';
import 'ngx-bootstrap';

Here's the boot-aot.ts:

/**
 * Angular bootstrapping
 */
import { platformBrowser } from '@angular/platform-browser';
import { decorateModuleRef } from './environment';
/**
 * App Module
 * our top level module that holds all of our components.
 */
import { AppModuleNgFactory } from '../../compiled/app/src/app.module.ngfactory';
/**
 * Bootstrap our Angular app with a top level NgModule.
 */
export function main(): Promise<any> {
  return platformBrowser()
    .bootstrapModuleFactory(AppModuleNgFactory)
    .then(decorateModuleRef)
    .catch((err) => console.error(err));
}

export function bootstrapDomReady() {
  document.addEventListener('DOMContentLoaded', main);
}

bootstrapDomReady();

Solution

  • In vendor.ts remove import 'platform-browser-dynamic' and in your webpack config manually remove unneeded modules.

    Sample webpack config:

    var empty = {
        NgProbeToken: {},
        HmrState: function() {},
        _createConditionalRootRenderer: function(rootRenderer, extraTokens, 
    coreTokens) {
          return rootRenderer;
        },
        __platform_browser_private__: {}
      };
    
    return {
        module: {
          rules: [
            ({
              test: /\.ts$/,
              use: removeEmpty([
                {
                  loader: '@angularclass/hmr-loader',
                  options: {
                    pretty: isDev,
                    prod: isProd
                  }
                },
                {
                  /**
                   *  MAKE SURE TO CHAIN VANILLA JS CODE, I.E. TS COMPILATION 
    OUTPUT.
                   */
                  loader: 'ng-router-loader',
                  options: {
                    loader: 'async-import',
                    genDir: 'compiled',
                    aot: isProd
                  }
                },
                {
                  loader: 'awesome-typescript-loader',
                  options: {
                    configFileName: 'tsconfig.webpack.json',
                    useCache: !isProd
                  }
                },
                ifProd(WebpackStrip.loader('console.log', 'console.info', 
    'console.error')),
                {
                  loader: 'angular2-template-loader'
                }
              ]),
              exclude: [/\.(spec|e2e)\.ts$/]
            })
          ]
        },
        plugins: [
        new ngcWebpack.NgcWebpackPlugin({
          disabled: !isProd,
          tsConfig: resolve('tsconfig.webpack.json')
        }),
    
        new NormalModuleReplacementPlugin(
          /zone\.js(\\|\/)dist(\\|\/)long-stack-trace-zone/,
          empty
        ),
    
        new HashedModuleIdsPlugin(),
    
         new NormalModuleReplacementPlugin(
           /@angular(\\|\/)upgrade/,
           empty
         ),
         new NormalModuleReplacementPlugin(
           /@angular(\\|\/)compiler/,
           empty
         ),
         new NormalModuleReplacementPlugin(
           /@angular(\\|\/)platform-browser-dynamic/,
           empty
         ),
         new NormalModuleReplacementPlugin(
           /dom(\\|\/)debug(\\|\/)ng_probe/,
           empty
         ),
         new NormalModuleReplacementPlugin(
           /dom(\\|\/)debug(\\|\/)by/,
           empty
         ),
         new NormalModuleReplacementPlugin(
           /src(\\|\/)debug(\\|\/)debug_node/,
           empty
         ),
         new NormalModuleReplacementPlugin(
           /src(\\|\/)debug(\\|\/)debug_renderer/,
           empty
         )
      ]
    };