Reputation: 11
I'm trying to reduce the size of my bundle.js. Here is my webpack config for production:
module.exports = () => {
return {
entry: ['babel-polyfill', './src/app.js'],
output: {
path: path.join(__dirname, 'public', 'dist'),
filename: 'bundle.js',
chunkFilename: '[name].js'
},
optimization: {
runtimeChunk: true,
splitChunks: {
chunks: 'all',
minSize: 50000,
maxSize: 250000,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
priority: -10
},
}
},
minimizer: [
new UglifyJSPlugin({
uglifyOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
},
cache: true,
parallel: true,
sourceMap: true
}),
new OptimizeCSSAssetsPlugin({})
]
},
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
},{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}]
},
plugins: [
new webpack.DefinePlugin({/*env variables*/}),
new MiniCssExtractPlugin({
filename: 'styles.css',
}),
new HtmlWebpackPlugin({ template: 'index.ejs', filename: path.join(__dirname, 'public', 'index.html')}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
devtool: 'source-map'
};
};
My app is structured like a classic React/Redux app followed:
|-src
|-|-app.js
|-|-actions
|-|-components
|-|-helpers
|-|-routers
|-|-selectors
|-|-store
With this webpack config, I managed to extract the css out and split into chunks of maximum 250kb. I also reduced the size of moment. After all this effort, my entrypoint is still a total of 583Kb.
What else I can do? I tried lazy loading part of the application but it didn't work. So if you have example of lazy loading for a React app, that would be great.
Upvotes: 1
Views: 1285
Reputation: 21765
I have webpack 6.0.1. Based on the documentation I use the following plugins:
I tested, use the following configuration ideas for webpack.config.js. You can test your configuration against these settings:
//webpack.config.js
module.exports = {
...
devtool: 'cheap-module-source-map',
...
plugins : [
...
new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 4
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
],
...
optimization: {
namedModules: false,
namedChunks: false,
nodeEnv: 'production',
flagIncludedChunks: true,
occurrenceOrder: true,
sideEffects: true,
usedExports: true,
concatenateModules: true,
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
},
minSize: 30000,
maxAsyncRequests: 5,
maxAsyncRequests: 3,
},
noEmitOnErrors: true,
minimize: true,
minimizer: [
// we specify a custom UglifyJsPlugin here to get source maps in production
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: false,
ecma: 6,
mangle: true
},
sourceMap: true
})
],
removeAvailableModules: true,
removeEmptyChunks: true,
mergeDuplicateChunks: true,
},
...
}
Upvotes: 1