How Upgrading to Webpack 5 Slashed Build Times by 60% in a Large Music App
This guide details how a massive music‑artist web application reduced its full build time from 140 seconds to 55 seconds and its incremental compile time from up to 80 seconds down to about 1 second by migrating from Webpack 4 to Webpack 5, including preparation steps, configuration changes, and common pitfalls.
Background
The music‑musician‑web‑node project is a large music‑artist platform with dozens of pages. On a MacBook Pro M1 a full build with Webpack 4 took about 140 s, while typical incremental builds were 4‑5 s. When many shared TypeScript definition files changed, incremental builds could exceed 80 s. Improving developer experience therefore required a faster build system, and upgrading to Webpack 5 was identified as the most direct solution.
Performance gains after migrating to Webpack 5
Startup time
Full build time dropped to roughly 55 s – a reduction of about 60 % .
Incremental build time
Typical incremental builds now finish in around 1 s. Even the worst‑case change to a shared TypeScript definition, which previously took > 80 s, completes in about 3 s – an improvement of more than 80 % .
Production build
Production bundle creation decreased from ~ 240 s to 200 s. This requires upgrading terser-webpack-plugin to the latest version.
Bundle size
Webpack 5’s built‑in optimizations and the recommended configuration generally produce smaller bundles, although exact size differences are hard to measure in a project of this scale.
Pre‑upgrade preparation (Webpack 4 → Webpack 5)
Upgrade Webpack to the latest v4 release (if still on v3 or earlier).
Upgrade webpack-cli to the latest version.
Upgrade all loaders and plugins to versions that are compatible with Webpack 4. Avoid versions that already require Webpack 5.
Typical loader/plugin versions used before the migration:
terser-webpack-plugin : 4.x for Webpack 4, latest for Webpack 5
babel-loader : 7.x or 8.x extract-text-webpack-plugin : latest v4; replace with mini-css-extract-plugin for Webpack 5
optimize-css-assets-webpack-plugin : latest v4; replace with css-minimizer-webpack-plugin for Webpack 5
ts-loader : 8.x for Webpack 4, latest for Webpack 5
less-loader : 7.x (last version supporting Webpack 4)
sass-loader : 10.x (last version supporting Webpack 4)
css-loader : 5.x (last version supporting Webpack 4)
postcss-loader : 4.x (last version supporting Webpack 4)
Fix warnings and errors after the preparatory upgrades
Run a build and resolve any warnings or errors that appear before proceeding.
Update deprecated Webpack 4 configuration syntax
Replace the following options with their Webpack 5 equivalents: optimization.hashedModuleIds: true →
optimization.moduleIds: 'hashed' optimization.namedChunks: true→
optimization.chunkIds: 'named' NamedModulesPlugin→
optimization.moduleIds: 'named' NamedChunksPlugin→
optimization.chunkIds: 'named' HashedModuleIdsPlugin→
optimization.moduleIds: 'hashed' optimization.noEmitOnErrors: false→ optimization.emitOnErrors: true Various splitChunks cache‑group changes (see the official migration guide for details).
Test Webpack 5 compatibility
Webpack 5 no longer polyfills Node core modules by default. Create a temporary configuration that disables Node globals to surface runtime errors early:
module.exports = {
node: {
Buffer: false,
process: false
}
};If the application crashes with ReferenceError: Buffer is not defined or ReferenceError: process is not defined, add appropriate polyfills via resolve.fallback (see the polyfill list below).
Actual upgrade to Webpack 5
Install the latest Webpack
npm install -D webpack@latestConfiguration changes
Remove optimization.moduleIds and optimization.chunkIds; Webpack 5 provides better defaults.
Replace [hash] placeholders with [contenthash] for more efficient caching.
Update IgnorePlugin syntax to
new webpack.IgnorePlugin({ resourceRegExp: /your‑regexp/ }).
Node configuration: only global, __dirname, and __filename remain supported under node. Move other Node options to resolve.fallback. Example:
// Old Webpack 4 syntax
node: {
fs: 'empty'
}
// Webpack 5 equivalent
resolve: {
fallback: {
fs: false
}
}Replace legacy loaders ( url-loader, raw-loader, file-loader) with the built‑in Assets Module.
For optimization.splitChunks, either keep the default configuration or use { chunks: 'all' }. Adjust cache‑group keys as needed (e.g., defaultVendors instead of vendors).
Code adjustments
Remove explicit /* webpackChunkName: '...' */ comments; in development mode Webpack 5 automatically names chunks based on the file name.
Update JSON imports:
// Before (Webpack 4)
import { version } from './package.json';
console.log(version);
// After (Webpack 5)
import pkg from './package.json';
console.log(pkg.version);Error handling during migration
Schema errors
These are configuration syntax errors. Webpack’s error messages point directly to the offending line; fix the configuration as indicated.
Missing polyfills (compilation errors)
Typical error: module not found for a Node core module. Add the required polyfills via resolve.fallback:
module.exports = {
resolve: {
fallback: {
assert: require.resolve('assert'),
buffer: require.resolve('buffer'),
console: require.resolve('console-browserify'),
crypto: require.resolve('crypto-browserify'),
// ...other core modules as needed
}
}
};Runtime errors
Missing Node globals : Use ProvidePlugin to inject polyfills.
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser'
})
]
};Changed import style : Some packages that worked with default imports in Webpack 4 require named imports in Webpack 5.
// Before
import uuidv4 from 'uuid/dist/v4';
// After
import { v4 as uuidv4 } from 'uuid';Undefined export : Packages that exported a default object may now require named imports.
// Before
import watermark from 'watermark-dom';
// After
import { watermark } from 'watermark-dom';Because runtime errors are highly project‑specific, thorough QA testing after migration is essential.
Loader optimizations after upgrade
Remove all cache‑related loaders and plugins; Webpack 5’s built‑in caching is sufficient.
Replace happypack with the officially supported thread-loader for multi‑threaded builds.
Swap optimize-css-assets-webpack-plugin for css-minimizer-webpack-plugin.
Replace ts-loader with @babel/preset-typescript plus fork-ts-checker-webpack-plugin for type checking.
References
Official migration guide: https://webpack.js.org/migrate/5/
Webpack 4 migration guide: https://webpack.js.org/migrate/4/
Node configuration docs: https://webpack.js.org/configuration/node/
Assets Module guide: https://webpack.js.org/guides/asset-modules/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
