diff --git a/packages/react-native/cli.js b/packages/react-native/cli.js index 609c8498e5c609..301a51241fbeae 100755 --- a/packages/react-native/cli.js +++ b/packages/react-native/cli.js @@ -10,10 +10,68 @@ 'use strict'; -var cli = require('@react-native-community/cli'); +const {get} = require('https'); +const {URL} = require('url'); +const chalk = require('chalk'); +const cli = require('@react-native-community/cli'); + +const {version: currentVersion} = require('./package.json'); + +const isNpxRuntime = process.env.npm_lifecycle_event === 'npx'; +const DEFAULT_REGISTRY_HOST = + process.env.npm_config_registry ?? 'https://registry.npmjs.org/'; +const HEAD = '1000.0.0'; + +async function getLatestVersion(registryHost = DEFAULT_REGISTRY_HOST) { + return new Promise((res, rej) => { + const url = new URL(registryHost); + url.pathname = 'react-native/latest'; + get(url.toString(), resp => { + const buffer = []; + resp.on('data', data => buffer.push(data)); + resp.on('end', () => { + try { + res(JSON.parse(Buffer.concat(buffer).toString('utf8')).version); + } catch (e) { + rej(e); + } + }); + }).on('error', e => rej(e)); + }); +} + +/** + * npx react-native -> @react-native-comminity/cli + * + * Will perform a version check and warning if you're not running the latest community cli when executed using npx. If + * you know what you're doing, you can skip this check: + * + * SKIP=true npx react-native ... + * + */ +async function main() { + if (isNpxRuntime && !process.env.SKIP && currentVersion !== HEAD) { + try { + const latest = await getLatestVersion(); + if (latest !== currentVersion) { + const msg = ` + ${chalk.bold.yellow('WARNING:')} You should run ${chalk.white.bold( + 'npx react-native@latest', + )} to ensure you're always using the most current version of the CLI. NPX has cached version (${chalk.bold.yellow( + currentVersion, + )}) != current release (${chalk.bold.green(latest)}) + `; + console.warn(msg); + } + } catch (_) { + // Ignore errors, since it's a nice to have warning + } + } + return cli.run(); +} if (require.main === module) { - cli.run(); + main(); } module.exports = cli;