Skip to content

chore(build): upgrade to webpack 5#30

Merged
jaschadub merged 1 commit into
masterfrom
chore/webpack-5-upgrade
May 26, 2026
Merged

chore(build): upgrade to webpack 5#30
jaschadub merged 1 commit into
masterfrom
chore/webpack-5-upgrade

Conversation

@jaschadub
Copy link
Copy Markdown
Member

Migrate the build off webpack 4 (unsupported since 2022) to webpack 5. Spiked end-to-end: prod build is green, prod server boots, full upload

  • password-protected download flow exercised under headless Chrome.

Package bumps
webpack 4.38.0 → ^5.97.0
webpack-cli ^3 → ^5
webpack-dev-server ^3 → ^5
webpack-dev-middleware ^3 → ^7
webpack-manifest-plugin ^2 → ^5 (named export changed)
copy-webpack-plugin ^6 → ^12
postcss-loader ^4 → ^8
svgo-loader ^3 → ^4 (svgo v3 plugin API)
val-loader ^2 → ^5
extract-text-webpack-plugin → REMOVED (mini-css-extract-plugin)
buffer → added (explicit polyfill)
path-browserify → added (used by content-disposition)

webpack.config.js

  • swap ExtractTextPlugin for MiniCssExtractPlugin (loader is chained in the CSS rule; [md5:contenthash:8] filename collapses to [contenthash:8])
  • IgnorePlugin: positional regex → { resourceRegExp }
  • ManifestPlugin: default import → named { WebpackManifestPlugin }
  • svgo plugins: { name, active: bool } objects → preset-default with overrides for disabled plugins, string entries for enabled ones
  • explicit output.publicPath: '' so webpack 5's default auto doesn't inject an auto/ prefix into manifest entries (server-side asset resolver expects bare filenames)
  • resolve.fallback: { buffer, path } + ProvidePlugin Buffer on both web and serviceWorker targets (webpack 5 dropped node-libs-browser auto-polyfill; app/ece.js relies on Buffer, content-disposition on path)
  • devServer.before → setupMiddlewares with explicit devServer.app
  • devServer.proxy: keyed object → array with context: [...]
  • drop the node-18 md4→sha256 createHash shim; webpack 5 doesn't need it

build/version_plugin.js

  • switch from the deprecated compilation.assets[name] = {...} mutation to the supported processAssets hook with webpack.sources.RawSource + emitAsset

common/assets.js

  • dev-middleware v5+ moved outputFileSystem under context; fall back to legacy fileSystem for older bundlers in case any caller still passes them

test/frontend/runner.js

  • drop logLevel: 'silent' (removed in webpack-dev-middleware v5)

Bundle deltas (gzip-uncompressed): app.js 373→397 KiB, serviceWorker.js 63→88 KiB — the +46 KiB total is the explicit buffer polyfill that webpack 4 auto-included.

Not addressed in this spike: 3 build warnings about importing the named export version from package.json (CommonJS default-export ambiguity, runtime works); file-loader/raw-loader still in use (work but emit deprecation hints — migrating to built-in Asset Modules is a separate cleanup).

Migrate the build off webpack 4 (unsupported since 2022) to webpack 5.
Spiked end-to-end: prod build is green, prod server boots, full upload
+ password-protected download flow exercised under headless Chrome.

Package bumps
  webpack                4.38.0 → ^5.97.0
  webpack-cli            ^3     → ^5
  webpack-dev-server     ^3     → ^5
  webpack-dev-middleware ^3     → ^7
  webpack-manifest-plugin ^2    → ^5  (named export changed)
  copy-webpack-plugin    ^6     → ^12
  postcss-loader         ^4     → ^8
  svgo-loader            ^3     → ^4  (svgo v3 plugin API)
  val-loader             ^2     → ^5
  extract-text-webpack-plugin  → REMOVED (mini-css-extract-plugin)
  buffer                       → added (explicit polyfill)
  path-browserify              → added (used by content-disposition)

webpack.config.js
- swap ExtractTextPlugin for MiniCssExtractPlugin (loader is chained
  in the CSS rule; `[md5:contenthash:8]` filename collapses to
  `[contenthash:8]`)
- IgnorePlugin: positional regex → { resourceRegExp }
- ManifestPlugin: default import → named { WebpackManifestPlugin }
- svgo plugins: { name, active: bool } objects → preset-default with
  `overrides` for disabled plugins, string entries for enabled ones
- explicit `output.publicPath: ''` so webpack 5's default `auto`
  doesn't inject an `auto/` prefix into manifest entries (server-side
  asset resolver expects bare filenames)
- resolve.fallback: { buffer, path } + ProvidePlugin Buffer on both
  web and serviceWorker targets (webpack 5 dropped node-libs-browser
  auto-polyfill; app/ece.js relies on Buffer, content-disposition on
  path)
- devServer.before → setupMiddlewares with explicit devServer.app
- devServer.proxy: keyed object → array with context: [...]
- drop the node-18 md4→sha256 createHash shim; webpack 5 doesn't need
  it

build/version_plugin.js
- switch from the deprecated `compilation.assets[name] = {...}`
  mutation to the supported processAssets hook with
  webpack.sources.RawSource + emitAsset

common/assets.js
- dev-middleware v5+ moved outputFileSystem under `context`; fall
  back to legacy `fileSystem` for older bundlers in case any
  caller still passes them

test/frontend/runner.js
- drop `logLevel: 'silent'` (removed in webpack-dev-middleware v5)

Bundle deltas (gzip-uncompressed): app.js 373→397 KiB,
serviceWorker.js 63→88 KiB — the +46 KiB total is the explicit
buffer polyfill that webpack 4 auto-included.

Not addressed in this spike: 3 build warnings about importing the
named export `version` from package.json (CommonJS default-export
ambiguity, runtime works); `file-loader`/`raw-loader` still in use
(work but emit deprecation hints — migrating to built-in Asset
Modules is a separate cleanup).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant