简体   繁体   中英

Webpack and large vendor bundles

I find my webpack vendor bundles very large (~1.6 MB originally). After using webpack-bundle-size-analyzer, I found angular to be contributing a large part to this.

➜  dapper-ui git:(master) webpack --config ./conf/webpack-dist.conf.js --json | webpack-bundle-size-analyzer
angular: 1.13 MB (25.9%)
lodash: 526.94 KB (11.8%)
moment: 429.12 KB (9.58%)
angular-ui-router: 339.35 KB (7.58%)
chart.js: 311.27 KB (6.95%)
angular-ui-bootstrap: 264.26 KB (5.90%)
ng-table: 197.55 KB (4.41%)
angular-animate: 147.1 KB (3.29%)
angularjs-slider: 87.52 KB (1.95%)
validator: 70.85 KB (1.58%)
bootstrap-sass: 68.07 KB (1.52%)
buffer: 47.47 KB (1.06%)
angular-resource: 34.45 KB (0.769%)
angular-messages: 27.39 KB (0.612%)
angular-file-upload: 20.36 KB (0.455%)
angular-sticky-plugin: 19.06 KB (0.426%)
color-convert: 16.53 KB (0.369%)
ng-tags-input: 15.62 KB (0.349%)
angular-aria: 14.87 KB (0.332%)
angular-ui-bootstrap-datetimepicker: 13.26 KB (0.296%)
angular-chart.js: 12.7 KB (0.284%)
chartjs-color: 10.96 KB (0.245%)
chartjs-color-string: 5.9 KB (0.132%)
color-name: 4.49 KB (0.100%)
base64-js: 3.4 KB (0.0760%)
angular-validation-match: 2.06 KB (0.0460%)
ieee754: 2.01 KB (0.0448%)
css-loader: 1.47 KB (0.0328%)
webpack: 1.03 KB (0.0230%)
isarray: 132 B (0.00288%)
<self>: 622.84 KB (13.9%)

I tried checked the minified angular file is ~160kb. I guess its not using or showing the minified size. In any case, I am using Uglify so I'd expect the size to be similar?

I tried using webpack aliases, to make webpack use the minified bundles but that didnt reduce the vendor bundle much.

For the time being I split up the vendor bundles into 4 parts so they can be downloaded in parallel to speed things up but am still curious how to do better and also why is angular and other libraries so large even tho the minified code provided is significantly smaller.

My webpack config:

const webpack = require('webpack');
const conf = require('./gulp.conf');
const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const pkg = require('../package.json');
const autoprefixer = require('autoprefixer');

const deps = Object.keys(pkg.dependencies);
const vendorNumInBundle = Math.ceil(deps.length / 4)

module.exports = {
  module: {
    preLoaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint'
      }
    ],

    loaders: [
      {
        test: /.json$/,
        loaders: [
          'json'
        ]
      },
      {
        test: /\.(css|less)$/,
        loaders: ExtractTextPlugin.extract(['css-loader', 'postcss-loader', 'less-loader'])
      },
      {
        test: /\.scss$/,
        loaders: ExtractTextPlugin.extract(['css-loader', 'postcss-loader', 'sass-loader'])
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: [
          'ng-annotate'
        ]
      },
      {
        test: /.html$/,
        loaders: [
          'html'
        ]
      }
    ]
  },
  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.NoErrorsPlugin(),
    new HtmlWebpackPlugin({
      template: conf.path.src('index.html')
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {unused: true, dead_code: true, warnings: false}, // eslint-disable-line camelcase
      comments: false
    }),
    new ExtractTextPlugin('index-[contenthash].css'),
    new webpack.optimize.CommonsChunkPlugin({
      names: ['vendor5', 'vendor4', 'vendor3', 'vendor2', 'vendor1'],
      minChunks: Infinity
    }),
    function()
    {
        this.plugin("done", function(stats)
        {
            if (stats.compilation.errors && stats.compilation.errors.length && process.argv.indexOf('--watch') == -1)
            {
                console.log(stats.compilation.errors);
                process.exit(1); // or throw new Error('webpack build failed.');
            }
            // ...
        });
    }
  ],
  postcss: () => [autoprefixer],
  output: {
    path: path.join(process.cwd(), conf.paths.dist),
    filename: '[name]-[hash].js'
  },
  entry: {
    app: `./${conf.path.src('index')}`,
    vendor1: deps.slice(0, vendorNumInBundle),
    vendor2: deps.slice(vendorNumInBundle, vendorNumInBundle * 2),
    vendor3: deps.slice(vendorNumInBundle * 2, vendorNumInBundle * 3),
    vendor4: deps.slice(vendorNumInBundle * 3),
    vendor5: [
      './src/assets/js/angular-natural-language.min.js',
      './src/assets/js/angular-img-cropper.js',
      './src/assets/js/satellizer.min.js',
      './src/assets/js/satellizer.min.js',
      './src/assets/js/angular-bootstrap-toggle',
    ]
  }
};

I guess its not using or showing the minified size.

This is correct. The output you are seeing is for the unminified versions of the libraries. See the Important Note about Minified Code in the README.

Size information for the unminified versions is useful to find out roughly the proportions of the bundles taken up by different modules. If you want to see minified sizes in the output of this tool, you'll need to configure Webpack to minify individual modules using a loader, rather than just minifying the whole bundle at the end of the process, which is what happens when you use webpack --optimize-minimize .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM