diff --git a/.gitignore b/.gitignore index c6980aef9..67c4f43e7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ build/ .watchmanconfig coverage !packages/cli-platform-ios/src/config/__fixtures__/native_modules/node_modules +*.env diff --git a/packages/cli-platform-android/package.json b/packages/cli-platform-android/package.json index c101ac072..f6e725f40 100644 --- a/packages/cli-platform-android/package.json +++ b/packages/cli-platform-android/package.json @@ -21,6 +21,7 @@ ], "devDependencies": { "@react-native-community/cli-types": "^11.0.0-alpha.2", + "@react-native-community/cli-plugin-metro": "^11.0.0-alpha.2", "@types/execa": "^0.9.0", "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1" diff --git a/packages/cli-platform-android/src/commands/buildAndroid/index.ts b/packages/cli-platform-android/src/commands/buildAndroid/index.ts index 05622b6d7..b6fd08ec9 100644 --- a/packages/cli-platform-android/src/commands/buildAndroid/index.ts +++ b/packages/cli-platform-android/src/commands/buildAndroid/index.ts @@ -38,8 +38,14 @@ export async function runPackager(args: BuildFlags, config: Config) { } else { // result == 'not_running' logger.info('Starting JS server...'); + try { - startServerInNewWindow(args.port, args.terminal, config.reactNativePath); + startServerInNewWindow( + args.port, + args.terminal, + config.root, + config.reactNativePath, + ); } catch (error) { logger.warn( `Failed to automatically start the packager server. Please run "react-native start" manually. Error details: ${error.message}`, diff --git a/packages/cli-platform-android/src/commands/buildAndroid/startServerInNewWindow.ts b/packages/cli-platform-android/src/commands/buildAndroid/startServerInNewWindow.ts index d534d5053..f7ff72fb1 100644 --- a/packages/cli-platform-android/src/commands/buildAndroid/startServerInNewWindow.ts +++ b/packages/cli-platform-android/src/commands/buildAndroid/startServerInNewWindow.ts @@ -1,49 +1,75 @@ import path from 'path'; import fs from 'fs'; import execa from 'execa'; -import {logger} from '@react-native-community/cli-tools'; +import { + CLIError, + logger, + resolveNodeModuleDir, +} from '@react-native-community/cli-tools'; export function startServerInNewWindow( port: number, terminal: string, + projectRoot: string, reactNativePath: string, ) { /** * Set up OS-specific filenames and commands */ const isWindows = /^win/.test(process.platform); - const scriptFile = isWindows - ? 'launchPackager.bat' - : 'launchPackager.command'; + const scriptFile = isWindows ? 'launchPackager.bat' : 'launchPackager.sh'; const packagerEnvFilename = isWindows ? '.packager.bat' : '.packager.env'; - const portExportContent = isWindows - ? `set RCT_METRO_PORT=${port}` - : `export RCT_METRO_PORT=${port}`; + const packagerEnvFileExportContent = isWindows + ? `set RCT_METRO_PORT=${port}\nset PROJECT_ROOT=${projectRoot}\nset REACT_NATIVE_PATH=${reactNativePath}` + : `export RCT_METRO_PORT=${port}\nexport PROJECT_ROOT=${projectRoot}\nexport REACT_NATIVE_PATH=${reactNativePath}`; + const nodeModulesPath = resolveNodeModuleDir(projectRoot, '.bin'); + const cliPluginMetroPath = path.dirname( + require.resolve('@react-native-community/cli-plugin-metro/package.json'), + ); /** - * Set up the `.packager.(env|bat)` file to ensure the packager starts on the right port. + * Set up the `.packager.(env|bat)` file to ensure the packager starts on the right port and in right directory. */ - const launchPackagerScript = path.join( - reactNativePath, - `scripts/${scriptFile}`, - ); + const packagerEnvFile = path.join(nodeModulesPath, `${packagerEnvFilename}`); /** - * Set up the `launchpackager.(command|bat)` file. + * Set up the `launchPackager.(command|bat)` file. * It lives next to `.packager.(bat|env)` */ - const scriptsDir = path.dirname(launchPackagerScript); - const packagerEnvFile = path.join(scriptsDir, packagerEnvFilename); - const procConfig: execa.SyncOptions = {cwd: scriptsDir}; + const launchPackagerScript = path.join(nodeModulesPath, scriptFile); + const procConfig: execa.SyncOptions = {cwd: path.dirname(packagerEnvFile)}; /** * Ensure we overwrite file by passing the `w` flag */ - fs.writeFileSync(packagerEnvFile, portExportContent, { + fs.writeFileSync(packagerEnvFile, packagerEnvFileExportContent, { encoding: 'utf8', flag: 'w', }); + /** + * Copy files into `node_modules/.bin`. + */ + + try { + if (isWindows) { + fs.copyFileSync( + path.join(cliPluginMetroPath, 'launchPackager.bat'), + path.join(nodeModulesPath, 'launchPackager.bat'), + ); + } else { + fs.copyFileSync( + path.join(cliPluginMetroPath, 'launchPackager.sh'), + path.join(nodeModulesPath, 'launchPackager.sh'), + ); + } + } catch (error) { + return new CLIError( + `Couldn't copy the script for running bundler. Please check if the "${scriptFile}" file exists in the "node_modules/@react-native-community/cli-plugin-metro" folder and try again.`, + error as any, + ); + } + if (process.platform === 'darwin') { try { return execa.sync( @@ -66,7 +92,7 @@ export function startServerInNewWindow( return execa.sync('sh', [launchPackagerScript], procConfig); } } - if (/^win/.test(process.platform)) { + if (isWindows) { // Awaiting this causes the CLI to hang indefinitely, so this must execute without await. return execa('cmd.exe', ['/C', launchPackagerScript], { ...procConfig, diff --git a/packages/cli-plugin-metro/launchPackager.bat b/packages/cli-plugin-metro/launchPackager.bat new file mode 100644 index 000000000..a76f4f06f --- /dev/null +++ b/packages/cli-plugin-metro/launchPackager.bat @@ -0,0 +1,7 @@ +@echo off +title Metro +call .packager.bat +cd "%PROJECT_ROOT%" +node "%REACT_NATIVE_PATH%/cli.js" start +pause +exit diff --git a/packages/cli-plugin-metro/launchPackager.sh b/packages/cli-plugin-metro/launchPackager.sh new file mode 100755 index 000000000..0ca3e2088 --- /dev/null +++ b/packages/cli-plugin-metro/launchPackager.sh @@ -0,0 +1,9 @@ +THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd) +source "$THIS_DIR/.packager.env" +cd $PROJECT_ROOT +$REACT_NATIVE_PATH/cli.js start + +if [[ -z "$CI" ]]; then + echo "Process terminated. Press to close the window" + read -r +fi