Skip to content

Commit 33d710e

Browse files
Michael S. Kazmierfacebook-github-bot
Michael S. Kazmier
authored andcommitted
adds --port option to react-native run-ios as well as patches port …
Summary: The pull request adds the `--port` option to `run-ios` allowing a developer to build and launch a react-native app using a single command line like this: ``` react-native run-ios --port 8088 ``` It defaults to the current port 8081. This pull request fixes issue #9145 and issue #14113. This patch also extends `run-android` to properly test and launch the packager with the specified port, extending the work done in PR: ##15316 1. Create a new react-native app, or simply clone this branch and then update your version of react-native using `yarn add file:./path/to/this/fork/of/react-native` 2. run `react-native run-ios --port 8088` 3. watch the packager start on the desired port (8088 in this case) and watch your app in your simulator connect to the packager and launch the app. Closes #16172 Differential Revision: D6612534 Pulled By: shergin fbshipit-source-id: 50af449f5e4c32fb76ba95f4cb7bf179e35526d5
1 parent e57a43b commit 33d710e

File tree

10 files changed

+66
-20
lines changed

10 files changed

+66
-20
lines changed

Libraries/WebSocket/RCTWebSocket.xcodeproj/project.pbxproj

+6
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,11 @@
433433
isa = XCBuildConfiguration;
434434
buildSettings = {
435435
EXECUTABLE_PREFIX = lib;
436+
GCC_PREPROCESSOR_DEFINITIONS = (
437+
"DEBUG=1",
438+
"RCT_METRO_PORT=${RCT_METRO_PORT}",
439+
"$(inherited)",
440+
);
436441
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
437442
OTHER_LDFLAGS = "-ObjC";
438443
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -443,6 +448,7 @@
443448
isa = XCBuildConfiguration;
444449
buildSettings = {
445450
EXECUTABLE_PREFIX = lib;
451+
GCC_PREPROCESSOR_DEFINITIONS = "RCT_METRO_PORT=${RCT_METRO_PORT}";
446452
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
447453
OTHER_LDFLAGS = "-ObjC";
448454
PRODUCT_NAME = "$(TARGET_NAME)";

Libraries/WebSocket/RCTWebSocketExecutor.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ - (instancetype)initWithURL:(NSURL *)URL
5454
- (void)setUp
5555
{
5656
if (!_url) {
57-
NSInteger port = [[[_bridge bundleURL] port] integerValue] ?: 8081;
57+
NSInteger port = [[[_bridge bundleURL] port] integerValue] ?: RCT_METRO_PORT;
5858
NSString *host = [[_bridge bundleURL] host] ?: @"localhost";
5959
NSString *URLString = [NSString stringWithFormat:@"http://%@:%lld/debugger-proxy?role=client", host, (long long)port];
6060
_url = [RCTConvert NSURL:URLString];

React/Base/RCTBundleURLProvider.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
NSString *const RCTBundleURLProviderUpdatedNotification = @"RCTBundleURLProviderUpdatedNotification";
1616

17-
const NSUInteger kRCTBundleURLProviderDefaultPort = 8081;
17+
const NSUInteger kRCTBundleURLProviderDefaultPort = RCT_METRO_PORT;
1818

1919
static NSString *const kRCTJsLocationKey = @"RCT_jsLocation";
2020
static NSString *const kRCTEnableLiveReloadKey = @"RCT_enableLiveReload";

React/Base/RCTDefines.h

+17
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@
7474
#define RCT_PROFILE RCT_DEV
7575
#endif
7676

77+
/**
78+
* Add the default Metro packager port number
79+
*/
80+
#ifndef RCT_METRO_PORT
81+
#define RCT_METRO_PORT 8081
82+
#else
83+
// test if RCT_METRO_PORT is empty
84+
#define RCT_METRO_PORT_DO_EXPAND(VAL) VAL ## 1
85+
#define RCT_METRO_PORT_EXPAND(VAL) RCT_METRO_PORT_DO_EXPAND(VAL)
86+
#if !defined(RCT_METRO_PORT) || (RCT_METRO_PORT_EXPAND(RCT_METRO_PORT) == 1)
87+
// Only here if RCT_METRO_PORT is not defined
88+
// OR RCT_METRO_PORT is the empty string
89+
#undef RCT_METRO_PORT
90+
#define RCT_METRO_PORT 8081
91+
#endif
92+
#endif
93+
7794
/**
7895
* By default, only raise an NSAssertion in debug mode
7996
* (custom assert functions will still be called).

React/React.xcodeproj/project.pbxproj

+12-2
Original file line numberDiff line numberDiff line change
@@ -3957,7 +3957,7 @@
39573957
);
39583958
runOnlyForDeploymentPostprocessing = 0;
39593959
shellPath = /bin/sh;
3960-
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost 8081 ; then\n if ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi";
3960+
shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi";
39613961
showEnvVarsInLog = 0;
39623962
};
39633963
142C4F7F1B582EA6001F0B58 /* Include RCTJSCProfiler */ = {
@@ -5100,6 +5100,13 @@
51005100
buildSettings = {
51015101
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
51025102
CLANG_STATIC_ANALYZER_MODE = deep;
5103+
GCC_PREPROCESSOR_DEFINITIONS = (
5104+
"DEBUG=1",
5105+
"RCT_DEBUG=1",
5106+
"RCT_DEV=1",
5107+
"RCT_NSASSERT=1",
5108+
"RCT_METRO_PORT=${RCT_METRO_PORT}",
5109+
);
51035110
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
51045111
OTHER_LDFLAGS = "-ObjC";
51055112
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -5114,7 +5121,10 @@
51145121
buildSettings = {
51155122
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
51165123
CLANG_STATIC_ANALYZER_MODE = deep;
5117-
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
5124+
GCC_PREPROCESSOR_DEFINITIONS = (
5125+
"$(inherited)",
5126+
"RCT_METRO_PORT=${RCT_METRO_PORT}",
5127+
);
51185128
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
51195129
OTHER_LDFLAGS = "-ObjC";
51205130
PRODUCT_NAME = "$(TARGET_NAME)";

local-cli/runAndroid/runAndroid.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ function runAndroid(argv, config, args) {
4545
return buildAndRun(args);
4646
}
4747

48-
return isPackagerRunning().then(result => {
48+
return isPackagerRunning(args.port).then(result => {
4949
if (result === 'running') {
5050
console.log(chalk.bold('JS server already running.'));
5151
} else if (result === 'unrecognized') {
5252
console.warn(chalk.yellow('JS server not recognized, continuing with build...'));
5353
} else {
5454
// result == 'not_running'
5555
console.log(chalk.bold('Starting JS server...'));
56-
startServerInNewWindow();
56+
startServerInNewWindow(args.port);
5757
}
5858
return buildAndRun(args);
5959
});
@@ -262,7 +262,7 @@ function runOnAllDevices(args, cmd, packageNameWithSuffix, packageName, adbPath)
262262
}
263263
}
264264

265-
function startServerInNewWindow() {
265+
function startServerInNewWindow(port) {
266266
const scriptFile = /^win/.test(process.platform) ?
267267
'launchPackager.bat' :
268268
'launchPackager.command';
@@ -271,6 +271,12 @@ function startServerInNewWindow() {
271271
const procConfig = {cwd: scriptsDir};
272272
const terminal = process.env.REACT_TERMINAL;
273273

274+
// setup the .packager.env file to ensure the packager starts on the right port
275+
const packagerEnvFile = path.join(__dirname, '..', '..', 'scripts', '.packager.env');
276+
const content = `export RCT_METRO_PORT=${port}`;
277+
// ensure we overwrite file by passing the 'w' flag
278+
fs.writeFileSync(packagerEnvFile, content, {encoding: 'utf8', flag: 'w'});
279+
274280
if (process.platform === 'darwin') {
275281
if (terminal) {
276282
return child_process.spawnSync('open', ['-a', terminal, launchPackagerScript], procConfig);
@@ -333,7 +339,7 @@ module.exports = {
333339
description: 'Do not launch packager while building',
334340
}, {
335341
command: '--port [number]',
336-
default: 8081,
342+
default: process.env.RCT_METRO_PORT || 8081,
337343
parse: (val: string) => Number(val),
338344
}],
339345
};

local-cli/runIOS/runIOS.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ function runIOS(argv, config, args) {
7878
function runOnDeviceByUdid(args, scheme, xcodeProject, devices) {
7979
const selectedDevice = matchingDeviceByUdid(devices, args.udid);
8080
if (selectedDevice) {
81-
return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose);
81+
return runOnDevice(selectedDevice, scheme, xcodeProject, args.configuration, args.packager, args.verbose, args.port);
8282
} else {
8383
if (devices && devices.length > 0) {
8484
console.log('Could not find device with the udid: "' + args.udid + '".');
@@ -115,7 +115,7 @@ function runOnSimulator(xcodeProject, args, scheme) {
115115
}
116116
resolve(selectedSimulator.udid);
117117
})
118-
.then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration, args.packager, args.verbose))
118+
.then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration, args.packager, args.verbose, args.port))
119119
.then((appName) => {
120120
if (!appName) {
121121
appName = scheme;
@@ -135,8 +135,8 @@ function runOnSimulator(xcodeProject, args, scheme) {
135135
});
136136
}
137137

138-
function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launchPackager, verbose) {
139-
return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration, launchPackager, verbose)
138+
function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launchPackager, verbose, port) {
139+
return buildProject(xcodeProject, selectedDevice.udid, scheme, configuration, launchPackager, verbose, port)
140140
.then((appName) => {
141141
if (!appName) {
142142
appName = scheme;
@@ -159,7 +159,7 @@ function runOnDevice(selectedDevice, scheme, xcodeProject, configuration, launch
159159
});
160160
}
161161

162-
function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launchPackager = false, verbose) {
162+
function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launchPackager = false, verbose, port) {
163163
return new Promise((resolve,reject) =>
164164
{
165165
var xcodebuildArgs = [
@@ -174,7 +174,7 @@ function buildProject(xcodeProject, udid, scheme, configuration = 'Debug', launc
174174
if (!verbose) {
175175
xcpretty = xcprettyAvailable() && child_process.spawn('xcpretty', [], { stdio: ['pipe', process.stdout, process.stderr] });
176176
}
177-
const buildProcess = child_process.spawn('xcodebuild', xcodebuildArgs, getProcessOptions(launchPackager));
177+
const buildProcess = child_process.spawn('xcodebuild', xcodebuildArgs, getProcessOptions(launchPackager, port));
178178
let buildOutput = '';
179179
buildProcess.stdout.on('data', function(data) {
180180
buildOutput += data.toString();
@@ -232,13 +232,15 @@ function printFoundDevices(devices) {
232232
}
233233
}
234234

235-
function getProcessOptions(launchPackager) {
235+
function getProcessOptions(launchPackager, port) {
236236
if (launchPackager) {
237-
return {};
237+
return {
238+
env: { ...process.env, RCT_METRO_PORT: port }
239+
};
238240
}
239241

240242
return {
241-
env: Object.assign({}, process.env, { RCT_NO_LAUNCH_PACKAGER: true }),
243+
env: { ...process.env, RCT_NO_LAUNCH_PACKAGER: true },
242244
};
243245
}
244246

@@ -287,5 +289,9 @@ module.exports = {
287289
}, {
288290
command: '--verbose',
289291
description: 'Do not use xcpretty even if installed',
292+
},{
293+
command: '--port [number]',
294+
default: process.env.RCT_METRO_PORT || 8081,
295+
parse: (val: string) => Number(val),
290296
}],
291297
};

local-cli/server/server.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ module.exports = {
6060
description: 'starts the webserver',
6161
options: [{
6262
command: '--port [number]',
63-
default: 8081,
63+
default: process.env.RCT_METRO_PORT || 8081,
6464
parse: (val: string) => Number(val),
6565
}, {
6666
command: '--host [string]',

local-cli/util/isPackagerRunning.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ const fetch = require('node-fetch');
1919
* - `unrecognized`: one other process is running on the port we expect the
2020
* packager to be running.
2121
*/
22-
function isPackagerRunning() {
23-
return fetch('http://localhost:8081/status').then(
22+
function isPackagerRunning(packagerPort = (process.env.RCT_METRO_PORT || 8081)) {
23+
return fetch(`http://localhost:${packagerPort}/status`).then(
2424
res => res.text().then(body =>
2525
body === 'packager-status:running' ? 'running' : 'unrecognized'
2626
),

scripts/packager.sh

+1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
# of patent rights can be found in the PATENTS file in the same directory.
99

1010
THIS_DIR=$(dirname "$0")
11+
source "${THIS_DIR}/.packager.env"
1112
cd "$THIS_DIR/.."
1213
node "./local-cli/cli.js" start "$@"

0 commit comments

Comments
 (0)