Skip to content

Migrate dev server to webpack-dev-server v5 (rc.4) - #224

Merged
endway merged 1 commit into
masterfrom
EWN-29581/wds5-dev-server
Aug 27, 2026
Merged

endway merged 1 commit into
masterfrom
EWN-29581/wds5-dev-server

Conversation

@endway

@endway endway commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Why

RunWebpackDevServerStrategy still used the webpack-dev-server v3 API — new WebpackDevServer(compiler, options) and server.listen(port, host, cb).

v4 tolerated the old argument order behind a deprecated compatibility shim (it logged DEP_WEBPACK_DEV_SERVER_CONSTRUCTOR). v5 removed that shim, so the compiler gets validated as an options object and any consumer on wds 5 dies at startup:

Invalid options object. Dev Server has been initialized using an options object
that does not match the API schema.
 - options has an unknown property '_assetEmittingPreviousFiles'.

(_assetEmittingPreviousFiles is an internal webpack Compiler field — the tell-tale sign of the swapped arguments.)

This surfaced in peo-frontend, which pins wds 5 via an overrides entry to pick up two dev-server security fixes, and consequently had a broken npm start for ~2.5 months.

What

  • run-webpack-dev-server.ts → v5 API: options first, compiler second; port/host folded into those options (v5 reads them from there, not from listen() arguments); start()/stop() replacing listen()/close().
  • webpack-dev-server ^4.11.1^5.2.6. 5.2.6 carries the fixes for the CSRF-via-internal-dev-endpoints and DoS-via-malformed-Host/Origin advisories (both affect <= 5.2.5). Consumers currently forcing wds 5 through overrides to get those can drop the override once they're on this ffbt.
  • typescript ^4.3.4^4.9.5 — required, not housekeeping. wds 5's types reference import("open").Options, and open@10 declares import {type ChildProcess} from 'node:child_process'. Inline type modifiers need TS ≥ 4.5, and skipLibCheck does not suppress syntax errors in .d.ts files, so the build fails on TS 4.3 with open/index.d.ts(1,14): error TS1005.
  • Dropped @types/webpack-dev-server — now a deprecated stub, since wds ships its own types. Removing it also avoids v4 types shadowing v5's.
  • Version → 1.0.0-rc.4.

⚠️ Breaking for consumers: onBeforeSetupMiddleware

wds v5 removed onBeforeSetupMiddleware. Any project passing it via devServerConfig will fail schema validation after upgrading. The migration is setupMiddlewares:

devServerConfig: {
    setupMiddlewares: (middlewares, devServer) => {
        initEndpoints(devServer);

        return middlewares;
    },
},

Registering routes directly on devServer.app inside the callback preserves the old ordering: wds invokes setupMiddlewares before it applies its own middleware array, so consumer routes keep precedence over historyApiFallback. Worth calling out in the release notes for rc.4 — peo-frontend needs exactly this change.

Verification

Check Result
npm run build (tsc) exit 0, no TS errors
npm run test:ci 2 suites, 19 tests passed
Consumer smoke test (peo-frontend) npm start boots on :9095, no schema error, webpack compiled successfully
Middleware precedence /dev-api/documentsapplication/json (real payload), /api/v2/edit/setDatestext/plain OK — handled by the app's routes, not swallowed by the SPA fallback
Consumer type-check under TS 4.9.5 peo-frontend src/ compiles with 0 errors

Consumer testing was done by npm pack-ing this branch and installing the tarball into peo-frontend.

Note

npm install on this repo needs --legacy-peer-deps on modern npm — pre-existing and unrelated: the root wants tslint ^6.0.0 while tslint-config-airbnb@5.11.2 peer-requires tslint ^5.11.0. Untouched here.

🤖 Generated with Claude Code

RunWebpackDevServerStrategy still used the webpack-dev-server v3 API:
`new WebpackDevServer(compiler, options)` plus `server.listen(port, host, cb)`.
v4 tolerated the old argument order through a deprecated compatibility shim,
but v5 removed it, so the compiler was validated as an options object and any
consumer on v5 failed with:

    Invalid options object. Dev Server has been initialized using an options
    object that does not match the API schema.
     - options has an unknown property '_assetEmittingPreviousFiles'.

Switch to the v5 API: options first and compiler second, port/host folded into
those options (v5 reads them from there rather than from listen() arguments),
and start()/stop() instead of listen()/close().

Bump webpack-dev-server to ^5.2.6, which also carries the fixes for
GHSA CSRF-via-internal-dev-endpoints and DoS-via-malformed-Host/Origin
(both <= 5.2.5). Consumers pinning wds 5 through an `overrides` entry to get
those fixes no longer need it.

TypeScript goes ^4.3.4 -> ^4.9.5 because this is required, not cosmetic:
webpack-dev-server 5 references `import("open").Options` in its types, and
open@10 declares `import {type ChildProcess}` — inline type modifiers need
TS >= 4.5, and `skipLibCheck` does not suppress syntax errors in .d.ts files.

Drop @types/webpack-dev-server: it is now a deprecated stub, since
webpack-dev-server ships its own type definitions.

Note for consumers: webpack-dev-server v5 removed `onBeforeSetupMiddleware`.
Projects using it must move to `setupMiddlewares`, registering their routes on
`devServer.app` inside the callback — that callback runs before the dev server
applies its own middleware stack, so route precedence over historyApiFallback
is preserved.

Verified: tsc build clean, 2 test suites / 19 tests pass, and a consumer
(peo-frontend) starts the dev server successfully with endpoints served ahead
of the SPA fallback.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@endway
endway merged commit 67a0838 into master Aug 27, 2026
1 of 7 checks passed
@endway
endway deleted the EWN-29581/wds5-dev-server branch August 27, 2026 12:38
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