react-native-cli
Advanced tools
+101
| ## Running CLI with local modifications | ||
| React Native is distributed as two npm packages, `react-native-cli` and `react-native`. The first one is a lightweight package that should be installed globally (`npm install -g react-native-cli`), while the second one contains the actual React Native framework code and is installed locally into your project when you run `react-native init`. | ||
| Because `react-native init` calls `npm install react-native`, simply linking your local github clone into npm is not enough to test local changes. | ||
| ### Introducing Sinopia | ||
| [Sinopia] is an npm registry that runs on your local machine and allows you to publish packages to it. Everything else is proxied from `npmjs.com`. We'll set up sinopia for React Native CLI development. First, install it with: | ||
| $ npm install -g sinopia | ||
| Then, open `~/.config/sinopia/config.yaml` and configure it like this (note the `max_body_size`): | ||
| storage: ./storage | ||
| auth: | ||
| htpasswd: | ||
| file: ./htpasswd | ||
| uplinks: | ||
| npmjs: | ||
| url: https://registry.npmjs.org/ | ||
| packages: | ||
| 'react-native': | ||
| allow_access: $all | ||
| allow_publish: $all | ||
| 'react-native-cli': | ||
| allow_access: $all | ||
| allow_publish: $all | ||
| '*': | ||
| allow_access: $all | ||
| proxy: npmjs | ||
| logs: | ||
| - {type: stdout, format: pretty, level: http} | ||
| max_body_size: '50mb' | ||
| Now you can run sinopia by simply doing: | ||
| $ sinopia | ||
| ### Publishing to sinopia | ||
| Now we need to publish the two React Native packages to our local registry. To do this, we configure npm to use the new registry, unpublish any existing packages and then publish the new ones: | ||
| react-native$ npm set registry http://localhost:4873/ | ||
| react-native$ npm adduser --registry http://localhost:4873/ | ||
| # Check that it worked: | ||
| react-native$ npm config list | ||
| react-native$ npm unpublish --force | ||
| react-native$ npm publish | ||
| react-native$ cd react-native-cli/ | ||
| react-native-cli$ npm unpublish --force | ||
| react-native-cli$ npm publish | ||
| ### Running the local CLI | ||
| Now that the packages are installed in sinopia, you can install the new `react-native-cli` package globally and when you use `react-native init`, it will install the new `react-native` package as well: | ||
| $ npm uninstall -g react-native-cli | ||
| $ npm install -g react-native-cli | ||
| $ react-native init AwesomeApp | ||
| ## Testing changes | ||
| Most of the CLI code is covered by jest tests, which you can run with: | ||
| $ npm test | ||
| Project generation is also covered by e2e tests, which you can run with: | ||
| $ ./scripts/e2e-test.sh | ||
| These tests actually create a very similar setup to what is described above (using sinopia) and they also run iOS-specific tests, so you will need to run this on OSX and have [xctool] installed. | ||
| Both of these types of tests also run on Travis both continuously and on pull requests. | ||
| [sinopia]: https://www.npmjs.com/package/sinopia | ||
| [xctool]: https://github.com/facebook/xctool | ||
| ## Clean up | ||
| To unset the npm registry, do: | ||
| $ npm set registry https://registry.npmjs.org/ | ||
| # Check that it worked: | ||
| $ npm config list | ||
| ## Troubleshooting | ||
| ##### Sinopia crashes with "Module version mismatch" | ||
| This usually happens when you install a package using one version of Node and then change to a different version. This can happen when you update Node, or switch to a different version with nvm. Do: | ||
| $ npm uninstall -g sinopia | ||
| $ npm install -g sinopia |
| Use react-native-cli to initialize a working starter React Native app using the latest react-native version in npm. This package should be installed globally. | ||
| Usage: | ||
| ``` | ||
| % npm install -g react-native-cli | ||
| % react-native init MyApplication | ||
| ``` |
+49
-23
@@ -7,6 +7,9 @@ #!/usr/bin/env node | ||
| 'use strict'; | ||
| var fs = require('fs'); | ||
| var path = require('path'); | ||
| var exec = require('child_process').exec; | ||
| var spawn = require('child_process').spawn; | ||
| var prompt = require("prompt"); | ||
| var prompt = require('prompt'); | ||
@@ -18,10 +21,13 @@ var CLI_MODULE_PATH = function() { | ||
| 'react-native', | ||
| 'cli' | ||
| 'cli.js' | ||
| ); | ||
| }; | ||
| checkForVersionArgument(); | ||
| var cli; | ||
| try { | ||
| cli = require(CLI_MODULE_PATH()); | ||
| } catch(e) {} | ||
| var cliPath = CLI_MODULE_PATH(); | ||
| if (fs.existsSync(cliPath)) { | ||
| cli = require(cliPath); | ||
| } | ||
@@ -42,6 +48,7 @@ if (cli) { | ||
| if (args[1]) { | ||
| init(args[1]); | ||
| var verbose = process.argv.indexOf('--verbose') >= 0; | ||
| init(args[1], verbose); | ||
| } else { | ||
| console.error( | ||
| 'Usage: react-native init <ProjectName>' | ||
| 'Usage: react-native init <ProjectName> [--verbose]' | ||
| ); | ||
@@ -82,13 +89,13 @@ process.exit(1); | ||
| function init(name) { | ||
| function init(name, verbose) { | ||
| validatePackageName(name); | ||
| if (fs.existsSync(name)) { | ||
| createAfterConfirmation(name) | ||
| createAfterConfirmation(name, verbose); | ||
| } else { | ||
| createProject(name); | ||
| createProject(name, verbose); | ||
| } | ||
| } | ||
| function createAfterConfirmation(name) { | ||
| function createAfterConfirmation(name, verbose) { | ||
| prompt.start(); | ||
@@ -106,3 +113,3 @@ | ||
| if (result.yesno[0] === 'y') { | ||
| createProject(name); | ||
| createProject(name, verbose); | ||
| } else { | ||
@@ -115,3 +122,3 @@ console.log('Project initialization canceled'); | ||
| function createProject(name) { | ||
| function createProject(name, verbose) { | ||
| var root = path.resolve(name); | ||
@@ -140,4 +147,16 @@ var projectName = path.basename(root); | ||
| run('npm install --save react-native', function(e) { | ||
| console.log('Installing react-native package from npm...'); | ||
| if (verbose) { | ||
| runVerbose(root, projectName); | ||
| } else { | ||
| run(root, projectName); | ||
| } | ||
| } | ||
| function run(root, projectName) { | ||
| exec('npm install --save react-native', function(e, stdout, stderr) { | ||
| if (e) { | ||
| console.log(stdout); | ||
| console.error(stderr); | ||
| console.error('`npm install --save react-native` failed'); | ||
@@ -152,14 +171,21 @@ process.exit(1); | ||
| function run(command, cb) { | ||
| var parts = command.split(/\s+/); | ||
| var cmd = parts[0]; | ||
| var args = parts.slice(1); | ||
| var proc = spawn(cmd, args, {stdio: 'inherit'}); | ||
| proc.on('close', function(code) { | ||
| function runVerbose(root, projectName) { | ||
| var proc = spawn('npm', ['install', '--verbose', '--save', 'react-native'], {stdio: 'inherit'}); | ||
| proc.on('close', function (code) { | ||
| if (code !== 0) { | ||
| cb(new Error('Command exited with a non-zero status')); | ||
| } else { | ||
| cb(null); | ||
| console.error('`npm install --save react-native` failed'); | ||
| return; | ||
| } | ||
| cli = require(CLI_MODULE_PATH()); | ||
| cli.init(root, projectName); | ||
| }); | ||
| } | ||
| function checkForVersionArgument() { | ||
| if (process.argv.indexOf('-v') >= 0 || process.argv.indexOf('--version') >= 0) { | ||
| var pjson = require('./package.json'); | ||
| console.log(pjson.version); | ||
| process.exit(); | ||
| } | ||
| } |
+4
-1
| { | ||
| "name": "react-native-cli", | ||
| "version": "0.1.4", | ||
| "version": "0.1.5", | ||
| "description": "The ReactNative cli tools", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "test": "mocha" | ||
| }, | ||
| "bin": { | ||
@@ -7,0 +10,0 @@ "react-native": "index.js" |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
7993
130.01%4
100%157
14.6%0
-100%9
Infinity%6
20%3
200%