Skip to content

Commit

Permalink
Replace console.warn/error with a custom wrapper at build time
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Dec 12, 2019
1 parent 43d70d7 commit f8febfe
Show file tree
Hide file tree
Showing 29 changed files with 279 additions and 353 deletions.
13 changes: 12 additions & 1 deletion .eslintrc.js
Expand Up @@ -33,7 +33,8 @@ module.exports = {
'comma-dangle': [ERROR, 'always-multiline'],
'consistent-return': OFF,
'dot-location': [ERROR, 'property'],
'dot-notation': ERROR,
// We use console['error']() as a signal to not transform it:
'dot-notation': [ERROR, {allowPattern: '^(error|warn)$'}],
'eol-last': ERROR,
eqeqeq: [ERROR, 'allow-null'],
indent: OFF,
Expand Down Expand Up @@ -135,6 +136,16 @@ module.exports = {
'jest/valid-expect-in-promise': ERROR,
},
},
{
files: [
'**/__tests__/**/*.js',
'scripts/**/*.js',
'packages/react-devtools*/**/*.js'
],
rules: {
'react-internal/no-production-logging': OFF,
},
},
{
files: ['packages/react-native-renderer/**/*.js'],
globals: {
Expand Down
8 changes: 5 additions & 3 deletions packages/legacy-events/ResponderEventPlugin.js
Expand Up @@ -515,9 +515,11 @@ const ResponderEventPlugin = {
if (trackedTouchCount >= 0) {
trackedTouchCount -= 1;
} else {
console.warn(
'Ended a touch event which was not counted in `trackedTouchCount`.',
);
if (__DEV__) {
console.warn(
'Ended a touch event which was not counted in `trackedTouchCount`.',
);
}
return null;
}
}
Expand Down
29 changes: 17 additions & 12 deletions packages/legacy-events/ResponderTouchHistoryStore.js
Expand Up @@ -129,12 +129,15 @@ function recordTouchMove(touch: Touch): void {
touchRecord.currentTimeStamp = timestampForTouch(touch);
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
} else {
console.warn(
'Cannot record touch move without a touch start.\n' + 'Touch Move: %s\n',
'Touch Bank: %s',
printTouch(touch),
printTouchBank(),
);
if (__DEV__) {
console.warn(
'Cannot record touch move without a touch start.\n' +
'Touch Move: %s\n',
'Touch Bank: %s',
printTouch(touch),
printTouchBank(),
);
}
}
}

Expand All @@ -150,12 +153,14 @@ function recordTouchEnd(touch: Touch): void {
touchRecord.currentTimeStamp = timestampForTouch(touch);
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
} else {
console.warn(
'Cannot record touch end without a touch start.\n' + 'Touch End: %s\n',
'Touch Bank: %s',
printTouch(touch),
printTouchBank(),
);
if (__DEV__) {
console.warn(
'Cannot record touch end without a touch start.\n' + 'Touch End: %s\n',
'Touch Bank: %s',
printTouch(touch),
printTouchBank(),
);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/react-dom/npm/index.js
Expand Up @@ -24,7 +24,7 @@ function checkDCE() {
} catch (err) {
// DevTools shouldn't crash React, no matter what.
// We should still report in case we break this code.
console.error(err);
console['error'](err);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/react-dom/npm/profiling.js
Expand Up @@ -24,7 +24,7 @@ function checkDCE() {
} catch (err) {
// DevTools shouldn't crash React, no matter what.
// We should still report in case we break this code.
console.error(err);
console['error'](err);
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/react-dom/src/client/ReactDOM.js
Expand Up @@ -211,6 +211,7 @@ if (__DEV__) {
const protocol = window.location.protocol;
// Don't warn in exotic cases like chrome-extension://.
if (/^(https?|file):$/.test(protocol)) {
// eslint-disable-next-line react-internal/no-production-logging
console.info(
'%cDownload the React DevTools ' +
'for a better development experience: ' +
Expand Down
1 change: 1 addition & 0 deletions packages/react-dom/src/test-utils/ReactTestUtilsAct.js
Expand Up @@ -79,6 +79,7 @@ function act(callback: () => Thenable) {
if (!__DEV__) {
if (didWarnAboutUsingActInProd === false) {
didWarnAboutUsingActInProd = true;
// eslint-disable-next-line react-internal/no-production-logging
console.error(
'act(...) is not supported in production builds of React, and might not behave as expected.',
);
Expand Down
Expand Up @@ -22,7 +22,9 @@ export function hasPointerEvent() {
export function setPointerEvent(bool) {
const pointerCaptureFn = name => id => {
if (typeof id !== 'number') {
console.error(`A pointerId must be passed to "${name}"`);
if (__DEV__) {
console.error(`A pointerId must be passed to "${name}"`);
}
}
};
global.PointerEvent = bool ? emptyFunction : undefined;
Expand Down
3 changes: 1 addition & 2 deletions packages/react-is/src/ReactIs.js
Expand Up @@ -25,7 +25,6 @@ import {
REACT_SUSPENSE_TYPE,
} from 'shared/ReactSymbols';
import isValidElementType from 'shared/isValidElementType';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';

export function typeOf(object: any) {
if (typeof object === 'object' && object !== null) {
Expand Down Expand Up @@ -88,7 +87,7 @@ export function isAsyncMode(object: any) {
if (__DEV__) {
if (!hasWarnedAboutDeprecatedIsAsyncMode) {
hasWarnedAboutDeprecatedIsAsyncMode = true;
lowPriorityWarningWithoutStack(
console.warn(
'The ReactIs.isAsyncMode() alias has been deprecated, ' +
'and will be removed in React 17+. Update your code to use ' +
'ReactIs.isConcurrentMode() instead. It has the exact same API.',
Expand Down
24 changes: 13 additions & 11 deletions packages/react-native-renderer/src/NativeMethodsMixinUtils.js
Expand Up @@ -66,17 +66,19 @@ export function throwOnStylesProp(component: any, props: any) {
}

export function warnForStyleProps(props: any, validAttributes: any) {
for (const key in validAttributes.style) {
if (!(validAttributes[key] || props[key] === undefined)) {
console.error(
'You are setting the style `{ ' +
key +
': ... }` as a prop. You ' +
'should nest it in a style object. ' +
'E.g. `{ style: { ' +
key +
': ... } }`',
);
if (__DEV__) {
for (const key in validAttributes.style) {
if (!(validAttributes[key] || props[key] === undefined)) {
console.error(
'You are setting the style `{ ' +
key +
': ... }` as a prop. You ' +
'should nest it in a style object. ' +
'E.g. `{ style: { ' +
key +
': ... } }`',
);
}
}
}
}
3 changes: 3 additions & 0 deletions packages/react-noop-renderer/src/createReactNoop.js
Expand Up @@ -638,6 +638,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
if (!__DEV__) {
if (didWarnAboutUsingActInProd === false) {
didWarnAboutUsingActInProd = true;
// eslint-disable-next-line react-internal/no-production-logging
console.error(
'act(...) is not supported in production builds of React, and might not behave as expected.',
);
Expand Down Expand Up @@ -1106,6 +1107,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
const root = roots.get(rootID);
const rootContainer = rootContainers.get(rootID);
if (!root || !rootContainer) {
// eslint-disable-next-line react-internal/no-production-logging
console.log('Nothing rendered yet.');
return;
}
Expand Down Expand Up @@ -1208,6 +1210,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
log('FIBERS:');
logFiber(root.current, 0);

// eslint-disable-next-line react-internal/no-production-logging
console.log(...bufferedLog);
},

Expand Down
10 changes: 4 additions & 6 deletions packages/react-reconciler/src/ReactFiberErrorLogger.js
Expand Up @@ -20,9 +20,6 @@ export function logCapturedError(capturedError: CapturedError): void {
return;
}

// Prevent it from being seen by Babel transform.
const rawConsoleError = console.error;

const error = (capturedError.error: any);
if (__DEV__) {
const {
Expand All @@ -47,7 +44,7 @@ export function logCapturedError(capturedError: CapturedError): void {
// been accidental, we'll surface it anyway.
// However, the browser would have silenced the original error
// so we'll print it first, and then print the stack addendum.
rawConsoleError(error);
console['error'](error); // Don't transform to our wrapper
// For a more detailed description of this block, see:
// https://github.com/facebook/react/pull/13384
}
Expand Down Expand Up @@ -81,11 +78,12 @@ export function logCapturedError(capturedError: CapturedError): void {
// We don't include the original error message and JS stack because the browser
// has already printed it. Even if the application swallows the error, it is still
// displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
rawConsoleError(combinedMessage);
console['error'](combinedMessage); // Don't transform to our wrapper
} else {
// In production, we print the error directly.
// This will include the message, the JS stack, and anything the browser wants to show.
// We pass the error object instead of custom message so that the browser displays the error natively.
rawConsoleError(error);
// eslint-disable-next-line react-internal/no-production-logging
console['error'](error); // Don't transform to our wrapper
}
}
1 change: 1 addition & 0 deletions packages/react-test-renderer/src/ReactTestRendererAct.js
Expand Up @@ -60,6 +60,7 @@ function act(callback: () => Thenable) {
if (!__DEV__) {
if (didWarnAboutUsingActInProd === false) {
didWarnAboutUsingActInProd = true;
// eslint-disable-next-line react-internal/no-production-logging
console.error(
'act(...) is not supported in production builds of React, and might not behave as expected.',
);
Expand Down
3 changes: 2 additions & 1 deletion packages/scheduler/src/SchedulerProfiling.js
Expand Up @@ -69,7 +69,8 @@ function logEvent(entries) {
if (eventLogIndex + 1 > eventLogSize) {
eventLogSize *= 2;
if (eventLogSize > MAX_EVENT_LOG_SIZE) {
console.error(
console['error'](
// Don't transform to our wrapper
"Scheduler Profiling: Event log exceeded maximum size. Don't " +
'forget to call `stopLoggingProfilingEvents()`.',
);
Expand Down
Expand Up @@ -544,7 +544,7 @@ Task 1 [Normal] │ █████████
}

expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error.calls.argsFor(0)[0]).toContain(
expect(console.error.calls.argsFor(0)[0]).toBe(
"Scheduler Profiling: Event log exceeded maximum size. Don't forget " +
'to call `stopLoggingProfilingEvents()`.',
);
Expand Down
9 changes: 6 additions & 3 deletions packages/scheduler/src/forks/SchedulerHostConfig.default.js
Expand Up @@ -81,14 +81,16 @@ if (
const cancelAnimationFrame = window.cancelAnimationFrame;
// TODO: Remove fb.me link
if (typeof requestAnimationFrame !== 'function') {
console.error(
console['error'](
// Don't transform to our wrapper
"This browser doesn't support requestAnimationFrame. " +
'Make sure that you load a ' +
'polyfill in older browsers. https://fb.me/react-polyfills',
);
}
if (typeof cancelAnimationFrame !== 'function') {
console.error(
console['error'](
// Don't transform to our wrapper
"This browser doesn't support cancelAnimationFrame. " +
'Make sure that you load a ' +
'polyfill in older browsers. https://fb.me/react-polyfills',
Expand Down Expand Up @@ -169,7 +171,8 @@ if (

forceFrameRate = function(fps) {
if (fps < 0 || fps > 125) {
console.error(
console['error'](
// Don't transform to our wrapper
'forceFrameRate takes a positive int between 0 and 125, ' +
'forcing framerates higher than 125 fps is not unsupported',
);
Expand Down
4 changes: 1 addition & 3 deletions packages/shared/enqueueTask.js
Expand Up @@ -7,8 +7,6 @@
* @flow
*/

import warningWithoutStack from 'shared/warningWithoutStack';

let didWarnAboutMessageChannel = false;
let enqueueTask;
try {
Expand All @@ -28,7 +26,7 @@ try {
if (didWarnAboutMessageChannel === false) {
didWarnAboutMessageChannel = true;
if (typeof MessageChannel === 'undefined') {
warningWithoutStack(
console.error(
'This browser does not have a MessageChannel implementation, ' +
'so enqueuing tasks via await act(async () => ...) will fail. ' +
'Please file an issue at https://github.com/facebook/react/issues ' +
Expand Down
13 changes: 0 additions & 13 deletions packages/shared/forks/lowPriorityWarningWithoutStack.www.js

This file was deleted.

13 changes: 0 additions & 13 deletions packages/shared/forks/warningWithoutStack.www.js

This file was deleted.

43 changes: 0 additions & 43 deletions packages/shared/lowPriorityWarning.js

This file was deleted.

0 comments on commit f8febfe

Please sign in to comment.