Skip to content

Commit cec070e

Browse files
authored
fix: allow run-windows to start Metro on custom port (#16126)
1 parent 0644ae8 commit cec070e

4 files changed

Lines changed: 46 additions & 9 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Add a run-windows port option for Metro",
4+
"packageName": "@react-native-windows/cli",
5+
"email": "vivekjm77@gmail.com",
6+
"dependentChangeType": "patch"
7+
}

packages/@react-native-windows/cli/src/commands/runWindows/runWindowsOptions.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type BuildConfig = 'Debug' | 'DebugBundle' | 'Release' | 'ReleaseBundle';
2828
* deploy-from-layout: Force deploy from layout, even in release builds
2929
* sln: String - Solution file to build
3030
* msbuildprops: String - Comma separated props to pass to msbuild, eg: prop1=value1,prop2=value2
31+
* port: Number - Port to use for the React Native packager
3132
* direct-debugging: Number - Enable direct debugging on specified port
3233
* no-telemetry: Boolean - Disables sending telemetry that allows analysis of usage and failures of the react-native-windows CLI
3334
*/
@@ -52,6 +53,7 @@ export interface RunWindowsOptions {
5253
msbuildprops?: string;
5354
buildLogDirectory?: string;
5455
info?: boolean;
56+
port?: number;
5557
directDebugging?: number;
5658
telemetry?: boolean;
5759
}
@@ -147,6 +149,12 @@ export const runWindowsOptions: CommandOption[] = [
147149
name: '--info',
148150
description: 'Dump environment information',
149151
},
152+
{
153+
name: '--port [number]',
154+
description: 'Port to use for the React Native packager',
155+
default: 8081,
156+
parse: parsePort,
157+
},
150158
{
151159
name: '--direct-debugging [number]',
152160
description: 'Enable direct debugging on specified port',
@@ -171,13 +179,17 @@ function parseBuildArch(arg: string): BuildArch {
171179
}
172180

173181
function parseDirectDebuggingPort(arg: string): number {
174-
const num = parseInt(arg, 10);
182+
return parsePort(arg, '--direct-debugging');
183+
}
184+
185+
function parsePort(arg: string, optionName = '--port'): number {
186+
const num = Number(arg);
175187

176188
if (!Number.isInteger(num)) {
177-
errorOut(`Expected argument '--direct-debugging' to be a number`);
189+
errorOut(`Expected argument '${optionName}' to be a number`);
178190
}
179191
if (num < 1024 || num >= 65535) {
180-
errorOut('Direct debugging port it out of range');
192+
errorOut(`${optionName} is out of range`);
181193
}
182194

183195
return num;

packages/@react-native-windows/cli/src/e2etest/runWindows.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ function validateOptionName(
3838
case 'msbuildprops':
3939
case 'buildLogDirectory':
4040
case 'info':
41+
case 'port':
4142
case 'directDebugging':
4243
case 'telemetry':
4344
return true;
@@ -77,3 +78,12 @@ test('runWindowsOptions - validate options', () => {
7778
).toBe(true);
7879
}
7980
});
81+
82+
test('runWindowsOptions - parses packager port', () => {
83+
const portOption = runWindowsOptions.find(option =>
84+
option.name.startsWith('--port'),
85+
);
86+
87+
expect(portOption).toBeDefined();
88+
expect(portOption!.parse!('9000')).toBe(9000);
89+
});

packages/@react-native-windows/cli/src/utils/deploy.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ export function getBuildConfiguration(options: RunWindowsOptions): BuildConfig {
4545
? 'ReleaseBundle'
4646
: 'Release'
4747
: options.bundle
48-
? 'DebugBundle'
49-
: 'Debug';
48+
? 'DebugBundle'
49+
: 'Debug';
5050
}
5151

5252
function shouldDeployByPackage(
@@ -314,8 +314,8 @@ export async function deployToDevice(
314314
const deployTarget = options.target
315315
? options.target
316316
: options.emulator
317-
? 'emulator'
318-
: 'device';
317+
? 'emulator'
318+
: 'device';
319319
const deployTool = new WinAppDeployTool();
320320
const appxManifest = getAppxManifest(options, projectName);
321321
const shouldLaunch = shouldLaunchApp(options);
@@ -512,9 +512,11 @@ export function startServerInNewWindow(
512512
options: RunWindowsOptions,
513513
verbose: boolean,
514514
): Promise<void> {
515+
const port = options.port ?? 8081;
516+
515517
return new Promise(resolve => {
516518
http
517-
.get('http://localhost:8081/status', res => {
519+
.get(`http://localhost:${port}/status`, res => {
518520
if (res.statusCode === 200) {
519521
newSuccess('React-Native Server already started');
520522
} else {
@@ -537,5 +539,11 @@ function launchServer(options: RunWindowsOptions, verbose: boolean) {
537539
stdio: verbose ? 'inherit' : 'ignore',
538540
};
539541

540-
spawn('cmd.exe', ['/C', 'start npx @react-native-community/cli start'], opts);
542+
const port = options.port ?? 8081;
543+
544+
spawn(
545+
'cmd.exe',
546+
['/C', `start npx @react-native-community/cli start --port ${port}`],
547+
opts,
548+
);
541549
}

0 commit comments

Comments
 (0)