From b7e45f24a2b53c472833567ebd780eb65367d2b0 Mon Sep 17 00:00:00 2001 From: Ade Viankakrisna Fadlil Date: Thu, 13 Jul 2017 03:07:57 +0700 Subject: [PATCH 1/2] add toast for warnings --- packages/react-dev-utils/logger.js | 167 ++++++++++++++++++ .../react-dev-utils/webpackHotDevClient.js | 45 ++--- packages/react-scripts/template/src/App.js | 2 +- 3 files changed, 187 insertions(+), 27 deletions(-) create mode 100644 packages/react-dev-utils/logger.js diff --git a/packages/react-dev-utils/logger.js b/packages/react-dev-utils/logger.js new file mode 100644 index 00000000000..631ab87b51e --- /dev/null +++ b/packages/react-dev-utils/logger.js @@ -0,0 +1,167 @@ +'use strict'; +const React = require('react'); +const ReactDOM = require('react-dom'); +const h = React.createElement; + +const useLogger = true; +const domId = 'toast'; + +let dom = document.getElementById(domId); + +if (!dom) { + dom = document.createElement('div'); + dom.id = domId; + document.body.appendChild(dom); +} + +const style = { + root: { + position: 'fixed', + bottom: '0', + left: '0', + right: '0', + padding: 10, + margin: 'auto', + transition: '250ms', + lineHeight: '24px', + borderTopLeftRadius: '2px', + borderTopRightRadius: '2px', + display: 'flex', + fontFamily: 'monospace', + color: '#293238', + }, + active: { + transform: 'translateY(0)', + }, + inactive: { + transform: 'translateY(100%)', + }, + link: { + padding: '0', + background: 'transparent', + border: '0', + fontSize: 'inherit', + lineHeight: 'inherit', + textTransform: 'uppercase', + textDecoration: 'none', + }, + button: { + padding: '0', + background: 'transparent', + border: '0', + color: 'inherit', + fontSize: 'inherit', + lineHeight: 'inherit', + textTransform: 'uppercase', + textDecoration: 'none', + cursor: 'pointer', + }, + text: { + flex: '1', + }, +}; + +class Logger extends React.Component { + constructor(...args) { + super(...args); + this.state = { + active: true, + }; + this.close = () => { + clearTimeout(this.timeout); + this.setState({ + active: false, + }); + }; + } + + componentDidMount() { + this.timeout = setTimeout(() => { + this.setState({ + active: false, + }); + }, this.props.timeout); + } + componentWillUnmount() { + clearTimeout(this.timeout); + } + render() { + return h( + 'div', + { + style: Object.assign( + {}, + style.root, + this.state.active ? style.active : style.inactive, + getColor(this.props.type) + ), + }, + h('span', { style: style.text }, this.props.children), + h('button', { style: style.button, onClick: this.close }, 'Dismiss') + ); + } +} + +Logger.defaultProps = { + timeout: 10000, +}; + +function getColor(type) { + switch (type) { + case 'info': + return { + background: '#61dafb', + }; + case 'warn': + return { + background: '#fbf5b4', + }; + case 'error': + return { + background: '#fccfcf', + }; + default: + return { + color: 'transparent', + }; + } +} + +function render(type, message) { + if (useLogger) { + ReactDOM.render(h(Logger, { type }, message), dom); + } else { + console.log(message); + } +} + +const logger = { + info(message) { + if (typeof console !== 'undefined' && typeof console.info === 'function') { + console.info(message); + } + render('info', message); + }, + error(message) { + if (typeof console !== 'undefined' && typeof console.error === 'function') { + console.error(message); + } + render('error', message); + }, + warn(message) { + if (typeof console !== 'undefined' && typeof console.warn === 'function') { + console.warn(message); + } + render('warn', message); + }, + clear() { + if (typeof console !== 'undefined' && typeof console.clear === 'function') { + console.clear(); + } + render('clear'); + }, +}; + +logger.clear(); + +module.exports = logger; diff --git a/packages/react-dev-utils/webpackHotDevClient.js b/packages/react-dev-utils/webpackHotDevClient.js index 611fc6ba042..2c953eee76c 100644 --- a/packages/react-dev-utils/webpackHotDevClient.js +++ b/packages/react-dev-utils/webpackHotDevClient.js @@ -22,6 +22,7 @@ var url = require('url'); var launchEditorEndpoint = require('./launchEditorEndpoint'); var formatWebpackMessages = require('./formatWebpackMessages'); var ErrorOverlay = require('react-error-overlay'); +var logger = require('./logger'); // We need to keep track of if there has been a runtime error. // Essentially, we cannot guarantee application state was not corrupted by the @@ -57,14 +58,12 @@ var connection = new SockJS( ); // Unlike WebpackDevServer client, we won't try to reconnect -// to avoid spamming the console. Disconnect usually happens +// to avoid spamming the logger. Disconnect usually happens // when developer stops the server. connection.onclose = function() { - if (typeof console !== 'undefined' && typeof console.info === 'function') { - console.info( - 'The development server has disconnected.\nRefresh the page if necessary.' - ); - } + logger.info( + 'The development server has disconnected.\nRefresh the page if necessary.' + ); }; // Remember some state related to hot module replacement. @@ -74,10 +73,8 @@ var hasCompileErrors = false; function clearOutdatedErrors() { // Clean up outdated compile errors, if any. - if (typeof console !== 'undefined' && typeof console.clear === 'function') { - if (hasCompileErrors) { - console.clear(); - } + if (hasCompileErrors) { + logger.clear(); } } @@ -108,23 +105,21 @@ function handleWarnings(warnings) { hasCompileErrors = false; function printWarnings() { - // Print warnings to the console. + // Print warnings to the logger. var formatted = formatWebpackMessages({ warnings: warnings, errors: [], }); - if (typeof console !== 'undefined' && typeof console.warn === 'function') { - for (var i = 0; i < formatted.warnings.length; i++) { - if (i === 5) { - console.warn( - 'There were more warnings in other files.\n' + - 'You can find a complete log in the terminal.' - ); - break; - } - console.warn(stripAnsi(formatted.warnings[i])); + for (var i = 0; i < formatted.warnings.length; i++) { + if (i === 5) { + logger.warn( + 'There were more warnings in other files.\n' + + 'You can find a complete log in the terminal.' + ); + break; } + logger.warn(stripAnsi(formatted.warnings[i])); } } @@ -160,11 +155,9 @@ function handleErrors(errors) { // Only show the first error. ErrorOverlay.reportBuildError(formatted.errors[0]); - // Also log them to the console. - if (typeof console !== 'undefined' && typeof console.error === 'function') { - for (var i = 0; i < formatted.errors.length; i++) { - console.error(stripAnsi(formatted.errors[i])); - } + // Also log them to the logger. + for (var i = 0; i < formatted.errors.length; i++) { + logger.error(stripAnsi(formatted.errors[i])); } // Do not attempt to reload now. diff --git a/packages/react-scripts/template/src/App.js b/packages/react-scripts/template/src/App.js index 203067e4d75..03361cfd69f 100644 --- a/packages/react-scripts/template/src/App.js +++ b/packages/react-scripts/template/src/App.js @@ -18,4 +18,4 @@ class App extends Component { } } -export default App; +export default App; \ No newline at end of file From b02372d76bfeb6feb0fcd53992713c88db46bab9 Mon Sep 17 00:00:00 2001 From: Ade Viankakrisna Fadlil Date: Thu, 13 Jul 2017 04:47:14 +0700 Subject: [PATCH 2/2] add logger to package.json and remove duplicate log --- packages/react-dev-utils/logger.js | 15 ++++++--------- packages/react-dev-utils/package.json | 3 ++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/react-dev-utils/logger.js b/packages/react-dev-utils/logger.js index 631ab87b51e..1080a0ae000 100644 --- a/packages/react-dev-utils/logger.js +++ b/packages/react-dev-utils/logger.js @@ -3,14 +3,13 @@ const React = require('react'); const ReactDOM = require('react-dom'); const h = React.createElement; -const useLogger = true; -const domId = 'toast'; +const id = 'create-react-app-logger'; -let dom = document.getElementById(domId); +let dom = document.getElementById(id); if (!dom) { dom = document.createElement('div'); - dom.id = domId; + dom.id = id; document.body.appendChild(dom); } @@ -82,9 +81,11 @@ class Logger extends React.Component { }); }, this.props.timeout); } + componentWillUnmount() { clearTimeout(this.timeout); } + render() { return h( 'div', @@ -128,11 +129,7 @@ function getColor(type) { } function render(type, message) { - if (useLogger) { - ReactDOM.render(h(Logger, { type }, message), dom); - } else { - console.log(message); - } + ReactDOM.render(h(Logger, { type }, message), dom); } const logger = { diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json index 48e1dc49d6a..e305bbf7c98 100644 --- a/packages/react-dev-utils/package.json +++ b/packages/react-dev-utils/package.json @@ -24,7 +24,8 @@ "inquirer.js", "InterpolateHtmlPlugin.js", "launchEditor.js", - "launchEditorEndpoint.js", + "logger.js", + "noopServiceWorkerMiddleware.js", "ModuleScopePlugin.js", "noopServiceWorkerMiddleware.js", "openBrowser.js",