Harshil Shah bce6ece5f6 Add symlinks under node_modules as part of projectRoots
Summary:
Support symlinks under `node_modules` for all local-cli commands. PR https://github.com/facebook/react-native/pull/9009 only adds symlink support to the packager.

But other cli commands like `react-native bundle` creates its own instance of packager that doesn't have symlinks as part of its project roots, which results in the bundler breaking since it cannot find modules that you have symlinked.

This change ensures all `local-cli` commands add symlinks to its project roots.

Test plan (required)

1.  Create a symlink in node_modules (for instance use npm/yarn link)
2. Run `react-native bundle`.
Closes https://github.com/facebook/react-native/pull/11810

Differential Revision: D4487741

fbshipit-source-id: 87fe44194134d086dca4eaca99ee5742d6eadb69
2017-01-31 03:43:39 -08:00

126 lines
4.1 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const chalk = require('chalk');
const formatBanner = require('./formatBanner');
const path = require('path');
const runServer = require('./runServer');
/**
* Starts the React Native Packager Server.
*/
function server(argv, config, args) {
args.projectRoots.concat(args.root);
console.log(formatBanner(
'Running packager on port ' + args.port + '.\n\n' +
'Keep this packager running while developing on any JS projects. ' +
'Feel free to close this tab and run your own packager instance if you ' +
'prefer.\n\n' +
'https://github.com/facebook/react-native', {
marginLeft: 1,
marginRight: 1,
paddingBottom: 1,
})
);
console.log(
'Looking for JS files in\n ',
chalk.dim(args.projectRoots.join('\n ')),
'\n'
);
process.on('uncaughtException', error => {
if (error.code === 'EADDRINUSE') {
console.log(
chalk.bgRed.bold(' ERROR '),
chalk.red('Packager can\'t listen on port', chalk.bold(args.port))
);
console.log('Most likely another process is already using this port');
console.log('Run the following command to find out which process:');
console.log('\n ', chalk.bold('lsof -i :' + args.port), '\n');
console.log('Then, you can either shut down the other process:');
console.log('\n ', chalk.bold('kill -9 <PID>'), '\n');
console.log('or run packager on different port.');
} else {
console.log(chalk.bgRed.bold(' ERROR '), chalk.red(error.message));
const errorAttributes = JSON.stringify(error);
if (errorAttributes !== '{}') {
console.error(chalk.red(errorAttributes));
}
console.error(chalk.red(error.stack));
}
console.log('\nSee', chalk.underline('http://facebook.github.io/react-native/docs/troubleshooting.html'));
console.log('for common problems and solutions.');
process.exit(11);
});
runServer(args, config, () => console.log('\nReact packager ready.\n'));
}
module.exports = {
name: 'start',
func: server,
description: 'starts the webserver',
options: [{
command: '--port [number]',
default: 8081,
parse: (val) => Number(val),
}, {
command: '--host [string]',
default: '',
}, {
command: '--root [list]',
description: 'add another root(s) to be used by the packager in this project',
parse: (val) => val.split(',').map(root => path.resolve(root)),
default: [],
}, {
command: '--projectRoots [list]',
description: 'override the root(s) to be used by the packager',
parse: (val) => val.split(','),
default: (config) => config.getProjectRoots(),
}, {
command: '--assetExts [list]',
description: 'Specify any additional asset extentions to be used by the packager',
parse: (val) => val.split(','),
default: (config) => config.getAssetExts(),
}, {
command: '--platforms [list]',
description: 'Specify any additional platforms to be used by the packager',
parse: (val) => val.split(','),
default: (config) => config.getPlatforms(),
}, {
command: '--providesModuleNodeModules [list]',
description: 'Specify any npm packages that import dependencies with providesModule',
parse: (val) => val.split(','),
default: (config) => {
if (typeof config.getProvidesModuleNodeModules === 'function') {
return config.getProvidesModuleNodeModules();
}
return null;
},
}, {
command: '--skipflow',
description: 'Disable flow checks'
}, {
command: '--nonPersistent',
description: 'Disable file watcher'
}, {
command: '--transformer [string]',
description: 'Specify a custom transformer to be used'
}, {
command: '--reset-cache, --resetCache',
description: 'Removes cached files',
}, {
command: '--verbose',
description: 'Enables logging',
}],
};