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 {
- 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((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 {
}),
)
.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);
});