I've followed pretty much all the Webpack 2 tutorials there are on code-splitting, but none of them seem to address the problem of code-splitting to a maximum bundle size. Since Webpack 2, the build emits a warning when a bundle is over 250kB. So what I'm trying to do is split my build into:
- Application code (so everything I've written myself)
- Async code
- Vendor code (everything from node_modules)
- A manifest (so that the bundle hash doesn't change unnecessarily across builds)
Now the vendor code bundle goes over 250kB, so I want to split that into bundles of 250kB max. But there doesn't seem to be any documentation on how to do that. I'm currently using the following webpack config for production builds:
var PreloadWebpackPlugin = require('preload-webpack-plugin')
var CleanWebpackPlugin = require('clean-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var path = require('path')
var webpack = require('webpack')
// Define two different css extractors
var extractBundle = new ExtractTextPlugin('[name]-[hash].css')
var extractVendor = new ExtractTextPlugin('vendor-[hash].css')
module.exports = {
entry: {
main: './client/index.jsx'
},
output: {
filename: '[name].[chunkhash].js',
path: path.join(__dirname, 'dist')
},
resolve: {
extensions: ['.js', '.jsx'],
modules: [
'./client',
'node_modules'
]
},
module: {
rules: [
{
test: /\.js$|\.jsx$/,
exclude: /(node_modules)/,
loader: 'babel-loader'
},
{
test: /\.css$/,
include: /node_modules/,
loader: extractVendor.extract({
fallback: 'style-loader?sourceMap',
use: 'css-loader?sourceMap'
})
},
{
test: /\.css$/,
exclude: /node_modules/,
loader: extractBundle.extract({
fallback: 'style-loader?sourceMap',
use: 'css-loader?sourceMap'
})
}
]
},
devtool: 'source-map',
plugins: [
extractVendor,
extractBundle,
new CleanWebpackPlugin(
path.join(__dirname, 'dist'),
{ verbose: false }
),
new CopyWebpackPlugin([{ from: path.join(__dirname, 'static')}]),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true
}),
new webpack.EnvironmentPlugin([
'NODE_ENV',
'SPACE_ID',
'CONTENT_DELIVERY_TOKEN',
'PROD_TRACKING_ID'
]),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'client', 'index.ejs'),
filename: 'index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
}),
new PreloadWebpackPlugin({
rel: 'preload'
}),
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: function(module){
return module.context && module.context.indexOf("node_modules") !== -1;
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: "manifest",
minChunks: Infinity
})
]
}
Which outputs:
Asset Size Chunks Chunk Names
android-chrome-192x192.png 20.1 kB [emitted]
0.a473279b795f515798d3.js 4.52 kB 0 [emitted]
main.4cabac8591610d12205d.js 33.2 kB 2 [emitted] main
manifest.b0393c03cc63335ff287.js 1.51 kB 3 [emitted] manifest
vendor-4a38a077b20fa163ffd6.css 2.21 kB 1 [emitted] vendor
main-4a38a077b20fa163ffd6.css 492 bytes 2 [emitted] main
0.a473279b795f515798d3.js.map 35.3 kB 0 [emitted]
vendor.04e2ff4d4cdd8e49d6ad.js.map 3.83 MB 1 [emitted] vendor
vendor-4a38a077b20fa163ffd6.css.map 8.9 kB 1 [emitted] vendor
main.4cabac8591610d12205d.js.map 209 kB 2 [emitted] main
main-4a38a077b20fa163ffd6.css.map 1.32 kB 2 [emitted] main
manifest.b0393c03cc63335ff287.js.map 14.3 kB 3 [emitted] manifest
vendor.04e2ff4d4cdd8e49d6ad.js 436 kB 1 [emitted] [big] vendor
apple-touch-icon.png 16.1 kB [emitted]
browserconfig.xml 246 bytes [emitted]
favicon-16x16.png 846 bytes [emitted]
favicon-32x32.png 1.93 kB [emitted]
android-chrome-512x512.png 128 kB [emitted]
favicon.ico 15.1 kB [emitted]
manifest.json 385 bytes [emitted]
mstile-150x150.png 1.5 kB [emitted]
robots.txt 24 bytes [emitted]
safari-pinned-tab.svg 35.3 kB [emitted]
index.html 1.35 kB [emitted]
How can I automatically split the vendor bundle into chunks that don't exceed the recommended 250kB?
via ismay
No comments:
Post a Comment