From 5849b81672663e77c65ffa6e6af0b908cdfc683e Mon Sep 17 00:00:00 2001 From: Oleksandr Karpov Date: Thu, 27 Aug 2026 15:36:10 +0300 Subject: [PATCH] Migrate dev server to webpack-dev-server v5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- package.json | 7 +++---- .../webpack/runner/run-webpack-dev-server.ts | 21 ++++++++++++------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index f353936..12850c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ffbt", - "version": "1.0.0-rc.3", + "version": "1.0.0-rc.4", "description": "Build a Typescript app without pain", "license": "MIT", "engines": { @@ -49,11 +49,11 @@ "tslib": "^2.4.1", "tslint": "^6.0.0", "tslint-config-airbnb": "^5.11.2", - "typescript": "^4.3.4", + "typescript": "^4.9.5", "url-loader": "^4.1.1", "webpack": "^5.75.0", "webpack-bundle-analyzer": "^4.8.0", - "webpack-dev-server": "^4.11.1", + "webpack-dev-server": "^5.2.6", "webpack-merge": "^5.8.0", "webpack-notifier": "^1.15.0" }, @@ -63,7 +63,6 @@ "@types/jest": "^27.5.2", "@types/node": "^14.17.4", "@types/stylelint": "^13.13.3", - "@types/webpack-dev-server": "^4.7.2", "@types/webpack-merge": "^5.0.0", "jest": "^27.3.1", "ts-jest": "^27.0.7", diff --git a/src/services/webpack/runner/run-webpack-dev-server.ts b/src/services/webpack/runner/run-webpack-dev-server.ts index 8781408..9feaea9 100644 --- a/src/services/webpack/runner/run-webpack-dev-server.ts +++ b/src/services/webpack/runner/run-webpack-dev-server.ts @@ -10,18 +10,23 @@ export class RunWebpackDevServerStrategy implements ServiceRunStrategy { run(): void { const compiler = webpack(this.webpackConfig); - const server = new WebpackDevServer(compiler, this.webpackConfig.devServer || {}); - const {port, host} = { - port: 9091, - host: "localhost", - ...this.webpackConfig.devServer, - }; + // webpack-dev-server v5 takes the options as the first argument and the + // compiler as the second, and reads port/host from those options rather + // than from listen() arguments. + const server = new WebpackDevServer( + { + port: 9091, + host: "localhost", + ...this.webpackConfig.devServer, + }, + compiler, + ); - server.listen(port, host, console.error); + server.start().catch(console.error); cleanupIfError(() => { - server.close(); + server.stop(); }); } }