Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • Is [emitted] means the given chunk was built?
  • How can I verify that the given chunk is rebuilt or not?
  • How can I see the chunkHash? (I want to make sure webpack sees the same way as I with md5)
  • What optimisations can I look for?

Facts:

  • The vendor bundle is not written to disk in watch mode if application code changes, I verified with modified date and by deleting it. The file was not created when rebuild triggered. Also, md5 hash doesn't change for the vendor code.
    • Most time spent in modules building, the module counter running from 0->1200.

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
like image 947
Mate Gulyas Avatar asked Dec 04 '16 11:12

Mate Gulyas


People also ask

What is the output of webpack?

Configuring the output configuration options tells webpack how to write the compiled files to disk. Note that, while there can be multiple entry points, only one output configuration is specified.

What are 4 core concept of webpack?

There are four basic concepts in webpack: entry , output , modules and plug-ins . These configurations are added in webpack.

How do I know if my webpack is working?

Webpack has a web server called webpack-dev-server. If you go to http://localhost:8080/webpack-dev-server/, you should see your application running there, along with any log statements in your app.

What is webpack in simple words?

Webpack is a static module bundler for JavaScript applications that takes all of your code and turns it into something that can be used in a web browser. Modules are reusable bits of code made up of JavaScript, node modules, images, and CSS styles that are bundled and ready to use in your website.


1 Answers

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.

like image 148
Filip Dupanović Avatar answered Sep 22 '22 10:09

Filip Dupanović