Guessing what is large in a bundle is unreliable, and the answer is frequently one dependency that pulled in a locale file for every language on earth.
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
plugins: [
new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false }),
]
// and the classic finding:
// moment.js locales — 330 KB
new webpack.IgnorePlugin(/^./locale$/, /moment$/)
The treemap shows parsed size rather than transferred size by default, and switching to the gzipped view is what makes the numbers comparable to what a user downloads. The moment.js case appears in almost every project that uses it and is worth checking first. Running the analyser in static mode writes an HTML file that can be committed to a build artifact, which makes bundle growth reviewable rather than something noticed a year later.