Mate Gulyas
Mate Gulyas

Reputation: 609

Understand Webpack Output

I try to optimise our 6s build time in watch mode with 1200 modules (95% vendor). I try to understand what is happening so I can make it faster.

Things I don't understand:

Facts:

The webpack config is the following:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var WatchIgnorePlugin = require('watch-ignore-webpack-plugin')
var CopyWebpackPlugin = require('copy-webpack-plugin');
var path = require('path');
var webpack = require('webpack');

function isExternal(module) {
    var userRequest = module.userRequest;

    if (typeof userRequest !== 'string') {
          return false;
        }

    return userRequest.indexOf('bower_components') >= 0 ||
             userRequest.indexOf('node_modules') >= 0 ||
             userRequest.indexOf('libraries') >= 0;
}

module.exports = {
  context: __dirname + "/src",
  cache: true,
  cacheDirectory: '.cache',
  entry: {
      index: ["babel-polyfill", "./index"],
      login: "./login"
  },
  resolve: {
    alias: {
      config: path.join(__dirname, 'src/config', `${process.env.NODE_ENV || 'development'}`)
    },
    modulesDirectories: [
      'node_modules',
    ],
    unsafeCache: true,
    extensions: ["", ".js", ".jsx"]
  },
  devtool: 'eval',
  module: {
    loaders: [{
      test: /\.scss$/,
      include: /src/,
      exclude: /node_modules/,
      loader: ExtractTextPlugin.extract('css!sass')
    }, {
      test: /\.css$/,
      exclude: /node_modules/,
      include: /src/,
      loaders: ['style', 'css?sourceMap'],
    },
    {
      test: /\.jsx?$/,
      include: /src/,
      exclude: /node_modules/,
      loader: "babel-loader",
      query: {
        "cacheDirectory": ".cache",
        "presets":  ["es2015", "stage-0", "react"],
        "plugins":  ["transform-class-properties", "transform-object-rest-spread"]
      }
    }],
    noParse: [
      /underscore\/underscore\.js$/,
      /react-with-addons\.js$/,
    ]
  },
  output: {
    filename: "[name].bundle.js",
    path: __dirname + "/dist",
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function(module) {
        return isExternal(module);
      },
    }),
    new WatchIgnorePlugin([
      path.resolve(__dirname, './node_modules/'),
      path.resolve(__dirname, './.git/')
    ]),
    new CopyWebpackPlugin([
      { from: 'static', to: 'static' }
    ]),
    new CopyWebpackPlugin([
      { from: 'login.html', to: 'login.html' }
    ]),
    new CopyWebpackPlugin([
      { from: 'index.html', to: 'index.html' }
    ]),
    new ExtractTextPlugin('[name].css', {
      allChunks: true
    })
  ],
  watchOptions: {
    poll: 300,
    ignore: /node_modules/,
  },
  externals: {}
}

The output in watch mode:

[mip] (+master)> node node_modules/webpack/bin/webpack.js --watch --progress --display-chunks --display-cached --display-reasons -v
Hash: fadbfa42fdd7810886d6  
Version: webpack 1.13.3
Time: 6346ms
                 Asset       Size  Chunks             Chunk Names
       index.bundle.js     582 kB       0  [emitted]  index
       login.bundle.js    8.88 kB       1  [emitted]  login
      vendor.bundle.js     4.9 MB       2  [emitted]  vendor
             index.css    87.2 kB       0  [emitted]  index
             login.css    44.4 kB       1  [emitted]  login
   static/img/logo.png    4.28 kB          [emitted]  
static/img/favicon.ico     270 kB          [emitted]  
            login.html  573 bytes          [emitted]  
            index.html  574 bytes          [emitted]  
chunk    {0} index.bundle.js, index.css (index) 519 kB {2} [rendered]
    [0] multi index 40 bytes {0} [built]
     + 100 hidden modules
chunk    {1} login.bundle.js, login.css (login) 7.33 kB {2} [rendered]
     + 5 hidden modules
chunk    {2} vendor.bundle.js (vendor) 4.41 MB [rendered]
     + 1191 hidden modules

Upvotes: 6

Views: 1564

Answers (1)

Filip Dupanović
Filip Dupanović

Reputation: 33660

If you want to speed up your initial development builds, you're going to want to reduce the amount of time Webpack spends on analyzing chunks, reduce the number of HTTP requests, introduce HMR for incremental changes..

You can start by removing CommonsChunkPlugin and ExtractTextPlugin. If you wish to take vendor modules from the equation, then you can build these as a library using DllPlugin in one compilation and then continue reusing them with DllReferencePlugin for your main bundle compilation for as long as the vendor sources do not change. You can read more about these in the optimization documentation, but here's an excellent article by Rob Knight where he provides more details.

Lastly, there's really no need to inquire about whether or not Webpack is correctly invalidating chunks when the loaders are configured. They're well equipped to track dependencies that are resting on disk and will judiciously invalidate anything onward. I can recommend webpack-bundle-analyzer to analyze your outputs.

Upvotes: 1

Related Questions