mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-02 09:21:44 +08:00
Summary:
In Expo tools such as XDE, exp we listen listen to stdout from the packager process and print it in our own buffer. In the case of XDE, an electron app, our log pane is DOM-based, and before printing each log chunk we need to remove special tty characters and sometimes parse it to get information that we need (eg: progress bar). By using a custom reporter, we can take the raw events and pass them along in a format that is easy to consume by XDE and exp. This same motivation applies to create-react-native-app, where we currently don't show a progress bar in the terminal, but we can with this change.
Create `LogReporter.js` in the root of a project with the CLI changes included in this PR.
```
class LogReporter {
update(event) {
console.log(JSON.stringify(event));
}
}
module.exports = LogReporter;
```
Now, run `react-native start --customLogReporterPath=LogReporter.js` -- all of the raw events will be output as JSON (while the logs
Closes https://github.com/facebook/react-native/pull/13172
Differential Revision: D4795760
Pulled By: hramos
fbshipit-source-id: 80164b2f30e33a3f9965f4865a8404f8640a52c1
129 lines
4.3 KiB
JavaScript
129 lines
4.3 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 = 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: '--custom-log-reporter-path, --customLogReporterPath [string]',
|
|
description: 'Path to a JavaScript file that exports a log reporter as a replacement for TerminalReporter',
|
|
}, {
|
|
command: '--verbose',
|
|
description: 'Enables logging',
|
|
}],
|
|
};
|