diff --git a/packages/angular_devkit/build_webpack/package.json b/packages/angular_devkit/build_webpack/package.json index daf2861bd524..0a267221c186 100644 --- a/packages/angular_devkit/build_webpack/package.json +++ b/packages/angular_devkit/build_webpack/package.json @@ -17,6 +17,6 @@ }, "peerDependencies": { "webpack": "^5.30.0", - "webpack-dev-server": "^3.1.4" + "webpack-dev-server": "^4.0.0" } } diff --git a/packages/angular_devkit/build_webpack/src/webpack-dev-server/index.ts b/packages/angular_devkit/build_webpack/src/webpack-dev-server/index.ts index bea3c99be376..2305481c841a 100644 --- a/packages/angular_devkit/build_webpack/src/webpack-dev-server/index.ts +++ b/packages/angular_devkit/build_webpack/src/webpack-dev-server/index.ts @@ -7,7 +7,6 @@ */ import { BuilderContext, createBuilder } from '@angular-devkit/architect'; -import * as net from 'net'; import { resolve as pathResolve } from 'path'; import { Observable, from, isObservable, of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; @@ -53,38 +52,27 @@ export function runWebpackDevServer( config: WebpackDevServer.Configuration, ) => { if (options.webpackDevServerFactory) { - // webpack-dev-server types currently do not support Webpack 5 - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return new options.webpackDevServerFactory(webpack as any, config); + return new options.webpackDevServerFactory(config, webpack); } - // webpack-dev-server types currently do not support Webpack 5 - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return new WebpackDevServer(webpack as any, config); + return new WebpackDevServer(config, webpack); }; const log: WebpackLoggingCallback = options.logging || ((stats, config) => context.logger.info(stats.toString(config.stats))); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const devServerConfig = options.devServerConfig || (config as any).devServer || {}; - if (devServerConfig.stats) { - config.stats = devServerConfig.stats; - } - // Disable stats reporting by the devserver, we have our own logger. - devServerConfig.stats = false; - return createWebpack({ ...config, watch: false }).pipe( switchMap( (webpackCompiler) => new Observable((obs) => { - const server = createWebpackDevServer(webpackCompiler, devServerConfig); + const devServerConfig = options.devServerConfig || config.devServer || {}; + devServerConfig.host ??= 'localhost'; + let result: Partial; webpackCompiler.hooks.done.tap('build-webpack', (stats) => { // Log stats. log(stats, config); - obs.next({ ...result, emittedFiles: getEmittedFiles(stats.compilation), @@ -93,34 +81,27 @@ export function runWebpackDevServer( } as unknown as DevServerBuildOutput); }); - server.listen( - devServerConfig.port === undefined ? 8080 : devServerConfig.port, - devServerConfig.host === undefined ? 'localhost' : devServerConfig.host, - function (this: net.Server, err) { - if (err) { - obs.error(err); - } else { - const address = this.address(); - if (!address) { - obs.error(new Error(`Dev-server address info is not defined.`)); - - return; - } - - result = { - success: true, - port: typeof address === 'string' ? 0 : address.port, - family: typeof address === 'string' ? '' : address.family, - address: typeof address === 'string' ? address : address.address, - }; - } - }, - ); + const devServer = createWebpackDevServer(webpackCompiler, devServerConfig); + devServer.startCallback(() => { + const address = devServer.server.address(); + if (!address) { + obs.error(new Error(`Dev-server address info is not defined.`)); + + return; + } + + result = { + success: true, + port: typeof address === 'string' ? 0 : address.port, + family: typeof address === 'string' ? '' : address.family, + address: typeof address === 'string' ? address : address.address, + }; + }); // Teardown logic. Close the server when unsubscribed from. return () => { - server.close(); - webpackCompiler.close?.(() => {}); + devServer.stopCallback(() => {}); + webpackCompiler.close(() => {}); }; }), ),