From b25ebc36c5ec881a947ee29ee69ddf85450111e3 Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Mon, 27 Mar 2017 19:24:00 -0700 Subject: [PATCH 1/2] [local-cli] Add support for custom log reporter cli option for packager server --- local-cli/server/runServer.js | 18 ++++++++++++++++-- local-cli/server/server.js | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/local-cli/server/runServer.js b/local-cli/server/runServer.js index 5cc924a3bd4946..595ae927d9de62 100644 --- a/local-cli/server/runServer.js +++ b/local-cli/server/runServer.js @@ -10,7 +10,6 @@ const InspectorProxy = require('./util/inspectorProxy.js'); const ReactPackager = require('../../packager/react-packager'); -const TerminalReporter = require('../../packager/src/lib/TerminalReporter'); const attachHMRServer = require('./util/attachHMRServer'); const connect = require('connect'); @@ -86,6 +85,21 @@ function getPackagerServer(args, config) { const providesModuleNodeModules = args.providesModuleNodeModules || defaultProvidesModuleNodeModules; + let LogReporter; + if (args.customLogReporterPath) { + try { + // First we let require resolve it, so we can require packages in node_modules + // as expected. eg: require('my-package/reporter'); + LogReporter = require(args.customLogReporterPath); + } catch(e) { + // If that doesn't work, then we next try relative to the cwd, eg: + // require('./reporter'); + LogReporter = require(path.resolve(args.customLogReporterPath)); + } + } else { + LogReporter = require('../../packager/src/lib/TerminalReporter'); + } + return ReactPackager.createServer({ assetExts: defaultAssetExts.concat(args.assetExts), blacklistRE: config.getBlacklistRE(), @@ -96,7 +110,7 @@ function getPackagerServer(args, config) { platforms: defaultPlatforms.concat(args.platforms), projectRoots: args.projectRoots, providesModuleNodeModules: providesModuleNodeModules, - reporter: new TerminalReporter(), + reporter: new LogReporter(), resetCache: args.resetCache, transformModulePath: transformModulePath, verbose: args.verbose, diff --git a/local-cli/server/server.js b/local-cli/server/server.js index 3d72c8d771bf9c..c09bc7c0bb96cd 100644 --- a/local-cli/server/server.js +++ b/local-cli/server/server.js @@ -118,6 +118,9 @@ module.exports = { }, { 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', From 21c5c60f5ceba6be0a43560f877b599d392cccae Mon Sep 17 00:00:00 2001 From: Brent Vatne Date: Wed, 29 Mar 2017 16:13:02 -0700 Subject: [PATCH 2/2] [local-cli][packager] Use the given log reporter for packager startup log messages too --- local-cli/server/runServer.js | 6 ++- local-cli/server/server.js | 65 ++++++++++------------------ packager/src/lib/TerminalReporter.js | 60 +++++++++++++++++++++++++ packager/src/lib/reporting.js | 10 +++++ 4 files changed, 96 insertions(+), 45 deletions(-) diff --git a/local-cli/server/runServer.js b/local-cli/server/runServer.js index 595ae927d9de62..a9cccbf35da51d 100644 --- a/local-cli/server/runServer.js +++ b/local-cli/server/runServer.js @@ -30,10 +30,12 @@ const systraceProfileMiddleware = require('./middleware/systraceProfileMiddlewar const unless = require('./middleware/unless'); const webSocketProxy = require('./util/webSocketProxy.js'); -function runServer(args, config, readyCallback) { +function runServer(args, config, startedCallback, readyCallback) { var wsProxy = null; var ms = null; const packagerServer = getPackagerServer(args, config); + startedCallback(packagerServer._reporter); + const inspectorProxy = new InspectorProxy(); const app = connect() .use(loadRawBodyMiddleware) @@ -67,7 +69,7 @@ function runServer(args, config, readyCallback) { wsProxy = webSocketProxy.attachToServer(serverInstance, '/debugger-proxy'); ms = messageSocket.attachToServer(serverInstance, '/message'); inspectorProxy.attachToServer(serverInstance, '/inspector'); - readyCallback(); + readyCallback(packagerServer._reporter); } ); // Disable any kind of automatic timeout behavior for incoming diff --git a/local-cli/server/server.js b/local-cli/server/server.js index c09bc7c0bb96cd..4825fc9a02bccb 100644 --- a/local-cli/server/server.js +++ b/local-cli/server/server.js @@ -8,8 +8,6 @@ */ 'use strict'; -const chalk = require('chalk'); -const formatBanner = require('./formatBanner'); const path = require('path'); const runServer = require('./runServer'); @@ -19,50 +17,31 @@ const runServer = require('./runServer'); 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, - }) - ); + const startedCallback = logReporter => { + logReporter.update({ + type: 'initialize_packager_started', + port: args.port, + projectRoots: args.projectRoots, + }); - console.log( - 'Looking for JS files in\n ', - chalk.dim(args.projectRoots.join('\n ')), - '\n' - ); + process.on('uncaughtException', error => { + logReporter.update({ + type: 'initialize_packager_failed', + port: args.port, + error, + }); - 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 '), '\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); - }); + process.exit(11); + }); + }; + + const readyCallback = logReporter => { + logReporter.update({ + type: 'initialize_packager_done', + }); + }; - runServer(args, config, () => console.log('\nReact packager ready.\n')); + runServer(args, config, startedCallback, readyCallback); } module.exports = { diff --git a/packager/src/lib/TerminalReporter.js b/packager/src/lib/TerminalReporter.js index 7f63d3b7049cae..40ed87392c6617 100644 --- a/packager/src/lib/TerminalReporter.js +++ b/packager/src/lib/TerminalReporter.js @@ -11,11 +11,13 @@ 'use strict'; +const chalk = require('chalk'); const path = require('path'); const reporting = require('./reporting'); const terminal = require('./terminal'); const throttle = require('lodash/throttle'); const util = require('util'); +const formatBanner = require('../../../local-cli/server/formatBanner'); import type {ReportableEvent, GlobalCacheDisabledReason} from './reporting'; @@ -133,12 +135,70 @@ class TerminalReporter { } } + + _logPackagerInitializing(port: number, projectRoots: Array) { + terminal.log( + formatBanner( + 'Running packager on port ' + + 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, + } + ) + ); + + terminal.log( + 'Looking for JS files in\n ', + chalk.dim(projectRoots.join('\n ')), + '\n' + ); + } + + _logPackagerInitializingFailed(port: number, error: Error) { + if (error.code === 'EADDRINUSE') { + terminal.log( + chalk.bgRed.bold(' ERROR '), + chalk.red("Packager can't listen on port", chalk.bold(port)) + ); + terminal.log('Most likely another process is already using this port'); + terminal.log('Run the following command to find out which process:'); + terminal.log('\n ', chalk.bold('lsof -i :' + port), '\n'); + terminal.log('Then, you can either shut down the other process:'); + terminal.log('\n ', chalk.bold('kill -9 '), '\n'); + terminal.log('or run packager on different port.'); + } else { + terminal.log(chalk.bgRed.bold(' ERROR '), chalk.red(error.message)); + const errorAttributes = JSON.stringify(error); + if (errorAttributes !== '{}') { + terminal.log(chalk.red(errorAttributes)); + } + terminal.log(chalk.red(error.stack)); + } + } + + /** * This function is only concerned with logging and should not do state * or terminal status updates. */ _log(event: TerminalReportableEvent): void { switch (event.type) { + case 'initialize_packager_started': + this._logPackagerInitializing(event.port, event.projectRoots); + break; + case 'initialize_packager_done': + terminal.log('\nReact packager ready.\n'); + break; + case 'initialize_packager_failed': + this._logPackagerInitializingFailed(event.port, event.error); + break; case 'bundle_build_done': this._logBundleBuildDone(event.entryFilePath); break; diff --git a/packager/src/lib/reporting.js b/packager/src/lib/reporting.js index d7f92fe81c9742..29994435f580f6 100644 --- a/packager/src/lib/reporting.js +++ b/packager/src/lib/reporting.js @@ -23,6 +23,16 @@ export type GlobalCacheDisabledReason = 'too_many_errors' | 'too_many_misses'; * report to the tool user. */ export type ReportableEvent = { + port: number, + projectRoots: Array, + type: 'initialize_packager_started', +} | { + type: 'initialize_packager_done', +} | { + type: 'initialize_packager_failed', + port: number, + error: Error, +} | { entryFilePath: string, type: 'bundle_build_done', } | {