Skip to content

Commit

Permalink
feat: add invoking CLI's scripts for launching Metro in run-ios com…
Browse files Browse the repository at this point in the history
…mand (#2021)

* feat: sync starting bundler implementations

* fix: remove starting packager from build-* commands

* feat: add better request response handling

* fix: add missing options

* chore: remove usage of `cli-plugin-metro` package by exposing command

* fix: remove useless dependencies

* feat: merge starting bundler hooks to `start` command & add interactivity

* fix: adjust descriptions

* chore: code review improvements

* fix: move logic to `run-ios/android` commands

* fix: move scripts to correct directory

* chore: simplify naming

* chore: code cleaning

* chore: lockfile

* fix: remove unnecessary dependency

* chore: unify `handlePortUnavailable`
  • Loading branch information
szymonrybczak authored Aug 11, 2023
1 parent f8db7b2 commit e7c2aeb
Show file tree
Hide file tree
Showing 25 changed files with 593 additions and 294 deletions.
4 changes: 2 additions & 2 deletions packages/cli-clean/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@react-native-community/cli-tools": "12.0.0-alpha.8",
"chalk": "^4.1.2",
"execa": "^5.0.0",
"prompts": "^2.4.0"
"prompts": "^2.4.2"
},
"files": [
"build",
Expand All @@ -20,7 +20,7 @@
],
"devDependencies": {
"@react-native-community/cli-types": "12.0.0-alpha.8",
"@types/prompts": "^2.0.9"
"@types/prompts": "^2.4.4"
},
"homepage": "https://github.com/react-native-community/cli/tree/main/packages/cli-clean",
"repository": {
Expand Down
5 changes: 2 additions & 3 deletions packages/cli-doctor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"@react-native-community/cli-config": "12.0.0-alpha.8",
"@react-native-community/cli-platform-android": "12.0.0-alpha.8",
"@react-native-community/cli-platform-ios": "12.0.0-alpha.8",
"@react-native-community/cli-plugin-metro": "12.0.0-alpha.8",
"@react-native-community/cli-tools": "12.0.0-alpha.8",
"chalk": "^4.1.2",
"command-exists": "^1.2.8",
Expand All @@ -21,7 +20,7 @@
"ip": "^1.1.5",
"node-stream-zip": "^1.9.1",
"ora": "^5.4.1",
"prompts": "^2.4.0",
"prompts": "^2.4.2",
"semver": "^7.5.2",
"strip-ansi": "^5.2.0",
"sudo-prompt": "^9.0.0",
Expand All @@ -38,7 +37,7 @@
"@types/command-exists": "^1.2.0",
"@types/envinfo": "^7.8.1",
"@types/ip": "^1.1.0",
"@types/prompts": "^2.0.9",
"@types/prompts": "^2.4.4",
"@types/semver": "^6.0.2",
"@types/wcwidth": "^1.0.0"
},
Expand Down
15 changes: 9 additions & 6 deletions packages/cli-doctor/src/tools/healthchecks/packager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
} from '@react-native-community/cli-tools';
import {HealthCheckInterface} from '../../types';
import {logManualInstallation} from './common';
import {startServerInNewWindow} from '@react-native-community/cli-plugin-metro';
import execa from 'execa';
import path from 'path';

export default {
label: 'Metro',
Expand All @@ -29,12 +30,14 @@ export default {
const terminal = getDefaultUserTerminal();
const port = Number(process.env.RCT_METRO_PORT) || 8081;
if (terminal && config) {
startServerInNewWindow(
port,
await execa('node', [
path.join(config.reactNativePath, 'cli.js'),
'start',
'--port',
port.toString(),
'--terminal',
terminal,
config.root,
config.reactNativePath,
);
]);
return loader.succeed();
}
return logManualInstallation({
Expand Down
1 change: 0 additions & 1 deletion packages/cli-platform-android/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"native_modules.gradle"
],
"devDependencies": {
"@react-native-community/cli-plugin-metro": "12.0.0-alpha.8",
"@react-native-community/cli-types": "12.0.0-alpha.8",
"@types/fs-extra": "^8.1.0",
"@types/glob": "^7.1.1"
Expand Down
53 changes: 1 addition & 52 deletions packages/cli-platform-android/src/commands/buildAndroid/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import {
CLIError,
getDefaultUserTerminal,
isPackagerRunning,
logger,
printRunDoctorTip,
} from '@react-native-community/cli-tools';
Expand All @@ -10,51 +8,17 @@ import execa from 'execa';
import {getAndroidProject} from '../../config/getAndroidProject';
import adb from '../runAndroid/adb';
import getAdbPath from '../runAndroid/getAdbPath';
import {startServerInNewWindow} from '@react-native-community/cli-plugin-metro';
import {getTaskNames} from '../runAndroid/getTaskNames';
import {promptForTaskSelection} from '../runAndroid/listAndroidTasks';

export interface BuildFlags {
mode?: string;
activeArchOnly?: boolean;
packager?: boolean;
port: number;
terminal: string;
tasks?: Array<string>;
extraParams?: Array<string>;
interactive?: boolean;
}

export async function runPackager(args: BuildFlags, config: Config) {
if (!args.packager) {
return;
}
const result = await isPackagerRunning(args.port);
if (result === 'running') {
logger.info('JS server already running.');
} else if (result === 'unrecognized') {
logger.warn('JS server not recognized, continuing with build...');
} else {
// result == 'not_running'
logger.info('Starting JS server...');

try {
startServerInNewWindow(
args.port,
args.terminal,
config.root,
config.reactNativePath,
);
} catch (error) {
if (error instanceof Error) {
logger.warn(
`Failed to automatically start the packager server. Please run "react-native start" manually. Error details: ${error.message}`,
);
}
}
}
}

async function buildAndroid(
_argv: Array<string>,
config: Config,
Expand Down Expand Up @@ -112,7 +76,7 @@ async function buildAndroid(
gradleArgs.push('-PreactNativeArchitectures=' + architectures.join(','));
}
}
await runPackager(args, config);

return build(gradleArgs, androidProject.sourceDir);
}

Expand All @@ -137,21 +101,6 @@ export const options = [
name: '--mode <string>',
description: "Specify your app's build variant",
},
{
name: '--no-packager',
description: 'Do not launch packager while building',
},
{
name: '--port <number>',
default: process.env.RCT_METRO_PORT || 8081,
parse: Number,
},
{
name: '--terminal <string>',
description:
'Launches the Metro Bundler in a new window using the specified terminal path.',
default: getDefaultUserTerminal(),
},
{
name: '--tasks <list>',
description:
Expand Down
61 changes: 58 additions & 3 deletions packages/cli-platform-android/src/commands/runAndroid/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@ import tryRunAdbReverse from './tryRunAdbReverse';
import tryLaunchAppOnDevice from './tryLaunchAppOnDevice';
import tryInstallAppOnDevice from './tryInstallAppOnDevice';
import getAdbPath from './getAdbPath';
import {logger, CLIError, link} from '@react-native-community/cli-tools';
import {
logger,
CLIError,
link,
getDefaultUserTerminal,
isPackagerRunning,
logAlreadyRunningBundler,
startServerInNewWindow,
handlePortUnavailable,
} from '@react-native-community/cli-tools';
import {getAndroidProject} from '../../config/getAndroidProject';
import listAndroidDevices from './listAndroidDevices';
import tryLaunchEmulator from './tryLaunchEmulator';
import chalk from 'chalk';
import path from 'path';
import {build, runPackager, BuildFlags, options} from '../buildAndroid';
import {build, BuildFlags, options} from '../buildAndroid';
import {promptForTaskSelection} from './listAndroidTasks';
import {getTaskNames} from './getTaskNames';
import {checkUsers, promptForUser} from './listAndroidUsers';
Expand All @@ -28,6 +37,9 @@ export interface Flags extends BuildFlags {
appId: string;
appIdSuffix: string;
mainActivity: string;
port: number;
terminal?: string;
packager?: boolean;
deviceId?: string;
listDevices?: boolean;
binaryPath?: string;
Expand All @@ -42,6 +54,35 @@ export type AndroidProject = NonNullable<Config['project']['android']>;
async function runAndroid(_argv: Array<string>, config: Config, args: Flags) {
link.setPlatform('android');

let {packager, port} = args;

const packagerStatus = await isPackagerRunning(port);

if (
typeof packagerStatus === 'object' &&
packagerStatus.status === 'running'
) {
if (packagerStatus.root === config.root) {
packager = false;
logAlreadyRunningBundler(port);
} else {
const result = await handlePortUnavailable(port, config.root, packager);
[port, packager] = [result.port, result.packager];
}
} else if (packagerStatus === 'unrecognized') {
const result = await handlePortUnavailable(port, config.root, packager);
[port, packager] = [result.port, result.packager];
}

if (packager) {
await startServerInNewWindow(
port,
config.root,
config.reactNativePath,
args.terminal,
);
}

if (config.reactNativeVersion !== 'unknown') {
link.setVersion(config.reactNativeVersion);
}
Expand All @@ -66,7 +107,6 @@ async function runAndroid(_argv: Array<string>, config: Config, args: Flags) {

const androidProject = getAndroidProject(config);

await runPackager(args, config);
return buildAndRun(args, androidProject);
}

Expand Down Expand Up @@ -269,6 +309,21 @@ export default {
func: runAndroid,
options: [
...options,
{
name: '--no-packager',
description: 'Do not launch packager while running the app',
},
{
name: '--port <number>',
default: process.env.RCT_METRO_PORT || 8081,
parse: Number,
},
{
name: '--terminal <string>',
description:
'Launches the Metro Bundler in a new window using the specified terminal path.',
default: getDefaultUserTerminal(),
},
{
name: '--appId <string>',
description:
Expand Down
38 changes: 19 additions & 19 deletions packages/cli-platform-ios/src/commands/buildIOS/buildProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@ import {
export type BuildFlags = {
mode: string;
target: string;
packager: boolean;
verbose: boolean;
xcconfig?: string;
buildFolder?: string;
port: number;
terminal: string | undefined;
interactive?: boolean;
destination?: string;
extraParams?: string[];
Expand Down Expand Up @@ -72,6 +69,7 @@ export function buildProject(
});
}
}

const buildProcess = child_process.spawn(
'xcodebuild',
xcodebuildArgs,
Expand Down Expand Up @@ -150,30 +148,32 @@ function xcprettyAvailable() {
return true;
}

function getProcessOptions({
packager,
terminal,
port,
}: {
packager: boolean;
terminal: string | undefined;
port: number;
}): SpawnOptionsWithoutStdio {
if (packager) {
function getProcessOptions<T extends BuildFlags>(
args: T,
): SpawnOptionsWithoutStdio {
if (
'packager' in args &&
typeof args.packager === 'boolean' &&
args.packager
) {
const terminal =
'terminal' in args && typeof args.terminal === 'string'
? args.terminal
: '';

const port =
'port' in args && typeof args.port === 'string' ? args.port : '';

return {
env: {
...process.env,
RCT_TERMINAL: terminal,
RCT_METRO_PORT: port.toString(),
RCT_METRO_PORT: port,
},
};
}

return {
env: {
...process.env,
RCT_TERMINAL: terminal,
RCT_NO_LAUNCH_PACKAGER: 'true',
},
env: process.env,
};
}
Loading

0 comments on commit e7c2aeb

Please sign in to comment.