From d1b27e53ed9e23a0c08c13c22fc0b4c00f3998b2 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:27:00 -0500 Subject: [PATCH] fix(@angular-devkit/build-angular): ensure port 0 uses random port with Vite development server Vite appears to consider a port value of `0` as a falsy value and use the default Vite port of `5173` when zero is used as a value for the development server port option. To workaround this issue, the port checker code now explicitly handles the zero value case and determines a random port as would be done automatically by the Webpack-based development server. (cherry picked from commit 5b8e2d5e57d1c0b07f015eec1bd8fb889dfa8a78) --- .../dev-server/tests/options/port_spec.ts | 5 ++++ .../build_angular/src/utils/check-port.ts | 25 +++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/port_spec.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/port_spec.ts index 8091983763c4..b93f4870061d 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/port_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/options/port_spec.ts @@ -71,6 +71,11 @@ describeServeBuilder( expect(result?.success).toBeTrue(); const port = getResultPort(result); expect(port).not.toBe('4200'); + if (isViteRun) { + // Should not be default Vite port either + expect(port).not.toBe('5173'); + } + expect(port).toMatch(/\d{4,6}/); expect(await response?.text()).toContain(''); diff --git a/packages/angular_devkit/build_angular/src/utils/check-port.ts b/packages/angular_devkit/build_angular/src/utils/check-port.ts index 3e942266071b..29c738c1d52b 100644 --- a/packages/angular_devkit/build_angular/src/utils/check-port.ts +++ b/packages/angular_devkit/build_angular/src/utils/check-port.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import * as net from 'net'; +import assert from 'node:assert'; +import { AddressInfo, createServer } from 'node:net'; import { loadEsmModule } from './load-esm'; import { isTTY } from './tty'; @@ -15,12 +16,14 @@ function createInUseError(port: number): Error { } export async function checkPort(port: number, host: string): Promise<number> { - if (port === 0) { - return 0; - } + // Disabled due to Vite not handling port 0 and instead always using the default value (5173) + // TODO: Enable this again once Vite is fixed + // if (port === 0) { + // return 0; + // } return new Promise<number>((resolve, reject) => { - const server = net.createServer(); + const server = createServer(); server .once('error', (err: NodeJS.ErrnoException) => { @@ -46,13 +49,21 @@ export async function checkPort(port: number, host: string): Promise<number> { }), ) .then( - (answers) => (answers.useDifferent ? resolve(0) : reject(createInUseError(port))), + (answers) => + answers.useDifferent ? resolve(checkPort(0, host)) : reject(createInUseError(port)), () => reject(createInUseError(port)), ); }) .once('listening', () => { + // Get the actual address from the listening server instance + const address = server.address(); + assert( + address && typeof address !== 'string', + 'Port check server address should always be an object.', + ); + server.close(); - resolve(port); + resolve(address.port); }) .listen(port, host); });