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
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.
There are four basic concepts in webpack: entry , output , modules and plug-ins . These configurations are added in webpack.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With