Skip to content

Commit 445af4c

Browse files
committed
fix(serve): find closest ports for ionic-angular
addresses #3022
1 parent c313450 commit 445af4c

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

packages/@ionic/cli-utils/src/lib/project/ionic-angular/serve.ts

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ export const DEFAULT_PROGRAM = 'ionic-app-scripts';
2020
export const DEFAULT_SERVE_SCRIPT_VALUE = `${DEFAULT_PROGRAM} serve`;
2121
const APP_SCRIPTS_SERVE_CONNECTIVITY_TIMEOUT = 20000; // ms
2222

23+
interface Ports {
24+
port: number;
25+
livereloadPort: number;
26+
notificationPort: number;
27+
}
28+
2329
interface ServeCmdDetails {
2430
program: string;
2531
}
@@ -75,15 +81,17 @@ export class ServeRunner extends BaseServeRunner<IonicAngularServeOptions> {
7581
}
7682

7783
async serveProject(options: IonicAngularServeOptions): Promise<ServeDetails> {
78-
const { findClosestOpenPort, isHostConnectable } = await import('../../utils/network');
84+
const { isHostConnectable } = await import('../../utils/network');
7985
const [ externalIP, availableInterfaces ] = await this.selectExternalIP(options);
86+
const { port, livereloadPort, notificationPort } = await this.findOpenPorts(options.address, options);
8087

81-
const port = await findClosestOpenPort(options.port, '0.0.0.0');
8288
options.port = port;
89+
options.livereloadPort = livereloadPort;
90+
options.notificationPort = notificationPort;
8391

8492
const { program } = await this.serveCommandWrapper(options);
8593

86-
debug('waiting for connectivity with app-scripts (%dms timeout)', APP_SCRIPTS_SERVE_CONNECTIVITY_TIMEOUT);
94+
debug(`waiting for connectivity with ${program} (${APP_SCRIPTS_SERVE_CONNECTIVITY_TIMEOUT}ms timeout)`);
8795
await isHostConnectable('localhost', port, APP_SCRIPTS_SERVE_CONNECTIVITY_TIMEOUT);
8896

8997
return {
@@ -202,4 +210,39 @@ export class ServeRunner extends BaseServeRunner<IonicAngularServeOptions> {
202210

203211
return [...unparseArgs(args, { useEquals: false }), ...options['--']];
204212
}
213+
214+
private async findOpenPorts(address: string, ports: Ports): Promise<Ports> {
215+
const { ERROR_NETWORK_ADDRESS_NOT_AVAIL, findClosestOpenPort } = await import('../../utils/network');
216+
217+
try {
218+
const [ port, livereloadPort, notificationPort ] = await Promise.all([
219+
findClosestOpenPort(ports.port, '0.0.0.0'),
220+
findClosestOpenPort(ports.livereloadPort, '0.0.0.0'),
221+
findClosestOpenPort(ports.notificationPort, '0.0.0.0'),
222+
]);
223+
224+
if (ports.port !== port) {
225+
debug(`Port ${chalk.bold(String(ports.port))} taken, using ${chalk.bold(String(port))}.`);
226+
ports.port = port;
227+
}
228+
229+
if (ports.livereloadPort !== livereloadPort) {
230+
debug(`Port ${chalk.bold(String(ports.livereloadPort))} taken, using ${chalk.bold(String(livereloadPort))}.`);
231+
ports.livereloadPort = livereloadPort;
232+
}
233+
234+
if (ports.notificationPort !== notificationPort) {
235+
debug(`Port ${chalk.bold(String(ports.notificationPort))} taken, using ${chalk.bold(String(notificationPort))}.`);
236+
ports.notificationPort = notificationPort;
237+
}
238+
239+
return { port, livereloadPort, notificationPort };
240+
} catch (e) {
241+
if (e !== ERROR_NETWORK_ADDRESS_NOT_AVAIL) {
242+
throw e;
243+
}
244+
245+
throw new FatalException(`${chalk.green(address)} is not available--cannot bind.`);
246+
}
247+
}
205248
}

packages/@ionic/cli-utils/src/lib/project/ionic1/serve.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,27 +114,16 @@ export class ServeRunner extends BaseServeRunner<Ionic1ServeOptions> {
114114

115115
async serveProject(options: Ionic1ServeOptions): Promise<ServeDetails> {
116116
const { isHostConnectable } = await import('../../utils/network');
117-
118117
const [ externalIP, availableInterfaces ] = await this.selectExternalIP(options);
119118
const { port, livereloadPort, notificationPort } = await this.findOpenPorts(options.address, options);
120119

121120
options.port = port;
122121
options.livereloadPort = livereloadPort;
123122
options.notificationPort = notificationPort;
124123

125-
const details = [
126-
`address: ${chalk.bold(options.address)}`,
127-
`port: ${chalk.bold(String(port))}`,
128-
`dev server port: ${chalk.bold(String(notificationPort))}`,
129-
];
130-
131-
if (options.livereload) {
132-
details.push(`livereload port: ${chalk.bold(String(livereloadPort))}`);
133-
}
134-
135124
const { program } = await this.serveCommandWrapper(options);
136125

137-
debug('waiting for connectivity with ionic-v1 (%dms timeout)', IONIC_V1_SERVE_CONNECTIVITY_TIMEOUT);
126+
debug(`waiting for connectivity with ${program} (${IONIC_V1_SERVE_CONNECTIVITY_TIMEOUT}ms timeout)`);
138127
await isHostConnectable('localhost', port, IONIC_V1_SERVE_CONNECTIVITY_TIMEOUT);
139128

140129
return {

0 commit comments

Comments
 (0)