Skip to content

Commit b7e45f2

Browse files
committed
add toast for warnings
1 parent b2c0b3f commit b7e45f2

File tree

3 files changed

+187
-27
lines changed

3 files changed

+187
-27
lines changed

packages/react-dev-utils/logger.js

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
'use strict';
2+
const React = require('react');
3+
const ReactDOM = require('react-dom');
4+
const h = React.createElement;
5+
6+
const useLogger = true;
7+
const domId = 'toast';
8+
9+
let dom = document.getElementById(domId);
10+
11+
if (!dom) {
12+
dom = document.createElement('div');
13+
dom.id = domId;
14+
document.body.appendChild(dom);
15+
}
16+
17+
const style = {
18+
root: {
19+
position: 'fixed',
20+
bottom: '0',
21+
left: '0',
22+
right: '0',
23+
padding: 10,
24+
margin: 'auto',
25+
transition: '250ms',
26+
lineHeight: '24px',
27+
borderTopLeftRadius: '2px',
28+
borderTopRightRadius: '2px',
29+
display: 'flex',
30+
fontFamily: 'monospace',
31+
color: '#293238',
32+
},
33+
active: {
34+
transform: 'translateY(0)',
35+
},
36+
inactive: {
37+
transform: 'translateY(100%)',
38+
},
39+
link: {
40+
padding: '0',
41+
background: 'transparent',
42+
border: '0',
43+
fontSize: 'inherit',
44+
lineHeight: 'inherit',
45+
textTransform: 'uppercase',
46+
textDecoration: 'none',
47+
},
48+
button: {
49+
padding: '0',
50+
background: 'transparent',
51+
border: '0',
52+
color: 'inherit',
53+
fontSize: 'inherit',
54+
lineHeight: 'inherit',
55+
textTransform: 'uppercase',
56+
textDecoration: 'none',
57+
cursor: 'pointer',
58+
},
59+
text: {
60+
flex: '1',
61+
},
62+
};
63+
64+
class Logger extends React.Component {
65+
constructor(...args) {
66+
super(...args);
67+
this.state = {
68+
active: true,
69+
};
70+
this.close = () => {
71+
clearTimeout(this.timeout);
72+
this.setState({
73+
active: false,
74+
});
75+
};
76+
}
77+
78+
componentDidMount() {
79+
this.timeout = setTimeout(() => {
80+
this.setState({
81+
active: false,
82+
});
83+
}, this.props.timeout);
84+
}
85+
componentWillUnmount() {
86+
clearTimeout(this.timeout);
87+
}
88+
render() {
89+
return h(
90+
'div',
91+
{
92+
style: Object.assign(
93+
{},
94+
style.root,
95+
this.state.active ? style.active : style.inactive,
96+
getColor(this.props.type)
97+
),
98+
},
99+
h('span', { style: style.text }, this.props.children),
100+
h('button', { style: style.button, onClick: this.close }, 'Dismiss')
101+
);
102+
}
103+
}
104+
105+
Logger.defaultProps = {
106+
timeout: 10000,
107+
};
108+
109+
function getColor(type) {
110+
switch (type) {
111+
case 'info':
112+
return {
113+
background: '#61dafb',
114+
};
115+
case 'warn':
116+
return {
117+
background: '#fbf5b4',
118+
};
119+
case 'error':
120+
return {
121+
background: '#fccfcf',
122+
};
123+
default:
124+
return {
125+
color: 'transparent',
126+
};
127+
}
128+
}
129+
130+
function render(type, message) {
131+
if (useLogger) {
132+
ReactDOM.render(h(Logger, { type }, message), dom);
133+
} else {
134+
console.log(message);
135+
}
136+
}
137+
138+
const logger = {
139+
info(message) {
140+
if (typeof console !== 'undefined' && typeof console.info === 'function') {
141+
console.info(message);
142+
}
143+
render('info', message);
144+
},
145+
error(message) {
146+
if (typeof console !== 'undefined' && typeof console.error === 'function') {
147+
console.error(message);
148+
}
149+
render('error', message);
150+
},
151+
warn(message) {
152+
if (typeof console !== 'undefined' && typeof console.warn === 'function') {
153+
console.warn(message);
154+
}
155+
render('warn', message);
156+
},
157+
clear() {
158+
if (typeof console !== 'undefined' && typeof console.clear === 'function') {
159+
console.clear();
160+
}
161+
render('clear');
162+
},
163+
};
164+
165+
logger.clear();
166+
167+
module.exports = logger;

packages/react-dev-utils/webpackHotDevClient.js

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ var url = require('url');
2222
var launchEditorEndpoint = require('./launchEditorEndpoint');
2323
var formatWebpackMessages = require('./formatWebpackMessages');
2424
var ErrorOverlay = require('react-error-overlay');
25+
var logger = require('./logger');
2526

2627
// We need to keep track of if there has been a runtime error.
2728
// Essentially, we cannot guarantee application state was not corrupted by the
@@ -57,14 +58,12 @@ var connection = new SockJS(
5758
);
5859

5960
// Unlike WebpackDevServer client, we won't try to reconnect
60-
// to avoid spamming the console. Disconnect usually happens
61+
// to avoid spamming the logger. Disconnect usually happens
6162
// when developer stops the server.
6263
connection.onclose = function() {
63-
if (typeof console !== 'undefined' && typeof console.info === 'function') {
64-
console.info(
65-
'The development server has disconnected.\nRefresh the page if necessary.'
66-
);
67-
}
64+
logger.info(
65+
'The development server has disconnected.\nRefresh the page if necessary.'
66+
);
6867
};
6968

7069
// Remember some state related to hot module replacement.
@@ -74,10 +73,8 @@ var hasCompileErrors = false;
7473

7574
function clearOutdatedErrors() {
7675
// Clean up outdated compile errors, if any.
77-
if (typeof console !== 'undefined' && typeof console.clear === 'function') {
78-
if (hasCompileErrors) {
79-
console.clear();
80-
}
76+
if (hasCompileErrors) {
77+
logger.clear();
8178
}
8279
}
8380

@@ -108,23 +105,21 @@ function handleWarnings(warnings) {
108105
hasCompileErrors = false;
109106

110107
function printWarnings() {
111-
// Print warnings to the console.
108+
// Print warnings to the logger.
112109
var formatted = formatWebpackMessages({
113110
warnings: warnings,
114111
errors: [],
115112
});
116113

117-
if (typeof console !== 'undefined' && typeof console.warn === 'function') {
118-
for (var i = 0; i < formatted.warnings.length; i++) {
119-
if (i === 5) {
120-
console.warn(
121-
'There were more warnings in other files.\n' +
122-
'You can find a complete log in the terminal.'
123-
);
124-
break;
125-
}
126-
console.warn(stripAnsi(formatted.warnings[i]));
114+
for (var i = 0; i < formatted.warnings.length; i++) {
115+
if (i === 5) {
116+
logger.warn(
117+
'There were more warnings in other files.\n' +
118+
'You can find a complete log in the terminal.'
119+
);
120+
break;
127121
}
122+
logger.warn(stripAnsi(formatted.warnings[i]));
128123
}
129124
}
130125

@@ -160,11 +155,9 @@ function handleErrors(errors) {
160155
// Only show the first error.
161156
ErrorOverlay.reportBuildError(formatted.errors[0]);
162157

163-
// Also log them to the console.
164-
if (typeof console !== 'undefined' && typeof console.error === 'function') {
165-
for (var i = 0; i < formatted.errors.length; i++) {
166-
console.error(stripAnsi(formatted.errors[i]));
167-
}
158+
// Also log them to the logger.
159+
for (var i = 0; i < formatted.errors.length; i++) {
160+
logger.error(stripAnsi(formatted.errors[i]));
168161
}
169162

170163
// Do not attempt to reload now.

packages/react-scripts/template/src/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ class App extends Component {
1818
}
1919
}
2020

21-
export default App;
21+
export default App;

0 commit comments

Comments
 (0)