From 0cf22a56a18790ef34c71bef14f64695c0498619 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sat, 14 Dec 2019 18:09:25 +0000 Subject: [PATCH] Use console directly instead of warning() modules (#17599) * Replace all warning/lowPriWarning with console calls * Replace console.warn/error with a custom wrapper at build time * Fail the build for console.error/warn() where we can't read the stack --- .eslintrc.js | 15 ++- .../src/createSubscription.js | 5 +- packages/legacy-events/EventPluginUtils.js | 5 +- packages/legacy-events/EventPropagators.js | 3 +- .../legacy-events/ResponderEventPlugin.js | 8 +- .../ResponderTouchHistoryStore.js | 35 +++--- packages/legacy-events/SyntheticEvent.js | 3 +- packages/react-cache/src/ReactCache.js | 3 +- packages/react-dom/src/client/ReactDOM.js | 7 +- .../react-dom/src/client/ReactDOMComponent.js | 29 +++-- .../react-dom/src/client/ReactDOMInput.js | 9 +- .../react-dom/src/client/ReactDOMLegacy.js | 24 ++-- .../react-dom/src/client/ReactDOMOption.js | 5 +- packages/react-dom/src/client/ReactDOMRoot.js | 7 +- .../react-dom/src/client/ReactDOMSelect.js | 7 +- .../react-dom/src/client/ReactDOMTextarea.js | 5 +- packages/react-dom/src/client/setInnerHTML.js | 3 +- .../src/client/validateDOMNesting.js | 7 +- .../src/events/DOMEventResponderSystem.js | 3 +- .../react-dom/src/events/SimpleEventPlugin.js | 3 +- .../src/server/ReactPartialRenderer.js | 42 +++---- .../src/server/ReactPartialRendererContext.js | 7 +- .../src/server/ReactPartialRendererHooks.js | 11 +- .../src/shared/CSSPropertyOperations.js | 3 +- packages/react-dom/src/shared/DOMProperty.js | 3 +- .../src/shared/ReactDOMInvalidARIAHook.js | 12 +- .../shared/ReactDOMNullInputValuePropHook.js | 6 +- .../src/shared/ReactDOMUnknownPropertyHook.js | 31 +++-- .../react-dom/src/shared/assertValidProps.js | 3 +- packages/react-dom/src/shared/sanitizeURL.js | 3 +- .../react-dom/src/shared/warnValidStyle.js | 15 +-- .../src/test-utils/ReactTestUtils.js | 3 +- .../src/test-utils/ReactTestUtilsAct.js | 10 +- .../events/src/dom/Press.js | 5 +- .../events/src/dom/PressLegacy.js | 3 +- .../src/dom/testing-library/domEnvironment.js | 4 +- packages/react-is/src/ReactIs.js | 4 +- .../src/NativeMethodsMixin.js | 8 +- .../src/NativeMethodsMixinUtils.js | 24 ++-- .../react-native-renderer/src/ReactFabric.js | 7 +- .../src/ReactFabricEventResponderSystem.js | 3 +- .../src/ReactFabricHostConfig.js | 7 +- .../src/ReactNativeComponent.js | 8 +- .../src/ReactNativeEventEmitter.js | 5 +- .../src/ReactNativeFiberHostComponent.js | 4 +- .../src/ReactNativeRenderer.js | 7 +- .../src/createReactNoop.js | 12 +- .../react-reconciler/src/ReactChildFiber.js | 15 ++- packages/react-reconciler/src/ReactFiber.js | 3 +- .../src/ReactFiberBeginWork.js | 43 ++++--- .../src/ReactFiberClassComponent.js | 67 ++++++----- .../src/ReactFiberCommitWork.js | 25 ++-- .../react-reconciler/src/ReactFiberContext.js | 3 +- .../src/ReactFiberDevToolsHook.js | 20 +++- .../src/ReactFiberErrorLogger.js | 6 +- .../react-reconciler/src/ReactFiberEvents.js | 3 +- .../react-reconciler/src/ReactFiberHooks.js | 21 ++-- .../src/ReactFiberHydrationContext.js | 3 +- .../src/ReactFiberNewContext.js | 9 +- .../src/ReactFiberReconciler.js | 9 +- .../react-reconciler/src/ReactFiberStack.js | 10 +- .../react-reconciler/src/ReactFiberThrow.js | 3 +- .../src/ReactFiberTreeReflection.js | 3 +- .../src/ReactFiberWorkLoop.js | 23 ++-- .../src/ReactStrictModeWarnings.js | 18 ++- .../react-reconciler/src/ReactUpdateQueue.js | 3 +- .../src/ReactShallowRenderer.js | 5 +- .../src/ReactTestHostConfig.js | 6 +- .../src/ReactTestRendererAct.js | 10 +- packages/react/src/ReactBaseClasses.js | 3 +- packages/react/src/ReactChildren.js | 3 +- packages/react/src/ReactContext.js | 8 +- packages/react/src/ReactElement.js | 5 +- packages/react/src/ReactElementValidator.js | 22 ++-- packages/react/src/ReactHooks.js | 9 +- packages/react/src/ReactLazy.js | 5 +- packages/react/src/ReactNoopUpdateQueue.js | 4 +- packages/react/src/forwardRef.js | 10 +- packages/react/src/memo.js | 3 +- packages/scheduler/src/SchedulerProfiling.js | 3 +- .../src/forks/SchedulerHostConfig.default.js | 9 +- packages/shared/ReactLazyComponent.js | 4 +- packages/shared/consoleWithStackDev.js | 63 ++++++++++ packages/shared/enqueueTask.js | 4 +- .../shared/forks/consoleWithStackDev.www.js | 22 ++++ .../lowPriorityWarningWithoutStack.www.js | 13 -- .../shared/forks/warningWithoutStack.www.js | 13 -- packages/shared/getComponentName.js | 3 +- packages/shared/lowPriorityWarning.js | 43 ------- .../shared/lowPriorityWarningWithoutStack.js | 51 -------- packages/shared/warning.js | 43 ------- packages/shared/warningWithoutStack.js | 50 -------- .../babel/transform-replace-console-calls.js | 82 +++++++++++++ .../no-production-logging-test.internal.js | 111 ++++++++++-------- .../__tests__/warning-args-test.internal.js | 39 +++--- scripts/eslint-rules/no-production-logging.js | 45 ++++--- scripts/eslint-rules/warning-args.js | 22 ++-- scripts/jest/preprocessor.js | 21 ++-- scripts/print-warnings/print-warnings.js | 17 +-- scripts/rollup/build.js | 31 ++++- scripts/rollup/forks.js | 23 +--- scripts/shared/evalToString.js | 1 + 102 files changed, 753 insertions(+), 776 deletions(-) create mode 100644 packages/shared/consoleWithStackDev.js create mode 100644 packages/shared/forks/consoleWithStackDev.www.js delete mode 100644 packages/shared/forks/lowPriorityWarningWithoutStack.www.js delete mode 100644 packages/shared/forks/warningWithoutStack.www.js delete mode 100644 packages/shared/lowPriorityWarning.js delete mode 100644 packages/shared/lowPriorityWarningWithoutStack.js delete mode 100644 packages/shared/warning.js delete mode 100644 packages/shared/warningWithoutStack.js create mode 100644 scripts/babel/transform-replace-console-calls.js diff --git a/.eslintrc.js b/.eslintrc.js index fd7aec7db8bd..82115d52504e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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, @@ -135,6 +136,18 @@ module.exports = { 'jest/valid-expect-in-promise': ERROR, }, }, + { + files: [ + '**/__tests__/**/*.js', + 'scripts/**/*.js', + 'packages/*/npm/**/*.js', + 'packages/react-devtools*/**/*.js' + ], + rules: { + 'react-internal/no-production-logging': OFF, + 'react-internal/warning-args': OFF, + }, + }, { files: ['packages/react-native-renderer/**/*.js'], globals: { diff --git a/packages/create-subscription/src/createSubscription.js b/packages/create-subscription/src/createSubscription.js index 0403762a059b..88143bc2f97b 100644 --- a/packages/create-subscription/src/createSubscription.js +++ b/packages/create-subscription/src/createSubscription.js @@ -9,7 +9,6 @@ import React from 'react'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; type Unsubscribe = () => void; @@ -38,10 +37,10 @@ export function createSubscription( if (__DEV__) { if (typeof getCurrentValue !== 'function') { - warning('Subscription must specify a getCurrentValue function'); + console.error('Subscription must specify a getCurrentValue function'); } if (typeof subscribe !== 'function') { - warning('Subscription must specify a subscribe function'); + console.error('Subscription must specify a subscribe function'); } } diff --git a/packages/legacy-events/EventPluginUtils.js b/packages/legacy-events/EventPluginUtils.js index ac78119b8d0b..bdc5f237d860 100644 --- a/packages/legacy-events/EventPluginUtils.js +++ b/packages/legacy-events/EventPluginUtils.js @@ -7,7 +7,6 @@ import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; export let getFiberCurrentPropsFromNode = null; export let getInstanceFromNode = null; @@ -23,7 +22,7 @@ export function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; if (__DEV__) { if (!getNodeFromInstance || !getInstanceFromNode) { - warning( + console.error( 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.', ); @@ -52,7 +51,7 @@ if (__DEV__) { : 0; if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { - warning('EventPluginUtils: Invalid `event`.'); + console.error('EventPluginUtils: Invalid `event`.'); } }; } diff --git a/packages/legacy-events/EventPropagators.js b/packages/legacy-events/EventPropagators.js index 02069849bb22..dfaacdab4ddf 100644 --- a/packages/legacy-events/EventPropagators.js +++ b/packages/legacy-events/EventPropagators.js @@ -10,7 +10,6 @@ import { traverseTwoPhase, traverseEnterLeave, } from 'shared/ReactTreeTraversal'; -import warning from 'shared/warning'; import {getListener} from './EventPluginHub'; import accumulateInto from './accumulateInto'; @@ -47,7 +46,7 @@ function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) { function accumulateDirectionalDispatches(inst, phase, event) { if (__DEV__) { if (!inst) { - warning('Dispatching inst must not be null'); + console.error('Dispatching inst must not be null'); } } const listener = listenerAtPhase(inst, event, phase); diff --git a/packages/legacy-events/ResponderEventPlugin.js b/packages/legacy-events/ResponderEventPlugin.js index f58323aa9a8b..ff736b8aeac0 100644 --- a/packages/legacy-events/ResponderEventPlugin.js +++ b/packages/legacy-events/ResponderEventPlugin.js @@ -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; } } diff --git a/packages/legacy-events/ResponderTouchHistoryStore.js b/packages/legacy-events/ResponderTouchHistoryStore.js index a892aeb324f9..1706f9af17fa 100644 --- a/packages/legacy-events/ResponderTouchHistoryStore.js +++ b/packages/legacy-events/ResponderTouchHistoryStore.js @@ -8,7 +8,6 @@ */ import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {isStartish, isMoveish, isEndish} from './ResponderTopLevelEventTypes'; @@ -96,7 +95,7 @@ function getTouchIdentifier({identifier}: Touch): number { invariant(identifier != null, 'Touch object is missing identifier.'); if (__DEV__) { if (identifier > MAX_TOUCH_BANK) { - warning( + console.error( 'Touch identifier %s is greater than maximum supported %s which causes ' + 'performance issues backfilling array locations for all of the indices.', identifier, @@ -130,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(), + ); + } } } @@ -151,12 +153,15 @@ 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(), + ); + } } } @@ -202,7 +207,7 @@ const ResponderTouchHistoryStore = { if (__DEV__) { const activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; if (activeRecord == null || !activeRecord.touchActive) { - warning('Cannot find single active touch.'); + console.error('Cannot find single active touch.'); } } } diff --git a/packages/legacy-events/SyntheticEvent.js b/packages/legacy-events/SyntheticEvent.js index 840da2e109c1..ca7a5cf4074f 100644 --- a/packages/legacy-events/SyntheticEvent.js +++ b/packages/legacy-events/SyntheticEvent.js @@ -8,7 +8,6 @@ /* eslint valid-typeof: 0 */ import invariant from 'shared/invariant'; -import warning from 'shared/warning'; const EVENT_POOL_SIZE = 10; @@ -284,7 +283,7 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function warn(action, result) { if (__DEV__) { - warning( + console.error( "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + diff --git a/packages/react-cache/src/ReactCache.js b/packages/react-cache/src/ReactCache.js index 242bc7d32a7b..203e2c339570 100644 --- a/packages/react-cache/src/ReactCache.js +++ b/packages/react-cache/src/ReactCache.js @@ -8,7 +8,6 @@ */ import React from 'react'; -import warning from 'shared/warning'; import {createLRU} from './LRU'; @@ -71,7 +70,7 @@ function identityHashFn(input) { input !== undefined && input !== null ) { - warning( + console.error( 'Invalid key type. Expected a string, number, symbol, or boolean, ' + 'but instead received: %s' + '\n\nTo use non-primitive values as keys, you must pass a hash ' + diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 759d87e3bc7d..818d0eef3a94 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -53,8 +53,6 @@ import { } from 'legacy-events/EventPropagators'; import ReactVersion from 'shared/ReactVersion'; import invariant from 'shared/invariant'; -import lowPriorityWarning from 'shared/lowPriorityWarning'; -import warning from 'shared/warning'; import {exposeConcurrentModeAPIs} from 'shared/ReactFeatureFlags'; import { @@ -92,7 +90,7 @@ if (__DEV__) { typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function' ) { - warning( + console.error( 'React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills', ); @@ -144,7 +142,7 @@ const ReactDOM: Object = { if (__DEV__) { if (!didWarnAboutUnstableCreatePortal) { didWarnAboutUnstableCreatePortal = true; - lowPriorityWarning( + console.warn( 'The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + @@ -213,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: ' + diff --git a/packages/react-dom/src/client/ReactDOMComponent.js b/packages/react-dom/src/client/ReactDOMComponent.js index 8f3448162bba..309ceb4514a3 100644 --- a/packages/react-dom/src/client/ReactDOMComponent.js +++ b/packages/react-dom/src/client/ReactDOMComponent.js @@ -11,7 +11,6 @@ import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber'; import {registrationNameModules} from 'legacy-events/EventPluginRegistry'; import {canUseDOM} from 'shared/ExecutionEnvironment'; -import warning from 'shared/warning'; import endsWith from 'shared/endsWith'; import {setListenToResponderEventTypes} from '../events/DOMEventResponderSystem'; @@ -183,7 +182,7 @@ if (__DEV__) { return; } didWarnInvalidHydration = true; - warning( + console.error( 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText, @@ -208,7 +207,7 @@ if (__DEV__) { return; } didWarnInvalidHydration = true; - warning( + console.error( 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), @@ -225,12 +224,12 @@ if (__DEV__) { attributeNames.forEach(function(name) { names.push(name); }); - warning('Extra attributes from the server: %s', names); + console.error('Extra attributes from the server: %s', names); }; warnForInvalidEventListener = function(registrationName, listener) { if (listener === false) { - warning( + console.error( 'Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', @@ -239,7 +238,7 @@ if (__DEV__) { registrationName, ); } else { - warning( + console.error( 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener, @@ -412,7 +411,7 @@ export function createElement( // Should this check be gated by parent namespace? Not sure we want to // allow or . if (!isCustomComponentTag && type !== type.toLowerCase()) { - warning( + console.error( '<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', @@ -427,7 +426,7 @@ export function createElement( const div = ownerDocument.createElement('div'); if (__DEV__) { if (enableTrustedTypesIntegration && !didWarnScriptTags) { - warning( + console.error( 'Encountered a script tag while rendering React component. ' + 'Scripts inside React components are never executed when rendering ' + 'on the client. Consider using template tag instead ' + @@ -482,7 +481,7 @@ export function createElement( !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type) ) { warnedUnknownTags[type] = true; - warning( + console.error( 'The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', @@ -518,7 +517,7 @@ export function setInitialProperties( !didWarnShadyDOM && (domElement: any).shadyRoot ) { - warning( + console.error( '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component', @@ -918,7 +917,7 @@ export function diffHydratedProperties( !didWarnShadyDOM && (domElement: any).shadyRoot ) { - warning( + console.error( '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component', @@ -1210,7 +1209,7 @@ export function warnForDeletedHydratableElement( return; } didWarnInvalidHydration = true; - warning( + console.error( 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase(), @@ -1227,7 +1226,7 @@ export function warnForDeletedHydratableText( return; } didWarnInvalidHydration = true; - warning( + console.error( 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase(), @@ -1245,7 +1244,7 @@ export function warnForInsertedHydratedElement( return; } didWarnInvalidHydration = true; - warning( + console.error( 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase(), @@ -1269,7 +1268,7 @@ export function warnForInsertedHydratedText( return; } didWarnInvalidHydration = true; - warning( + console.error( 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase(), diff --git a/packages/react-dom/src/client/ReactDOMInput.js b/packages/react-dom/src/client/ReactDOMInput.js index d274189db520..0f5d61b8dc42 100644 --- a/packages/react-dom/src/client/ReactDOMInput.js +++ b/packages/react-dom/src/client/ReactDOMInput.js @@ -10,7 +10,6 @@ // TODO: direct imports like some-package/src/* are bad. Fix me. import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {setValueForProperty} from './DOMPropertyOperations'; import {getFiberCurrentPropsFromNode} from './ReactDOMComponentTree'; @@ -79,7 +78,7 @@ export function initWrapperState(element: Element, props: Object) { props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked ) { - warning( + console.error( '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + @@ -96,7 +95,7 @@ export function initWrapperState(element: Element, props: Object) { props.defaultValue !== undefined && !didWarnValueDefaultValue ) { - warning( + console.error( '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + @@ -141,7 +140,7 @@ export function updateWrapper(element: Element, props: Object) { controlled && !didWarnUncontrolledToControlled ) { - warning( + console.error( 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + @@ -155,7 +154,7 @@ export function updateWrapper(element: Element, props: Object) { !controlled && !didWarnControlledToUncontrolled ) { - warning( + console.error( 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + diff --git a/packages/react-dom/src/client/ReactDOMLegacy.js b/packages/react-dom/src/client/ReactDOMLegacy.js index 27d78788d48d..aca2a7a7adbf 100644 --- a/packages/react-dom/src/client/ReactDOMLegacy.js +++ b/packages/react-dom/src/client/ReactDOMLegacy.js @@ -38,8 +38,6 @@ import { } from 'react-reconciler/inline.dom'; import getComponentName from 'shared/getComponentName'; import invariant from 'shared/invariant'; -import lowPriorityWarning from 'shared/lowPriorityWarning'; -import warning from 'shared/warning'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import {has as hasInstance} from 'shared/ReactInstanceMap'; @@ -56,7 +54,7 @@ if (__DEV__) { ); if (hostInstance) { if (hostInstance.parentNode !== container) { - warning( + console.error( 'render(...): It looks like the React-rendered content of this ' + 'container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + @@ -71,7 +69,7 @@ if (__DEV__) { const hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl)); if (hasNonRootReactChild && !isRootRenderedBySomeReact) { - warning( + console.error( 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + @@ -84,7 +82,7 @@ if (__DEV__) { ((container: any): Element).tagName && ((container: any): Element).tagName.toUpperCase() === 'BODY' ) { - warning( + console.error( 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + @@ -134,7 +132,7 @@ function legacyCreateRootFromDOMContainer( (rootSibling: any).hasAttribute(ROOT_ATTRIBUTE_NAME) ) { warned = true; - warning( + console.error( 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.', @@ -147,7 +145,7 @@ function legacyCreateRootFromDOMContainer( if (__DEV__) { if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) { warnedAboutHydrateAPI = true; - lowPriorityWarning( + console.warn( 'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v17. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.', @@ -222,7 +220,7 @@ export function findDOMNode( if (owner !== null && owner.stateNode !== null) { const warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender; if (!warnedAboutRefsInRender) { - warning( + console.error( '%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + @@ -260,7 +258,7 @@ export function hydrate( isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; if (isModernRoot) { - warning( + console.error( 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?', @@ -291,7 +289,7 @@ export function render( isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; if (isModernRoot) { - warning( + console.error( 'You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?', @@ -341,7 +339,7 @@ export function unmountComponentAtNode(container: DOMContainer) { isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; if (isModernRoot) { - warning( + console.error( 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?', ); @@ -353,7 +351,7 @@ export function unmountComponentAtNode(container: DOMContainer) { const rootEl = getReactRootElementInContainer(container); const renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl); if (renderedByDifferentReact) { - warning( + console.error( "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.', ); @@ -382,7 +380,7 @@ export function unmountComponentAtNode(container: DOMContainer) { !!container.parentNode._reactRootContainer; if (hasNonRootReactChild) { - warning( + console.error( "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot diff --git a/packages/react-dom/src/client/ReactDOMOption.js b/packages/react-dom/src/client/ReactDOMOption.js index 5900bc348883..d18813cfa445 100644 --- a/packages/react-dom/src/client/ReactDOMOption.js +++ b/packages/react-dom/src/client/ReactDOMOption.js @@ -8,7 +8,6 @@ */ import React from 'react'; -import warning from 'shared/warning'; import {getToStringValue, toString} from './ToStringValue'; let didWarnSelectedSetOnOption = false; @@ -58,7 +57,7 @@ export function validateProps(element: Element, props: Object) { } if (!didWarnInvalidChild) { didWarnInvalidChild = true; - warning( + console.error( 'Only strings and numbers are supported as = (S => S) | S; @@ -72,7 +71,7 @@ function resolveCurrentlyRenderingComponent(): Object { ); if (__DEV__) { if (isInHookUserCodeInDev) { - warning( + console.error( 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + @@ -89,7 +88,7 @@ function areHookInputsEqual( ) { if (prevDeps === null) { if (__DEV__) { - warning( + console.error( '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', @@ -103,7 +102,7 @@ function areHookInputsEqual( // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning( + console.error( 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + @@ -223,7 +222,7 @@ function readContext( validateContextBounds(context, threadID); if (__DEV__) { if (isInHookUserCodeInDev) { - warning( + console.error( 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + @@ -392,7 +391,7 @@ export function useLayoutEffect( ) { if (__DEV__) { currentHookNameInDev = 'useLayoutEffect'; - warning( + console.error( 'useLayoutEffect does nothing on the server, because its effect cannot ' + "be encoded into the server renderer's output format. This will lead " + 'to a mismatch between the initial, non-hydrated UI and the intended ' + diff --git a/packages/react-dom/src/shared/CSSPropertyOperations.js b/packages/react-dom/src/shared/CSSPropertyOperations.js index 5f30464d1893..f307510813cc 100644 --- a/packages/react-dom/src/shared/CSSPropertyOperations.js +++ b/packages/react-dom/src/shared/CSSPropertyOperations.js @@ -10,7 +10,6 @@ import {shorthandToLonghand} from './CSSShorthandProperty'; import dangerousStyleValue from './dangerousStyleValue'; import hyphenateStyleName from './hyphenateStyleName'; import warnValidStyle from './warnValidStyle'; -import warning from 'shared/warning'; import {warnAboutShorthandPropertyCollision} from 'shared/ReactFeatureFlags'; @@ -149,7 +148,7 @@ export function validateShorthandPropertyCollisionInDev( continue; } warnedAbout[warningKey] = true; - warning( + console.error( '%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + diff --git a/packages/react-dom/src/shared/DOMProperty.js b/packages/react-dom/src/shared/DOMProperty.js index 6d744a78bab3..279d438fa7d7 100644 --- a/packages/react-dom/src/shared/DOMProperty.js +++ b/packages/react-dom/src/shared/DOMProperty.js @@ -7,7 +7,6 @@ * @flow */ -import warning from 'shared/warning'; import {enableFlareAPI} from 'shared/ReactFeatureFlags'; type PropertyType = 0 | 1 | 2 | 3 | 4 | 5 | 6; @@ -85,7 +84,7 @@ export function isAttributeNameSafe(attributeName: string): boolean { } illegalAttributeNameCache[attributeName] = true; if (__DEV__) { - warning('Invalid attribute name: `%s`', attributeName); + console.error('Invalid attribute name: `%s`', attributeName); } return false; } diff --git a/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js b/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js index a6747f39452a..cceea9758c57 100644 --- a/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js +++ b/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import warning from 'shared/warning'; - import {ATTRIBUTE_NAME_CHAR} from './DOMProperty'; import isCustomComponent from './isCustomComponent'; import validAriaProperties from './validAriaProperties'; @@ -32,7 +30,7 @@ function validateProperty(tagName, name) { // If this is an aria-* attribute, but is not listed in the known DOM // DOM properties, then it is an invalid aria-* attribute. if (correctName == null) { - warning( + console.error( 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name, ); @@ -41,7 +39,7 @@ function validateProperty(tagName, name) { } // aria-* attributes should be lowercase; suggest the lowercase version. if (name !== correctName) { - warning( + console.error( 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName, @@ -65,7 +63,7 @@ function validateProperty(tagName, name) { } // aria-* attributes should be lowercase; suggest the lowercase version. if (name !== standardName) { - warning( + console.error( 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName, @@ -95,14 +93,14 @@ function warnInvalidARIAProps(type, props) { .join(', '); if (invalidProps.length === 1) { - warning( + console.error( 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type, ); } else if (invalidProps.length > 1) { - warning( + console.error( 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, diff --git a/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js b/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js index 26c64cc8f908..20879a4c7974 100644 --- a/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js +++ b/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import warning from 'shared/warning'; - let didWarnValueNull = false; export function validateProperties(type, props) { @@ -18,14 +16,14 @@ export function validateProperties(type, props) { if (props != null && props.value === null && !didWarnValueNull) { didWarnValueNull = true; if (type === 'select' && props.multiple) { - warning( + console.error( '`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type, ); } else { - warning( + console.error( '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', diff --git a/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js b/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js index bbb5a88a73f9..fd0f71dacb82 100644 --- a/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js +++ b/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js @@ -9,7 +9,6 @@ import { registrationNameModules, possibleRegistrationNames, } from 'legacy-events/EventPluginRegistry'; -import warning from 'shared/warning'; import { ATTRIBUTE_NAME_CHAR, @@ -38,7 +37,7 @@ if (__DEV__) { const lowerCasedName = name.toLowerCase(); if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { - warning( + console.error( 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.', @@ -58,7 +57,7 @@ if (__DEV__) { ? possibleRegistrationNames[lowerCasedName] : null; if (registrationName != null) { - warning( + console.error( 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName, @@ -67,7 +66,7 @@ if (__DEV__) { return true; } if (EVENT_NAME_REGEX.test(name)) { - warning( + console.error( 'Unknown event handler property `%s`. It will be ignored.', name, ); @@ -79,7 +78,7 @@ if (__DEV__) { // So we can't tell if the event name is correct for sure, but we can filter // out known bad ones like `onclick`. We can't suggest a specific replacement though. if (INVALID_EVENT_NAME_REGEX.test(name)) { - warning( + console.error( 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name, @@ -95,7 +94,7 @@ if (__DEV__) { } if (lowerCasedName === 'innerhtml') { - warning( + console.error( 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.', ); @@ -104,7 +103,7 @@ if (__DEV__) { } if (lowerCasedName === 'aria') { - warning( + console.error( 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.', ); @@ -118,7 +117,7 @@ if (__DEV__) { value !== undefined && typeof value !== 'string' ) { - warning( + console.error( 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value, @@ -128,7 +127,7 @@ if (__DEV__) { } if (typeof value === 'number' && isNaN(value)) { - warning( + console.error( 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name, @@ -144,7 +143,7 @@ if (__DEV__) { if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { const standardName = possibleStandardNames[lowerCasedName]; if (standardName !== name) { - warning( + console.error( 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName, @@ -155,7 +154,7 @@ if (__DEV__) { } else if (!isReserved && name !== lowerCasedName) { // Unknown attributes should have lowercase casing since that's how they // will be cased anyway with server rendering. - warning( + console.error( 'React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + @@ -173,7 +172,7 @@ if (__DEV__) { shouldRemoveAttributeWithWarning(name, value, propertyInfo, false) ) { if (value) { - warning( + console.error( 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', @@ -184,7 +183,7 @@ if (__DEV__) { name, ); } else { - warning( + console.error( 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + @@ -221,7 +220,7 @@ if (__DEV__) { propertyInfo !== null && propertyInfo.type === BOOLEAN ) { - warning( + console.error( 'Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', @@ -260,7 +259,7 @@ const warnUnknownProperties = function(type, props, canUseEventSystem) { .map(prop => '`' + prop + '`') .join(', '); if (unknownProps.length === 1) { - warning( + console.error( 'Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', @@ -268,7 +267,7 @@ const warnUnknownProperties = function(type, props, canUseEventSystem) { type, ); } else if (unknownProps.length > 1) { - warning( + console.error( 'Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', diff --git a/packages/react-dom/src/shared/assertValidProps.js b/packages/react-dom/src/shared/assertValidProps.js index bb7f84599cc9..52a1b5b47ff8 100644 --- a/packages/react-dom/src/shared/assertValidProps.js +++ b/packages/react-dom/src/shared/assertValidProps.js @@ -6,7 +6,6 @@ */ import invariant from 'shared/invariant'; -import warning from 'shared/warning'; // TODO: We can remove this if we add invariantWithStack() // or add stack by default to invariants where possible. import ReactSharedInternals from 'shared/ReactSharedInternals'; @@ -53,7 +52,7 @@ function assertValidProps(tag: string, props: ?Object) { props.contentEditable && props.children != null ) { - warning( + console.error( 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + diff --git a/packages/react-dom/src/shared/sanitizeURL.js b/packages/react-dom/src/shared/sanitizeURL.js index c33e61ce8a6a..a34ba87bbbcf 100644 --- a/packages/react-dom/src/shared/sanitizeURL.js +++ b/packages/react-dom/src/shared/sanitizeURL.js @@ -8,7 +8,6 @@ */ import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import {disableJavaScriptURLs} from 'shared/ReactFeatureFlags'; @@ -41,7 +40,7 @@ function sanitizeURL(url: string) { } else if (__DEV__) { if (!didWarn && isJavaScriptProtocol.test(url)) { didWarn = true; - warning( + console.error( 'A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', diff --git a/packages/react-dom/src/shared/warnValidStyle.js b/packages/react-dom/src/shared/warnValidStyle.js index f9cb12dc0b5c..648e51cf3c26 100644 --- a/packages/react-dom/src/shared/warnValidStyle.js +++ b/packages/react-dom/src/shared/warnValidStyle.js @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import warning from 'shared/warning'; - let warnValidStyle = () => {}; if (__DEV__) { @@ -35,7 +33,7 @@ if (__DEV__) { } warnedStyleNames[name] = true; - warning( + console.error( 'Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests @@ -51,7 +49,7 @@ if (__DEV__) { } warnedStyleNames[name] = true; - warning( + console.error( 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1), @@ -64,7 +62,7 @@ if (__DEV__) { } warnedStyleValues[value] = true; - warning( + console.error( "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, @@ -78,7 +76,10 @@ if (__DEV__) { } warnedForNaNValue = true; - warning('`NaN` is an invalid value for the `%s` css style property.', name); + console.error( + '`NaN` is an invalid value for the `%s` css style property.', + name, + ); }; const warnStyleValueIsInfinity = function(name, value) { @@ -87,7 +88,7 @@ if (__DEV__) { } warnedForInfinityValue = true; - warning( + console.error( '`Infinity` is an invalid value for the `%s` css style property.', name, ); diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js index 55b203447312..23e99cd15ae4 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtils.js +++ b/packages/react-dom/src/test-utils/ReactTestUtils.js @@ -17,7 +17,6 @@ import { } from 'shared/ReactWorkTags'; import SyntheticEvent from 'legacy-events/SyntheticEvent'; import invariant from 'shared/invariant'; -import lowPriorityWarning from 'shared/lowPriorityWarning'; import {ELEMENT_NODE} from '../shared/HTMLNodeType'; import * as DOMTopLevelEventTypes from '../events/DOMTopLevelEventTypes'; import {PLUGIN_EVENT_SYSTEM} from 'legacy-events/EventSystemFlags'; @@ -362,7 +361,7 @@ const ReactTestUtils = { if (__DEV__) { if (!hasWarnedAboutDeprecatedMockComponent) { hasWarnedAboutDeprecatedMockComponent = true; - lowPriorityWarning( + console.warn( 'ReactTestUtils.mockComponent() is deprecated. ' + 'Use shallow rendering or jest.mock() instead.\n\n' + 'See https://fb.me/test-utils-mock-component for more information.', diff --git a/packages/react-dom/src/test-utils/ReactTestUtilsAct.js b/packages/react-dom/src/test-utils/ReactTestUtilsAct.js index ce72da89dac0..7aa5b916820d 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtilsAct.js +++ b/packages/react-dom/src/test-utils/ReactTestUtilsAct.js @@ -9,7 +9,6 @@ import type {Thenable} from 'react-reconciler/src/ReactFiberWorkLoop'; -import warning from 'shared/warning'; import ReactDOM from 'react-dom'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import enqueueTask from 'shared/enqueueTask'; @@ -80,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.', ); @@ -102,7 +102,7 @@ function act(callback: () => Thenable) { if (__DEV__) { if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) { // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned - warning( + console.error( 'You seem to have overlapping act() calls, this is not supported. ' + 'Be sure to await previous act() calls before making a new one. ', ); @@ -134,7 +134,7 @@ function act(callback: () => Thenable) { .then(() => {}) .then(() => { if (called === false) { - warning( + console.error( 'You called act(async () => ...) without await. ' + 'This could lead to unexpected testing behaviour, interleaving multiple act ' + 'calls and mixing their scopes. You should - await act(async () => ...);', @@ -182,7 +182,7 @@ function act(callback: () => Thenable) { } else { if (__DEV__) { if (result !== undefined) { - warning( + console.error( 'The callback passed to act(...) function ' + 'must return undefined, or a Promise. You returned %s', result, @@ -210,7 +210,7 @@ function act(callback: () => Thenable) { return { then(resolve: () => void) { if (__DEV__) { - warning( + console.error( 'Do not await the result of calling act(...) with sync logic, it is not a Promise.', ); } diff --git a/packages/react-interactions/events/src/dom/Press.js b/packages/react-interactions/events/src/dom/Press.js index 048703de3d83..574ca806832a 100644 --- a/packages/react-interactions/events/src/dom/Press.js +++ b/packages/react-interactions/events/src/dom/Press.js @@ -12,7 +12,6 @@ import type {PointerType} from 'shared/ReactDOMTypes'; import React from 'react'; import {useTap} from 'react-interactions/events/tap'; import {useKeyboard} from 'react-interactions/events/keyboard'; -import warning from 'shared/warning'; const emptyObject = {}; @@ -73,7 +72,7 @@ function createGestureState(e: any, type: PressEventType): PressEvent { preventDefault() { // NO-OP, we should remove this in the future if (__DEV__) { - warning( + console.error( 'preventDefault is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.preventDefault() }`', ); @@ -82,7 +81,7 @@ function createGestureState(e: any, type: PressEventType): PressEvent { stopPropagation() { // NO-OP, we should remove this in the future if (__DEV__) { - warning( + console.error( 'stopPropagation is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.stopPropagation() }`', ); diff --git a/packages/react-interactions/events/src/dom/PressLegacy.js b/packages/react-interactions/events/src/dom/PressLegacy.js index 0a8089f23bd3..7627fbd92328 100644 --- a/packages/react-interactions/events/src/dom/PressLegacy.js +++ b/packages/react-interactions/events/src/dom/PressLegacy.js @@ -19,7 +19,6 @@ import type { import React from 'react'; import {DiscreteEvent, UserBlockingEvent} from 'shared/ReactTypes'; -import warning from 'shared/warning'; type PressProps = {| disabled: boolean, @@ -206,7 +205,7 @@ function createPressEvent( stopPropagation() { // NO-OP, we should remove this in the future if (__DEV__) { - warning( + console.error( 'stopPropagation is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.stopPropagation() }`', ); diff --git a/packages/react-interactions/events/src/dom/testing-library/domEnvironment.js b/packages/react-interactions/events/src/dom/testing-library/domEnvironment.js index 5042f3e81eee..2c87c783e7cc 100644 --- a/packages/react-interactions/events/src/dom/testing-library/domEnvironment.js +++ b/packages/react-interactions/events/src/dom/testing-library/domEnvironment.js @@ -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 "%s"', name); + } } }; global.PointerEvent = bool ? emptyFunction : undefined; diff --git a/packages/react-is/src/ReactIs.js b/packages/react-is/src/ReactIs.js index b6ee4f592e7e..0ca1ddc91b9f 100644 --- a/packages/react-is/src/ReactIs.js +++ b/packages/react-is/src/ReactIs.js @@ -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) { @@ -88,7 +87,8 @@ export function isAsyncMode(object: any) { if (__DEV__) { if (!hasWarnedAboutDeprecatedIsAsyncMode) { hasWarnedAboutDeprecatedIsAsyncMode = true; - lowPriorityWarningWithoutStack( + // Using console['warn'] to evade Babel and ESLint + 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.', diff --git a/packages/react-native-renderer/src/NativeMethodsMixin.js b/packages/react-native-renderer/src/NativeMethodsMixin.js index af34be73d9b0..4c15f4925865 100644 --- a/packages/react-native-renderer/src/NativeMethodsMixin.js +++ b/packages/react-native-renderer/src/NativeMethodsMixin.js @@ -29,8 +29,6 @@ import { warnForStyleProps, } from './NativeMethodsMixinUtils'; -import warning from 'shared/warning'; - export default function( findNodeHandle: any => ?number, findHostInstance: any => any, @@ -180,7 +178,7 @@ export default function( if (maybeInstance.canonical) { if (__DEV__) { - warning( + console.error( 'Warning: measureLayout on components using NativeMethodsMixin ' + 'or ReactNative.NativeComponent is not currently supported in Fabric. ' + 'measureLayout must be called on a native ref. Consider using forwardRef.', @@ -199,7 +197,7 @@ export default function( if (relativeNode == null) { if (__DEV__) { - warning( + console.error( 'Warning: ref.measureLayout must be called with a node handle or a ref to a native component.', ); } @@ -246,7 +244,7 @@ export default function( if (maybeInstance.canonical) { if (__DEV__) { - warning( + console.error( 'Warning: setNativeProps is not currently supported in Fabric', ); } diff --git a/packages/react-native-renderer/src/NativeMethodsMixinUtils.js b/packages/react-native-renderer/src/NativeMethodsMixinUtils.js index 639b39c67db3..1f6611523fbd 100644 --- a/packages/react-native-renderer/src/NativeMethodsMixinUtils.js +++ b/packages/react-native-renderer/src/NativeMethodsMixinUtils.js @@ -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 `{ %s' + + ': ... }` as a prop. You ' + + 'should nest it in a style object. ' + + 'E.g. `{ style: { %s' + + ': ... } }`', + key, + key, + ); + } } } } diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index e108aba1afb0..fd9d06d5104f 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -37,7 +37,6 @@ import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; import {LegacyRoot} from 'shared/ReactRootTags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentName from 'shared/getComponentName'; -import warning from 'shared/warning'; const {dispatchCommand: fabricDispatchCommand} = nativeFabricUIManager; @@ -50,7 +49,7 @@ function findHostInstance_DEPRECATED( const owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { if (!owner.stateNode._warnedAboutRefsInRender) { - warning( + console.error( '%s is accessing findNodeHandle inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + @@ -97,7 +96,7 @@ function findNodeHandle(componentOrHandle: any): ?number { const owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { if (!owner.stateNode._warnedAboutRefsInRender) { - warning( + console.error( '%s is accessing findNodeHandle inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + @@ -169,7 +168,7 @@ const ReactFabric: ReactFabricType = { if (invalid) { if (__DEV__) { if (invalid) { - warning( + console.error( "dispatchCommand was called with a ref that isn't a " + 'native component. Use React.forwardRef to get access to the underlying native component', ); diff --git a/packages/react-native-renderer/src/ReactFabricEventResponderSystem.js b/packages/react-native-renderer/src/ReactFabricEventResponderSystem.js index bc793096a8f8..53854b01d088 100644 --- a/packages/react-native-renderer/src/ReactFabricEventResponderSystem.js +++ b/packages/react-native-renderer/src/ReactFabricEventResponderSystem.js @@ -31,7 +31,6 @@ import { UserBlockingEvent, DiscreteEvent, } from './ReactNativeTypes'; -import warning from 'shared/warning'; import invariant from 'shared/invariant'; // Intentionally not named imports because Rollup would use dynamic dispatch for @@ -179,7 +178,7 @@ function validateEventValue(eventValue: any): void { } const showWarning = name => { if (__DEV__) { - warning( + console.error( '%s is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', name, diff --git a/packages/react-native-renderer/src/ReactFabricHostConfig.js b/packages/react-native-renderer/src/ReactFabricHostConfig.js index 8a599fe462d4..3af03e5e2620 100644 --- a/packages/react-native-renderer/src/ReactFabricHostConfig.js +++ b/packages/react-native-renderer/src/ReactFabricHostConfig.js @@ -25,7 +25,6 @@ import {mountSafeCallback_NOT_REALLY_SAFE} from './NativeMethodsMixinUtils'; import {create, diff} from './ReactNativeAttributePayload'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {dispatchEvent} from './ReactFabricEventEmitter'; import { @@ -159,7 +158,7 @@ class ReactFabricHostComponent { !(relativeToNativeNode instanceof ReactFabricHostComponent) ) { if (__DEV__) { - warning( + console.error( 'Warning: ref.measureLayout must be called with a ref to a native component.', ); } @@ -177,7 +176,9 @@ class ReactFabricHostComponent { setNativeProps(nativeProps: Object) { if (__DEV__) { - warning('Warning: setNativeProps is not currently supported in Fabric'); + console.error( + 'Warning: setNativeProps is not currently supported in Fabric', + ); } return; diff --git a/packages/react-native-renderer/src/ReactNativeComponent.js b/packages/react-native-renderer/src/ReactNativeComponent.js index c7e44f26dc7f..795c666474a6 100644 --- a/packages/react-native-renderer/src/ReactNativeComponent.js +++ b/packages/react-native-renderer/src/ReactNativeComponent.js @@ -26,8 +26,6 @@ import { import {create} from './ReactNativeAttributePayload'; import {mountSafeCallback_NOT_REALLY_SAFE} from './NativeMethodsMixinUtils'; -import warning from 'shared/warning'; - export default function( findNodeHandle: any => ?number, findHostInstance: any => any, @@ -191,7 +189,7 @@ export default function( if (maybeInstance.canonical) { if (__DEV__) { - warning( + console.error( 'Warning: measureLayout on components using NativeMethodsMixin ' + 'or ReactNative.NativeComponent is not currently supported in Fabric. ' + 'measureLayout must be called on a native ref. Consider using forwardRef.', @@ -210,7 +208,7 @@ export default function( if (relativeNode == null) { if (__DEV__) { - warning( + console.error( 'Warning: ref.measureLayout must be called with a node handle or a ref to a native component.', ); } @@ -257,7 +255,7 @@ export default function( if (maybeInstance.canonical) { if (__DEV__) { - warning( + console.error( 'Warning: setNativeProps is not currently supported in Fabric', ); } diff --git a/packages/react-native-renderer/src/ReactNativeEventEmitter.js b/packages/react-native-renderer/src/ReactNativeEventEmitter.js index 32592c3e8026..07c62f83edd6 100644 --- a/packages/react-native-renderer/src/ReactNativeEventEmitter.js +++ b/packages/react-native-renderer/src/ReactNativeEventEmitter.js @@ -14,7 +14,6 @@ import { } from 'legacy-events/EventPluginHub'; import {registrationNameModules} from 'legacy-events/EventPluginRegistry'; import {batchedUpdates} from 'legacy-events/ReactGenericBatching'; -import warning from 'shared/warning'; import {enableNativeTargetAsInstance} from 'shared/ReactFeatureFlags'; import {getInstanceFromNode} from './ReactNativeComponentTree'; @@ -184,7 +183,9 @@ export function receiveTouches( if (target !== null && target !== undefined) { if (target < 1) { if (__DEV__) { - warning('A view is reporting that a touch occurred on tag zero.'); + console.error( + 'A view is reporting that a touch occurred on tag zero.', + ); } } else { rootNodeID = target; diff --git a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js index 8850f830bb7e..cad31637b4ea 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js +++ b/packages/react-native-renderer/src/ReactNativeFiberHostComponent.js @@ -28,8 +28,6 @@ import { warnForStyleProps, } from './NativeMethodsMixinUtils'; -import warning from 'shared/warning'; - /** * This component defines the same methods as NativeMethodsMixin but without the * findNodeHandle wrapper. This wrapper is unnecessary for HostComponent views @@ -86,7 +84,7 @@ class ReactNativeFiberHostComponent { if (relativeNode == null) { if (__DEV__) { - warning( + console.error( 'Warning: ref.measureLayout must be called with a node handle or a ref to a native component.', ); } diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index 550e63609c5d..c06d1ff267e5 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -43,7 +43,6 @@ import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; import {LegacyRoot} from 'shared/ReactRootTags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentName from 'shared/getComponentName'; -import warning from 'shared/warning'; const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; @@ -54,7 +53,7 @@ function findHostInstance_DEPRECATED( const owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { if (!owner.stateNode._warnedAboutRefsInRender) { - warning( + console.error( '%s is accessing findNodeHandle inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + @@ -101,7 +100,7 @@ function findNodeHandle(componentOrHandle: any): ?number { const owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { if (!owner.stateNode._warnedAboutRefsInRender) { - warning( + console.error( '%s is accessing findNodeHandle inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + @@ -176,7 +175,7 @@ const ReactNativeRenderer: ReactNativeType = { if (handle._nativeTag == null) { if (__DEV__) { if (handle._nativeTag == null) { - warning( + console.error( "dispatchCommand was called with a ref that isn't a " + 'native component. Use React.forwardRef to get access to the underlying native component', ); diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index d39252e28099..a21febff88f0 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -25,7 +25,6 @@ import {createPortal} from 'shared/ReactPortal'; import {REACT_FRAGMENT_TYPE, REACT_ELEMENT_TYPE} from 'shared/ReactSymbols'; import enqueueTask from 'shared/enqueueTask'; import ReactSharedInternals from 'shared/ReactSharedInternals'; -import warning from 'shared/warning'; import {ConcurrentRoot, BlockingRoot, LegacyRoot} from 'shared/ReactRootTags'; type Container = { @@ -639,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.', ); @@ -661,7 +661,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { if (__DEV__) { if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) { // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned - warning( + console.error( 'You seem to have overlapping act() calls, this is not supported. ' + 'Be sure to await previous act() calls before making a new one. ', ); @@ -693,7 +693,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { .then(() => {}) .then(() => { if (called === false) { - warning( + console.error( 'You called act(async () => ...) without await. ' + 'This could lead to unexpected testing behaviour, interleaving multiple act ' + 'calls and mixing their scopes. You should - await act(async () => ...);', @@ -741,7 +741,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { } else { if (__DEV__) { if (result !== undefined) { - warning( + console.error( 'The callback passed to act(...) function ' + 'must return undefined, or a Promise. You returned %s', result, @@ -770,7 +770,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { return { then(resolve: () => void) { if (__DEV__) { - warning( + console.error( 'Do not await the result of calling act(...) with sync logic, it is not a Promise.', ); } @@ -1107,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; } @@ -1209,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); }, diff --git a/packages/react-reconciler/src/ReactChildFiber.js b/packages/react-reconciler/src/ReactChildFiber.js index b2e862536417..eabd303dc3ab 100644 --- a/packages/react-reconciler/src/ReactChildFiber.js +++ b/packages/react-reconciler/src/ReactChildFiber.js @@ -28,7 +28,6 @@ import { Fragment, } from 'shared/ReactWorkTags'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {warnAboutStringRefs} from 'shared/ReactFeatureFlags'; import { @@ -91,7 +90,7 @@ if (__DEV__) { } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning( + console.error( 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.', @@ -119,7 +118,7 @@ function coerceRef( const componentName = getComponentName(returnFiber.type) || 'Component'; if (!didWarnAboutStringRefs[componentName]) { if (warnAboutStringRefs) { - warning( + console.error( 'Component "%s" contains the string ref "%s". Support for string refs ' + 'will be removed in a future major release. We recommend using ' + 'useRef() or createRef() instead. ' + @@ -130,7 +129,7 @@ function coerceRef( getStackByFiberInDevAndProd(returnFiber), ); } else { - warning( + console.error( 'A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + @@ -240,7 +239,7 @@ function warnOnFunctionType() { } ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - warning( + console.error( 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of from render. ' + 'Or maybe you meant to call this function rather than return it.', @@ -733,7 +732,7 @@ function ChildReconciler(shouldTrackSideEffects) { knownKeys.add(key); break; } - warning( + console.error( 'Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + @@ -933,7 +932,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChildrenIterable[Symbol.toStringTag] === 'Generator' ) { if (!didWarnAboutGenerators) { - warning( + console.error( 'Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + @@ -947,7 +946,7 @@ function ChildReconciler(shouldTrackSideEffects) { // Warn about using Maps as children if ((newChildrenIterable: any).entries === iteratorFn) { if (!didWarnAboutMaps) { - warning( + console.error( 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.', diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js index 15ab7d0d4fe5..2b0152bad664 100644 --- a/packages/react-reconciler/src/ReactFiber.js +++ b/packages/react-reconciler/src/ReactFiber.js @@ -28,7 +28,6 @@ import type {HookType} from './ReactFiberHooks'; import type {SuspenseInstance} from './ReactFiberHostConfig'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import { enableProfilerTimer, enableFundamentalAPI, @@ -805,7 +804,7 @@ function createFiberFromProfiler( typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function' ) { - warning( + console.error( 'Profiler must specify an "id" string and "onRender" function as props', ); } diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index b08602d09cc6..554aee6693b9 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -71,7 +71,6 @@ import getComponentName from 'shared/getComponentName'; import ReactStrictModeWarnings from './ReactStrictModeWarnings'; import {refineResolvedLazyComponent} from 'shared/ReactLazyComponent'; import {REACT_LAZY_TYPE, getIteratorFn} from 'shared/ReactSymbols'; -import warning from 'shared/warning'; import { setCurrentPhase, getCurrentFiberOwnerNameInDevOrNull, @@ -782,7 +781,7 @@ function updateClassComponent( let inst = workInProgress.stateNode; if (inst.props !== nextProps) { if (!didWarnAboutReassigningProps) { - warning( + console.error( 'It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component', @@ -1256,7 +1255,7 @@ function mountIndeterminateComponent( const componentName = getComponentName(Component) || 'Unknown'; if (!didWarnAboutBadClass[componentName]) { - warning( + console.error( "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, @@ -1301,7 +1300,7 @@ function mountIndeterminateComponent( if (__DEV__) { const componentName = getComponentName(Component) || 'Unknown'; if (!didWarnAboutModulePatternComponent[componentName]) { - warning( + console.error( 'The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + @@ -1363,7 +1362,7 @@ function mountIndeterminateComponent( workInProgress.tag = FunctionComponent; if (__DEV__) { if (disableLegacyContext && Component.contextTypes) { - warning( + console.error( '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown', @@ -1399,7 +1398,7 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) { if (__DEV__) { if (Component) { if (Component.childContextTypes) { - warning( + console.error( '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component', ); @@ -1419,7 +1418,7 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) { } if (!didWarnAboutFunctionRefs[warningKey]) { didWarnAboutFunctionRefs[warningKey] = true; - warning( + console.error( 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', @@ -1435,7 +1434,7 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) { const componentName = getComponentName(Component) || 'Unknown'; if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { - warning( + console.error( '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName, @@ -1448,7 +1447,7 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) { const componentName = getComponentName(Component) || 'Unknown'; if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) { - warning( + console.error( '%s: Function components do not support getDerivedStateFromProps.', componentName, ); @@ -1463,7 +1462,7 @@ function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) { const componentName = getComponentName(Component) || 'Unknown'; if (!didWarnAboutContextTypeOnFunctionComponent[componentName]) { - warning( + console.error( '%s: Function components do not support contextType.', componentName, ); @@ -1553,7 +1552,7 @@ function updateSuspenseComponent( if ('maxDuration' in nextProps) { if (!didWarnAboutMaxDuration) { didWarnAboutMaxDuration = true; - warning( + console.error( 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.', ); @@ -1960,7 +1959,7 @@ function mountDehydratedSuspenseComponent( // Instead, we'll leave the content in place and try to hydrate it later. if ((workInProgress.mode & BlockingMode) === NoMode) { if (__DEV__) { - warning( + console.error( 'Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOM.createBlockingRoot(container, { hydrate: true })' + @@ -2205,7 +2204,7 @@ function validateRevealOrder(revealOrder: SuspenseListRevealOrder) { case 'together': case 'forwards': case 'backwards': { - warning( + console.error( '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, @@ -2215,7 +2214,7 @@ function validateRevealOrder(revealOrder: SuspenseListRevealOrder) { } case 'forward': case 'backward': { - warning( + console.error( '"%s" is not a valid value for revealOrder on . ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, @@ -2224,7 +2223,7 @@ function validateRevealOrder(revealOrder: SuspenseListRevealOrder) { break; } default: - warning( + console.error( '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder, @@ -2232,7 +2231,7 @@ function validateRevealOrder(revealOrder: SuspenseListRevealOrder) { break; } } else { - warning( + console.error( '%s is not a supported value for revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder, @@ -2250,14 +2249,14 @@ function validateTailOptions( if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== 'collapsed' && tailMode !== 'hidden') { didWarnAboutTailOptions[tailMode] = true; - warning( + console.error( '"%s" is not a supported value for tail on . ' + 'Did you mean "collapsed" or "hidden"?', tailMode, ); } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') { didWarnAboutTailOptions[tailMode] = true; - warning( + console.error( ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -2274,7 +2273,7 @@ function validateSuspenseListNestedChild(childSlot: mixed, index: number) { let isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function'; if (isArray || isIterable) { let type = isArray ? 'array' : 'iterable'; - warning( + console.error( 'A nested %s was passed to row #%s in . Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + ' ... ' + @@ -2320,7 +2319,7 @@ function validateSuspenseListChildren( } } } else { - warning( + console.error( 'A single row was passed to a . ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', @@ -2615,7 +2614,7 @@ function updateContextConsumer( if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - warning( + console.error( 'Rendering directly is not supported and will be removed in ' + 'a future major release. Did you mean to render instead?', ); @@ -2630,7 +2629,7 @@ function updateContextConsumer( if (__DEV__) { if (typeof render !== 'function') { - warning( + console.error( 'A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.js b/packages/react-reconciler/src/ReactFiberClassComponent.js index 112beebda2d9..6b28bf900a89 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.js @@ -24,7 +24,6 @@ import {get as getInstance, set as setInstance} from 'shared/ReactInstanceMap'; import shallowEqual from 'shared/shallowEqual'; import getComponentName from 'shared/getComponentName'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols'; import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf'; @@ -95,7 +94,7 @@ if (__DEV__) { const key = `${callerName}_${(callback: any)}`; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warning( + console.error( '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, @@ -109,7 +108,7 @@ if (__DEV__) { const componentName = getComponentName(type) || 'Component'; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warning( + console.error( '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName, @@ -273,7 +272,7 @@ function checkShouldComponentUpdate( if (__DEV__) { if (shouldUpdate === undefined) { - warning( + console.error( '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component', @@ -301,13 +300,13 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === 'function') { - warning( + console.error( '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name, ); } else { - warning( + console.error( '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name, @@ -320,7 +319,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { !instance.getInitialState.isReactClassApproved && !instance.state ) { - warning( + console.error( 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', @@ -331,7 +330,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved ) { - warning( + console.error( 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', @@ -339,14 +338,14 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { ); } if (instance.propTypes) { - warning( + console.error( 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name, ); } if (instance.contextType) { - warning( + console.error( 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name, @@ -355,14 +354,14 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { if (disableLegacyContext) { if (ctor.childContextTypes) { - warning( + console.error( '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name, ); } if (ctor.contextTypes) { - warning( + console.error( '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name, @@ -370,7 +369,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { } } else { if (instance.contextTypes) { - warning( + console.error( 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name, @@ -383,7 +382,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warning( + console.error( '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name, @@ -392,7 +391,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { } if (typeof instance.componentShouldUpdate === 'function') { - warning( + console.error( '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + @@ -405,7 +404,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined' ) { - warning( + console.error( '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', @@ -413,7 +412,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { ); } if (typeof instance.componentDidUnmount === 'function') { - warning( + console.error( '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', @@ -421,7 +420,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { ); } if (typeof instance.componentDidReceiveProps === 'function') { - warning( + console.error( '%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + @@ -431,14 +430,14 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { ); } if (typeof instance.componentWillRecieveProps === 'function') { - warning( + console.error( '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name, ); } if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') { - warning( + console.error( '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name, @@ -446,7 +445,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { } const hasMutatedProps = instance.props !== newProps; if (instance.props !== undefined && hasMutatedProps) { - warning( + console.error( '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, @@ -454,7 +453,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { ); } if (instance.defaultProps) { - warning( + console.error( 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, @@ -468,7 +467,7 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warning( + console.error( '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor), @@ -476,21 +475,21 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { } if (typeof instance.getDerivedStateFromProps === 'function') { - warning( + console.error( '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name, ); } if (typeof instance.getDerivedStateFromError === 'function') { - warning( + console.error( '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name, ); } if (typeof ctor.getSnapshotBeforeUpdate === 'function') { - warning( + console.error( '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name, @@ -498,13 +497,13 @@ function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) { } const state = instance.state; if (state && (typeof state !== 'object' || isArray(state))) { - warning('%s.state: must be set to an object or null', name); + console.error('%s.state: must be set to an object or null', name); } if ( typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object' ) { - warning( + console.error( '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name, @@ -566,7 +565,7 @@ function constructClassInstance( Object.keys(contextType).join(', ') + '}.'; } - warning( + console.error( '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', @@ -610,7 +609,7 @@ function constructClassInstance( const componentName = getComponentName(ctor) || 'Component'; if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warning( + console.error( '`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + @@ -670,7 +669,7 @@ function constructClassInstance( : 'getSnapshotBeforeUpdate()'; if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(componentName); - warning( + console.error( 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + @@ -712,7 +711,7 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { if (__DEV__) { - warning( + console.error( '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', @@ -745,7 +744,7 @@ function callComponentWillReceiveProps( getComponentName(workInProgress.type) || 'Component'; if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warning( + console.error( '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', @@ -790,7 +789,7 @@ function mountClassInstance( const componentName = getComponentName(ctor) || 'Component'; if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warning( + console.error( '%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.js b/packages/react-reconciler/src/ReactFiberCommitWork.js index b884a5fd5e26..c295153bbeaf 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.js @@ -67,7 +67,6 @@ import { } from 'shared/ReactSideEffectTags'; import getComponentName from 'shared/getComponentName'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {onCommitUnmount} from './ReactFiberDevToolsHook'; import {startPhaseTimer, stopPhaseTimer} from './ReactDebugFiberPerf'; @@ -268,7 +267,7 @@ function commitBeforeMutationLifeCycles( !didWarnAboutReassigningProps ) { if (instance.props !== finishedWork.memoizedProps) { - warning( + console.error( 'Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + @@ -278,7 +277,7 @@ function commitBeforeMutationLifeCycles( ); } if (instance.state !== finishedWork.memoizedState) { - warning( + console.error( 'Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + @@ -301,7 +300,7 @@ function commitBeforeMutationLifeCycles( >); if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - warning( + console.error( '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type), @@ -380,7 +379,7 @@ function commitHookEffectList( } else { addendum = ' You returned: ' + destroy; } - warning( + console.error( 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, @@ -437,7 +436,7 @@ function commitLifeCycles( !didWarnAboutReassigningProps ) { if (instance.props !== finishedWork.memoizedProps) { - warning( + console.error( 'Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + @@ -447,7 +446,7 @@ function commitLifeCycles( ); } if (instance.state !== finishedWork.memoizedState) { - warning( + console.error( 'Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + @@ -476,7 +475,7 @@ function commitLifeCycles( !didWarnAboutReassigningProps ) { if (instance.props !== finishedWork.memoizedProps) { - warning( + console.error( 'Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + @@ -486,7 +485,7 @@ function commitLifeCycles( ); } if (instance.state !== finishedWork.memoizedState) { - warning( + console.error( 'Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + @@ -513,7 +512,7 @@ function commitLifeCycles( !didWarnAboutReassigningProps ) { if (instance.props !== finishedWork.memoizedProps) { - warning( + console.error( 'Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + @@ -523,7 +522,7 @@ function commitLifeCycles( ); } if (instance.state !== finishedWork.memoizedState) { - warning( + console.error( 'Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + @@ -712,7 +711,7 @@ function commitAttachRef(finishedWork: Fiber) { } else { if (__DEV__) { if (!ref.hasOwnProperty('current')) { - warning( + console.error( 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), @@ -1464,7 +1463,7 @@ function commitSuspenseComponent(finishedWork: Fiber) { } } else if (__DEV__) { if (suspenseCallback !== undefined) { - warning('Unexpected type for suspenseCallback.'); + console.error('Unexpected type for suspenseCallback.'); } } } diff --git a/packages/react-reconciler/src/ReactFiberContext.js b/packages/react-reconciler/src/ReactFiberContext.js index 3187dcfc6d8a..946d33606c81 100644 --- a/packages/react-reconciler/src/ReactFiberContext.js +++ b/packages/react-reconciler/src/ReactFiberContext.js @@ -15,7 +15,6 @@ import {disableLegacyContext} from 'shared/ReactFeatureFlags'; import {ClassComponent, HostRoot} from 'shared/ReactWorkTags'; import getComponentName from 'shared/getComponentName'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import checkPropTypes from 'prop-types/checkPropTypes'; import {setCurrentPhase, getCurrentFiberStackInDev} from './ReactCurrentFiber'; @@ -198,7 +197,7 @@ function processChildContext( if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warning( + console.error( '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', diff --git a/packages/react-reconciler/src/ReactFiberDevToolsHook.js b/packages/react-reconciler/src/ReactFiberDevToolsHook.js index 944890dc3022..d75a34080273 100644 --- a/packages/react-reconciler/src/ReactFiberDevToolsHook.js +++ b/packages/react-reconciler/src/ReactFiberDevToolsHook.js @@ -17,7 +17,6 @@ import type {ExpirationTime} from './ReactFiberExpirationTime'; import type {ReactNodeList} from 'shared/ReactTypes'; import {DidCapture} from 'shared/ReactSideEffectTags'; -import warning from 'shared/warning'; declare var __REACT_DEVTOOLS_GLOBAL_HOOK__: Object | void; @@ -43,7 +42,7 @@ export function injectInternals(internals: Object): boolean { } if (!hook.supportsFiber) { if (__DEV__) { - warning( + console.error( 'The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools', @@ -64,7 +63,10 @@ export function injectInternals(internals: Object): boolean { } catch (err) { if (__DEV__ && !hasLoggedError) { hasLoggedError = true; - warning('React instrumentation encountered an error: %s', err); + console.error( + 'React instrumentation encountered an error: %s', + err, + ); } } }; @@ -87,7 +89,10 @@ export function injectInternals(internals: Object): boolean { if (__DEV__) { if (!hasLoggedError) { hasLoggedError = true; - warning('React instrumentation encountered an error: %s', err); + console.error( + 'React instrumentation encountered an error: %s', + err, + ); } } } @@ -99,7 +104,10 @@ export function injectInternals(internals: Object): boolean { if (__DEV__) { if (!hasLoggedError) { hasLoggedError = true; - warning('React instrumentation encountered an error: %s', err); + console.error( + 'React instrumentation encountered an error: %s', + err, + ); } } } @@ -107,7 +115,7 @@ export function injectInternals(internals: Object): boolean { } catch (err) { // Catch all errors because it is unsafe to throw during initialization. if (__DEV__) { - warning('React instrumentation encountered an error: %s.', err); + console.error('React instrumentation encountered an error: %s.', err); } } // DevTools exists diff --git a/packages/react-reconciler/src/ReactFiberErrorLogger.js b/packages/react-reconciler/src/ReactFiberErrorLogger.js index 9276faf3daea..724907d561e0 100644 --- a/packages/react-reconciler/src/ReactFiberErrorLogger.js +++ b/packages/react-reconciler/src/ReactFiberErrorLogger.js @@ -44,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. - console.error(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 } @@ -78,11 +78,11 @@ 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. - console.error(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. - console.error(error); + console['error'](error); // Don't transform to our wrapper } } diff --git a/packages/react-reconciler/src/ReactFiberEvents.js b/packages/react-reconciler/src/ReactFiberEvents.js index f761eae275bc..e5a1aef0a0c1 100644 --- a/packages/react-reconciler/src/ReactFiberEvents.js +++ b/packages/react-reconciler/src/ReactFiberEvents.js @@ -21,7 +21,6 @@ import { } from './ReactFiberHostConfig'; import {NoWork} from './ReactFiberExpirationTime'; -import warning from 'shared/warning'; import {REACT_RESPONDER_TYPE} from 'shared/ReactSymbols'; import invariant from 'shared/invariant'; @@ -118,7 +117,7 @@ function updateEventListener( if (visistedResponders.has(responder)) { // show warning if (__DEV__) { - warning( + console.error( 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName, diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 461db6649881..bed592711050 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -46,7 +46,6 @@ import { } from './ReactFiberWorkLoop'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import getComponentName from 'shared/getComponentName'; import is from 'shared/objectIs'; import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork'; @@ -240,7 +239,7 @@ function checkDepsAreArrayDev(deps: mixed) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - warning( + console.error( '%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, @@ -281,7 +280,7 @@ function warnOnHookMismatchInDev(currentHookName: HookType) { table += row; } - warning( + console.error( 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + @@ -322,7 +321,7 @@ function areHookInputsEqual( if (prevDeps === null) { if (__DEV__) { - warning( + console.error( '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', @@ -336,7 +335,7 @@ function areHookInputsEqual( // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning( + console.error( 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + @@ -1033,7 +1032,7 @@ function imperativeHandleEffect( const refObject = ref; if (__DEV__) { if (!refObject.hasOwnProperty('current')) { - warning( + console.error( 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}', @@ -1055,7 +1054,7 @@ function mountImperativeHandle( ): void { if (__DEV__) { if (typeof create !== 'function') { - warning( + console.error( 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null', @@ -1082,7 +1081,7 @@ function updateImperativeHandle( ): void { if (__DEV__) { if (typeof create !== 'function') { - warning( + console.error( 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null', @@ -1257,7 +1256,7 @@ function dispatchAction( ) { if (__DEV__) { if (typeof arguments[3] === 'function') { - warning( + console.error( "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().', @@ -1440,7 +1439,7 @@ let InvalidNestedHooksDispatcherOnRerenderInDEV: Dispatcher | null = null; if (__DEV__) { const warnInvalidContextAccess = () => { - warning( + console.error( 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + @@ -1449,7 +1448,7 @@ if (__DEV__) { }; const warnInvalidHookAccess = () => { - warning( + console.error( 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + diff --git a/packages/react-reconciler/src/ReactFiberHydrationContext.js b/packages/react-reconciler/src/ReactFiberHydrationContext.js index d601d50182f6..0cc2c41ff6be 100644 --- a/packages/react-reconciler/src/ReactFiberHydrationContext.js +++ b/packages/react-reconciler/src/ReactFiberHydrationContext.js @@ -55,7 +55,6 @@ import { didNotFindHydratableSuspenseInstance, } from './ReactFiberHostConfig'; import {enableSuspenseServerRenderer} from 'shared/ReactFeatureFlags'; -import warning from 'shared/warning'; import {Never} from './ReactFiberExpirationTime'; // The deepest Fiber on the stack involved in a hydration context. @@ -67,7 +66,7 @@ let isHydrating: boolean = false; function warnIfHydrating() { if (__DEV__) { if (isHydrating) { - warning( + console.error( 'We should not be hydrating here. This is a bug in React. Please file a bug.', ); } diff --git a/packages/react-reconciler/src/ReactFiberNewContext.js b/packages/react-reconciler/src/ReactFiberNewContext.js index dcc75e06a545..ac7fdd79853e 100644 --- a/packages/react-reconciler/src/ReactFiberNewContext.js +++ b/packages/react-reconciler/src/ReactFiberNewContext.js @@ -28,7 +28,6 @@ import { } from 'shared/ReactWorkTags'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import is from 'shared/objectIs'; import { createUpdate, @@ -89,7 +88,7 @@ export function pushProvider(providerFiber: Fiber, nextValue: T): void { context._currentRenderer !== null && context._currentRenderer !== rendererSigil ) { - warning( + console.error( 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.', ); @@ -106,7 +105,7 @@ export function pushProvider(providerFiber: Fiber, nextValue: T): void { context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil ) { - warning( + console.error( 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.', ); @@ -145,7 +144,7 @@ export function calculateChangedBits( if (__DEV__) { if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - warning( + console.error( 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits, @@ -343,7 +342,7 @@ export function readContext( // This warning would fire if you read context inside a Hook like useMemo. // Unlike the class check below, it's not enforced in production for perf. if (isDisallowedContextReadInDEV) { - warning( + console.error( 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index 6b44f180847f..fb46524645ae 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -37,7 +37,6 @@ import { } from 'shared/ReactWorkTags'; import getComponentName from 'shared/getComponentName'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import {getPublicInstance} from './ReactFiberHostConfig'; @@ -181,7 +180,7 @@ function findHostInstanceWithWarning( if (!didWarnAboutFindNodeInStrictMode[componentName]) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warning( + console.error( '%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -193,7 +192,7 @@ function findHostInstanceWithWarning( getStackByFiberInDevAndProd(hostFiber), ); } else { - warning( + console.error( '%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + @@ -260,7 +259,7 @@ export function updateContainer( !didWarnAboutNestedUpdates ) { didWarnAboutNestedUpdates = true; - warning( + console.error( 'Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + @@ -279,7 +278,7 @@ export function updateContainer( if (callback !== null) { if (__DEV__) { if (typeof callback !== 'function') { - warning( + console.error( 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback, diff --git a/packages/react-reconciler/src/ReactFiberStack.js b/packages/react-reconciler/src/ReactFiberStack.js index bd9677492d7c..1a7b0620e9aa 100644 --- a/packages/react-reconciler/src/ReactFiberStack.js +++ b/packages/react-reconciler/src/ReactFiberStack.js @@ -9,8 +9,6 @@ import type {Fiber} from './ReactFiber'; -import warning from 'shared/warning'; - export type StackCursor = { current: T, }; @@ -38,14 +36,14 @@ function isEmpty(): boolean { function pop(cursor: StackCursor, fiber: Fiber): void { if (index < 0) { if (__DEV__) { - warning('Unexpected pop.'); + console.error('Unexpected pop.'); } return; } if (__DEV__) { if (fiber !== fiberStack[index]) { - warning('Unexpected Fiber popped.'); + console.error('Unexpected Fiber popped.'); } } @@ -75,7 +73,9 @@ function push(cursor: StackCursor, value: T, fiber: Fiber): void { function checkThatStackIsEmpty() { if (__DEV__) { if (index !== -1) { - warning('Expected an empty stack. Something was not reset properly.'); + console.error( + 'Expected an empty stack. Something was not reset properly.', + ); } } } diff --git a/packages/react-reconciler/src/ReactFiberThrow.js b/packages/react-reconciler/src/ReactFiberThrow.js index fdc562c2a219..f56b1a04b33a 100644 --- a/packages/react-reconciler/src/ReactFiberThrow.js +++ b/packages/react-reconciler/src/ReactFiberThrow.js @@ -16,7 +16,6 @@ import type {Thenable} from './ReactFiberWorkLoop'; import type {SuspenseContext} from './ReactFiberSuspenseContext'; import getComponentName from 'shared/getComponentName'; -import warning from 'shared/warning'; import { ClassComponent, HostRoot, @@ -125,7 +124,7 @@ function createClassErrorUpdate( // then it needs to call setState to recover from errors. // If no state update is scheduled then the boundary will swallow the error. if (fiber.expirationTime !== Sync) { - warning( + console.error( '%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown', diff --git a/packages/react-reconciler/src/ReactFiberTreeReflection.js b/packages/react-reconciler/src/ReactFiberTreeReflection.js index e82169f1b995..68a6c83d577f 100644 --- a/packages/react-reconciler/src/ReactFiberTreeReflection.js +++ b/packages/react-reconciler/src/ReactFiberTreeReflection.js @@ -12,7 +12,6 @@ import type {Container, SuspenseInstance} from './ReactFiberHostConfig'; import type {SuspenseState} from './ReactFiberSuspenseComponent'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {get as getInstance} from 'shared/ReactInstanceMap'; import ReactSharedInternals from 'shared/ReactSharedInternals'; @@ -98,7 +97,7 @@ export function isMounted(component: React$Component): boolean { const ownerFiber: Fiber = owner; const instance = ownerFiber.stateNode; if (!instance._warnedAboutRefsInRender) { - warning( + console.error( '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js index 10d4eeffcb19..758bc50f2780 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js @@ -150,7 +150,6 @@ import { } from './ReactProfilerTimer'; // DEV stuff -import warning from 'shared/warning'; import getComponentName from 'shared/getComponentName'; import ReactStrictModeWarnings from './ReactStrictModeWarnings'; import { @@ -1091,7 +1090,7 @@ export function flushDiscreteUpdates() { ) { if (__DEV__) { if ((executionContext & RenderContext) !== NoContext) { - warning( + console.error( 'unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.', ); @@ -2522,7 +2521,7 @@ function checkForNestedUpdates() { if (__DEV__) { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning( + console.error( 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + @@ -2594,7 +2593,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } else { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warning( + console.error( "Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', @@ -2685,7 +2684,7 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { if (didWarnAboutUpdateInGetChildContext) { return; } - warning( + console.error( 'setState(...): Cannot call setState() inside getChildContext()', ); didWarnAboutUpdateInGetChildContext = true; @@ -2694,7 +2693,7 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { if (didWarnAboutUpdateInRender) { return; } - warning( + console.error( 'Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure function of ' + 'props and state.', @@ -2716,7 +2715,7 @@ export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void { IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - warning( + console.error( "It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + @@ -2743,7 +2742,7 @@ export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warning( + console.error( 'An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + @@ -2770,7 +2769,7 @@ function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void { IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warning( + console.error( 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + @@ -2806,7 +2805,7 @@ export function warnIfUnmockedScheduler(fiber: Fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warning( + console.error( 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + @@ -2815,7 +2814,7 @@ export function warnIfUnmockedScheduler(fiber: Fiber) { ); } else if (warnAboutUnmockedScheduler === true) { didWarnAboutUnmockedScheduler = true; - warning( + console.error( 'Starting from React v17, the "scheduler" module will need to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + @@ -2925,7 +2924,7 @@ function flushSuspensePriorityWarningInDEV() { componentsThatTriggeredHighPriSuspend = null; if (componentNames.length > 0) { - warning( + console.error( '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + diff --git a/packages/react-reconciler/src/ReactStrictModeWarnings.js b/packages/react-reconciler/src/ReactStrictModeWarnings.js index 75495c572f09..29af663d90ec 100644 --- a/packages/react-reconciler/src/ReactStrictModeWarnings.js +++ b/packages/react-reconciler/src/ReactStrictModeWarnings.js @@ -13,8 +13,6 @@ import {getStackByFiberInDevAndProd} from './ReactCurrentFiber'; import getComponentName from 'shared/getComponentName'; import {StrictMode} from './ReactTypeOfMode'; -import lowPriorityWarning from 'shared/lowPriorityWarning'; -import warning from 'shared/warning'; type FiberArray = Array; type FiberToFiberComponentsMap = Map; @@ -191,7 +189,7 @@ if (__DEV__) { const sortedNames = setToSortedString( UNSAFE_componentWillMountUniqueNames, ); - warning( + console.error( 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + @@ -204,7 +202,7 @@ if (__DEV__) { const sortedNames = setToSortedString( UNSAFE_componentWillReceivePropsUniqueNames, ); - warning( + console.error( 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + @@ -221,7 +219,7 @@ if (__DEV__) { const sortedNames = setToSortedString( UNSAFE_componentWillUpdateUniqueNames, ); - warning( + console.error( 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + @@ -234,7 +232,7 @@ if (__DEV__) { if (componentWillMountUniqueNames.size > 0) { const sortedNames = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarning( + console.warn( 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + @@ -252,7 +250,7 @@ if (__DEV__) { componentWillReceivePropsUniqueNames, ); - lowPriorityWarning( + console.warn( 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + @@ -271,7 +269,7 @@ if (__DEV__) { if (componentWillUpdateUniqueNames.size > 0) { const sortedNames = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarning( + console.warn( 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + @@ -296,7 +294,7 @@ if (__DEV__) { ) => { const strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - warning( + console.error( 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.', ); @@ -337,7 +335,7 @@ if (__DEV__) { strictRoot, ); - warning( + console.error( 'Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + diff --git a/packages/react-reconciler/src/ReactUpdateQueue.js b/packages/react-reconciler/src/ReactUpdateQueue.js index e4d83d7f39f6..2c3e65bd0d7f 100644 --- a/packages/react-reconciler/src/ReactUpdateQueue.js +++ b/packages/react-reconciler/src/ReactUpdateQueue.js @@ -105,7 +105,6 @@ import { } from './ReactFiberWorkLoop'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {getCurrentPriorityLevel} from './SchedulerWithReactIntegration'; export type Update = { @@ -228,7 +227,7 @@ export function enqueueUpdate(fiber: Fiber, update: Update) { currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warning( + console.error( 'An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + diff --git a/packages/react-test-renderer/src/ReactShallowRenderer.js b/packages/react-test-renderer/src/ReactShallowRenderer.js index 3a28e1603543..df3f93575287 100644 --- a/packages/react-test-renderer/src/ReactShallowRenderer.js +++ b/packages/react-test-renderer/src/ReactShallowRenderer.js @@ -15,7 +15,6 @@ import shallowEqual from 'shared/shallowEqual'; import invariant from 'shared/invariant'; import checkPropTypes from 'prop-types/checkPropTypes'; import ReactSharedInternals from 'shared/ReactSharedInternals'; -import warning from 'shared/warning'; import is from 'shared/objectIs'; import type {Dispatcher as DispatcherType} from 'react-reconciler/src/ReactFiberHooks'; @@ -62,7 +61,7 @@ function areHookInputsEqual( ) { if (prevDeps === null) { if (__DEV__) { - warning( + console.error( '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', @@ -76,7 +75,7 @@ function areHookInputsEqual( // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning( + console.error( 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + diff --git a/packages/react-test-renderer/src/ReactTestHostConfig.js b/packages/react-test-renderer/src/ReactTestHostConfig.js index 434fcdb857bf..0fb67a8ebdc0 100644 --- a/packages/react-test-renderer/src/ReactTestHostConfig.js +++ b/packages/react-test-renderer/src/ReactTestHostConfig.js @@ -7,8 +7,6 @@ * @flow */ -import warning from 'shared/warning'; - import type { ReactEventResponder, ReactEventResponderInstance, @@ -83,7 +81,7 @@ export function appendChild( ): void { if (__DEV__) { if (!Array.isArray(parentInstance.children)) { - warning( + console.error( 'An invalid container has been provided. ' + 'This may indicate that another renderer is being used in addition to the test renderer. ' + '(For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) ' + @@ -218,7 +216,7 @@ export function createTextInstance( if (__DEV__) { if (enableFlareAPI) { if (hostContext === EVENT_COMPONENT_CONTEXT) { - warning( + console.error( 'validateDOMNesting: React event components cannot have text DOM nodes as children. ' + 'Wrap the child text "%s" in an element.', text, diff --git a/packages/react-test-renderer/src/ReactTestRendererAct.js b/packages/react-test-renderer/src/ReactTestRendererAct.js index 3e097abfc48c..362de4e2b22a 100644 --- a/packages/react-test-renderer/src/ReactTestRendererAct.js +++ b/packages/react-test-renderer/src/ReactTestRendererAct.js @@ -14,7 +14,6 @@ import { IsThisRendererActing, } from 'react-reconciler/inline.test'; import ReactSharedInternals from 'shared/ReactSharedInternals'; -import warning from 'shared/warning'; import enqueueTask from 'shared/enqueueTask'; import * as Scheduler from 'scheduler'; @@ -61,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.', ); @@ -83,7 +83,7 @@ function act(callback: () => Thenable) { if (__DEV__) { if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) { // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned - warning( + console.error( 'You seem to have overlapping act() calls, this is not supported. ' + 'Be sure to await previous act() calls before making a new one. ', ); @@ -115,7 +115,7 @@ function act(callback: () => Thenable) { .then(() => {}) .then(() => { if (called === false) { - warning( + console.error( 'You called act(async () => ...) without await. ' + 'This could lead to unexpected testing behaviour, interleaving multiple act ' + 'calls and mixing their scopes. You should - await act(async () => ...);', @@ -163,7 +163,7 @@ function act(callback: () => Thenable) { } else { if (__DEV__) { if (result !== undefined) { - warning( + console.error( 'The callback passed to act(...) function ' + 'must return undefined, or a Promise. You returned %s', result, @@ -191,7 +191,7 @@ function act(callback: () => Thenable) { return { then(resolve: () => void) { if (__DEV__) { - warning( + console.error( 'Do not await the result of calling act(...) with sync logic, it is not a Promise.', ); } diff --git a/packages/react/src/ReactBaseClasses.js b/packages/react/src/ReactBaseClasses.js index c160e10d2e0a..94dbd19eb811 100644 --- a/packages/react/src/ReactBaseClasses.js +++ b/packages/react/src/ReactBaseClasses.js @@ -6,7 +6,6 @@ */ import invariant from 'shared/invariant'; -import lowPriorityWarning from 'shared/lowPriorityWarning'; import ReactNoopUpdateQueue from './ReactNoopUpdateQueue'; @@ -105,7 +104,7 @@ if (__DEV__) { const defineDeprecationWarning = function(methodName, info) { Object.defineProperty(Component.prototype, methodName, { get: function() { - lowPriorityWarning( + console.warn( '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1], diff --git a/packages/react/src/ReactChildren.js b/packages/react/src/ReactChildren.js index 89ef10b03e0b..5941e1a75150 100644 --- a/packages/react/src/ReactChildren.js +++ b/packages/react/src/ReactChildren.js @@ -6,7 +6,6 @@ */ import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import { getIteratorFn, REACT_ELEMENT_TYPE, @@ -163,7 +162,7 @@ function traverseAllChildrenImpl( // Warn about using Maps as children if (iteratorFn === children.entries) { if (!didWarnAboutMaps) { - warning( + console.error( 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.', diff --git a/packages/react/src/ReactContext.js b/packages/react/src/ReactContext.js index 970a35f7be5f..cbcd3373c816 100644 --- a/packages/react/src/ReactContext.js +++ b/packages/react/src/ReactContext.js @@ -11,8 +11,6 @@ import {REACT_PROVIDER_TYPE, REACT_CONTEXT_TYPE} from 'shared/ReactSymbols'; import type {ReactContext} from 'shared/ReactTypes'; -import warning from 'shared/warning'; - export function createContext( defaultValue: T, calculateChangedBits: ?(a: T, b: T) => number, @@ -25,7 +23,7 @@ export function createContext( calculateChangedBits !== null && typeof calculateChangedBits !== 'function' ) { - warning( + console.error( 'createContext: Expected the optional second argument to be a ' + 'function. Instead received: %s', calculateChangedBits, @@ -75,7 +73,7 @@ export function createContext( get() { if (!hasWarnedAboutUsingConsumerProvider) { hasWarnedAboutUsingConsumerProvider = true; - warning( + console.error( 'Rendering is not supported and will be removed in ' + 'a future major release. Did you mean to render instead?', ); @@ -114,7 +112,7 @@ export function createContext( get() { if (!hasWarnedAboutUsingNestedContextConsumers) { hasWarnedAboutUsingNestedContextConsumers = true; - warning( + console.error( 'Rendering is not supported and will be removed in ' + 'a future major release. Did you mean to render instead?', ); diff --git a/packages/react/src/ReactElement.js b/packages/react/src/ReactElement.js index f23b589dbec1..47c7cf2015ef 100644 --- a/packages/react/src/ReactElement.js +++ b/packages/react/src/ReactElement.js @@ -6,7 +6,6 @@ */ import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols'; import ReactCurrentOwner from './ReactCurrentOwner'; @@ -51,7 +50,7 @@ function defineKeyPropWarningGetter(props, displayName) { if (__DEV__) { if (!specialPropKeyWarningShown) { specialPropKeyWarningShown = true; - warning( + console.error( '%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + @@ -73,7 +72,7 @@ function defineRefPropWarningGetter(props, displayName) { if (__DEV__) { if (!specialPropRefWarningShown) { specialPropRefWarningShown = true; - warning( + console.error( '%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + diff --git a/packages/react/src/ReactElementValidator.js b/packages/react/src/ReactElementValidator.js index 35fd62f2cf57..4da3058feee8 100644 --- a/packages/react/src/ReactElementValidator.js +++ b/packages/react/src/ReactElementValidator.js @@ -12,7 +12,6 @@ * that support it. */ -import lowPriorityWarning from 'shared/lowPriorityWarning'; import isValidElementType from 'shared/isValidElementType'; import getComponentName from 'shared/getComponentName'; import { @@ -23,7 +22,6 @@ import { REACT_ELEMENT_TYPE, } from 'shared/ReactSymbols'; import checkPropTypes from 'prop-types/checkPropTypes'; -import warning from 'shared/warning'; import ReactCurrentOwner from './ReactCurrentOwner'; import { @@ -132,7 +130,7 @@ function validateExplicitKey(element, parentType) { setCurrentlyValidatingElement(element); if (__DEV__) { - warning( + console.error( 'Each child in a list should have a unique "key" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.', currentComponentErrorInfo, @@ -224,7 +222,7 @@ function validatePropTypes(element) { setCurrentlyValidatingElement(null); } else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) { propTypesMisspellWarningShown = true; - warning( + console.error( 'Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', name || 'Unknown', ); @@ -233,7 +231,7 @@ function validatePropTypes(element) { typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved ) { - warning( + console.error( 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.', ); @@ -253,7 +251,7 @@ function validateFragmentProps(fragment) { for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (key !== 'children' && key !== 'key') { - warning( + console.error( 'Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key, @@ -263,7 +261,7 @@ function validateFragmentProps(fragment) { } if (fragment.ref !== null) { - warning('Invalid attribute `ref` supplied to `React.Fragment`.'); + console.error('Invalid attribute `ref` supplied to `React.Fragment`.'); } setCurrentlyValidatingElement(null); @@ -316,7 +314,7 @@ export function jsxWithValidation( } if (__DEV__) { - warning( + console.error( 'React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', @@ -354,7 +352,7 @@ export function jsxWithValidation( } } else { if (__DEV__) { - warning( + console.error( 'React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.', @@ -369,7 +367,7 @@ export function jsxWithValidation( if (hasOwnProperty.call(props, 'key')) { if (__DEV__) { - warning( + console.error( 'React.jsx: Spreading a key to JSX is a deprecated pattern. ' + 'Explicitly pass a key after spreading props in your JSX call. ' + 'E.g. ', @@ -437,7 +435,7 @@ export function createElementWithValidation(type, props, children) { } if (__DEV__) { - warning( + console.error( 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', @@ -483,7 +481,7 @@ export function createFactoryWithValidation(type) { Object.defineProperty(validatedFactory, 'type', { enumerable: false, get: function() { - lowPriorityWarning( + console.warn( 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.', ); diff --git a/packages/react/src/ReactHooks.js b/packages/react/src/ReactHooks.js index 314ac7d182ac..420c68fdb571 100644 --- a/packages/react/src/ReactHooks.js +++ b/packages/react/src/ReactHooks.js @@ -13,7 +13,6 @@ import type { ReactEventResponderListener, } from 'shared/ReactTypes'; import invariant from 'shared/invariant'; -import warning from 'shared/warning'; import {REACT_RESPONDER_TYPE} from 'shared/ReactSymbols'; import ReactCurrentDispatcher from './ReactCurrentDispatcher'; @@ -39,7 +38,7 @@ export function useContext( const dispatcher = resolveDispatcher(); if (__DEV__) { if (unstable_observedBits !== undefined) { - warning( + console.error( 'useContext() second argument is reserved for future ' + 'use in React. Passing it is not supported. ' + 'You passed: %s.%s', @@ -58,12 +57,12 @@ export function useContext( // Don't deduplicate because this legitimately causes bugs // and nobody should be using this in existing code. if (realContext.Consumer === Context) { - warning( + console.error( 'Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be ' + 'removed in a future major release. Did you mean to call useContext(Context) instead?', ); } else if (realContext.Provider === Context) { - warning( + console.error( 'Calling useContext(Context.Provider) is not supported. ' + 'Did you mean to call useContext(Context) instead?', ); @@ -149,7 +148,7 @@ export function useResponder( const dispatcher = resolveDispatcher(); if (__DEV__) { if (responder == null || responder.$$typeof !== REACT_RESPONDER_TYPE) { - warning( + console.error( 'useResponder: invalid first argument. Expected an event responder, but instead got %s', responder, ); diff --git a/packages/react/src/ReactLazy.js b/packages/react/src/ReactLazy.js index 88786fca449f..c804c53741a6 100644 --- a/packages/react/src/ReactLazy.js +++ b/packages/react/src/ReactLazy.js @@ -8,7 +8,6 @@ import type {LazyComponent, Thenable} from 'shared/ReactLazyComponent'; import {REACT_LAZY_TYPE} from 'shared/ReactSymbols'; -import warning from 'shared/warning'; export function lazy(ctor: () => Thenable): LazyComponent { let lazyType = { @@ -30,7 +29,7 @@ export function lazy(ctor: () => Thenable): LazyComponent { return defaultProps; }, set(newDefaultProps) { - warning( + console.error( 'React.lazy(...): It is not supported to assign `defaultProps` to ' + 'a lazy component import. Either specify them where the component ' + 'is defined, or create a wrapping component around it.', @@ -48,7 +47,7 @@ export function lazy(ctor: () => Thenable): LazyComponent { return propTypes; }, set(newPropTypes) { - warning( + console.error( 'React.lazy(...): It is not supported to assign `propTypes` to ' + 'a lazy component import. Either specify them where the component ' + 'is defined, or create a wrapping component around it.', diff --git a/packages/react/src/ReactNoopUpdateQueue.js b/packages/react/src/ReactNoopUpdateQueue.js index 8301c14d4964..a7f4611ab0fb 100644 --- a/packages/react/src/ReactNoopUpdateQueue.js +++ b/packages/react/src/ReactNoopUpdateQueue.js @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import warning from 'shared/warning'; - const didWarnStateUpdateForUnmountedComponent = {}; function warnNoop(publicInstance, callerName) { @@ -19,7 +17,7 @@ function warnNoop(publicInstance, callerName) { if (didWarnStateUpdateForUnmountedComponent[warningKey]) { return; } - warning( + console.error( "Can't call %s on a component that is not yet mounted. " + 'This is a no-op, but it might indicate a bug in your application. ' + 'Instead, assign to `this.state` directly or define a `state = {};` ' + diff --git a/packages/react/src/forwardRef.js b/packages/react/src/forwardRef.js index 7fefbc06e366..64bc4698dd7c 100644 --- a/packages/react/src/forwardRef.js +++ b/packages/react/src/forwardRef.js @@ -7,26 +7,24 @@ import {REACT_FORWARD_REF_TYPE, REACT_MEMO_TYPE} from 'shared/ReactSymbols'; -import warning from 'shared/warning'; - export default function forwardRef( render: (props: Props, ref: React$Ref) => React$Node, ) { if (__DEV__) { if (render != null && render.$$typeof === REACT_MEMO_TYPE) { - warning( + console.error( 'forwardRef requires a render function but received a `memo` ' + 'component. Instead of forwardRef(memo(...)), use ' + 'memo(forwardRef(...)).', ); } else if (typeof render !== 'function') { - warning( + console.error( 'forwardRef requires a render function but was given %s.', render === null ? 'null' : typeof render, ); } else { if (render.length !== 0 && render.length !== 2) { - warning( + console.error( 'forwardRef render functions accept exactly two parameters: props and ref. %s', render.length === 1 ? 'Did you forget to use the ref parameter?' @@ -37,7 +35,7 @@ export default function forwardRef( if (render != null) { if (render.defaultProps != null || render.propTypes != null) { - warning( + console.error( 'forwardRef render functions do not support propTypes or defaultProps. ' + 'Did you accidentally pass a React component?', ); diff --git a/packages/react/src/memo.js b/packages/react/src/memo.js index b1c203f074db..e52270185e5a 100644 --- a/packages/react/src/memo.js +++ b/packages/react/src/memo.js @@ -8,7 +8,6 @@ import {REACT_MEMO_TYPE} from 'shared/ReactSymbols'; import isValidElementType from 'shared/isValidElementType'; -import warning from 'shared/warning'; export default function memo( type: React$ElementType, @@ -16,7 +15,7 @@ export default function memo( ) { if (__DEV__) { if (!isValidElementType(type)) { - warning( + console.error( 'memo: The first argument must be a component. Instead ' + 'received: %s', type === null ? 'null' : typeof type, diff --git a/packages/scheduler/src/SchedulerProfiling.js b/packages/scheduler/src/SchedulerProfiling.js index b2e7781101a7..41c6003942c3 100644 --- a/packages/scheduler/src/SchedulerProfiling.js +++ b/packages/scheduler/src/SchedulerProfiling.js @@ -69,7 +69,8 @@ function logEvent(entries) { if (eventLogIndex + 1 > eventLogSize) { eventLogSize *= 2; if (eventLogSize > MAX_EVENT_LOG_SIZE) { - console.error( + // Using console['error'] to evade Babel and ESLint + console['error']( "Scheduler Profiling: Event log exceeded maximum size. Don't " + 'forget to call `stopLoggingProfilingEvents()`.', ); diff --git a/packages/scheduler/src/forks/SchedulerHostConfig.default.js b/packages/scheduler/src/forks/SchedulerHostConfig.default.js index c5b28c84bbf0..00e3ff745c59 100644 --- a/packages/scheduler/src/forks/SchedulerHostConfig.default.js +++ b/packages/scheduler/src/forks/SchedulerHostConfig.default.js @@ -81,14 +81,16 @@ if ( const cancelAnimationFrame = window.cancelAnimationFrame; // TODO: Remove fb.me link if (typeof requestAnimationFrame !== 'function') { - console.error( + // Using console['error'] to evade Babel and ESLint + console['error']( "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( + // Using console['error'] to evade Babel and ESLint + console['error']( "This browser doesn't support cancelAnimationFrame. " + 'Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills', @@ -169,7 +171,8 @@ if ( forceFrameRate = function(fps) { if (fps < 0 || fps > 125) { - console.error( + // Using console['error'] to evade Babel and ESLint + console['error']( 'forceFrameRate takes a positive int between 0 and 125, ' + 'forcing framerates higher than 125 fps is not unsupported', ); diff --git a/packages/shared/ReactLazyComponent.js b/packages/shared/ReactLazyComponent.js index a57d630b8d45..00c375a1bcc7 100644 --- a/packages/shared/ReactLazyComponent.js +++ b/packages/shared/ReactLazyComponent.js @@ -7,8 +7,6 @@ * @flow */ -import warning from 'shared/warning'; - export type Thenable = { then(resolve: (T) => mixed, reject: (mixed) => mixed): R, }; @@ -52,7 +50,7 @@ export function initializeLazyComponentType( const defaultExport = moduleObject.default; if (__DEV__) { if (defaultExport === undefined) { - warning( + console.error( 'lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", diff --git a/packages/shared/consoleWithStackDev.js b/packages/shared/consoleWithStackDev.js new file mode 100644 index 000000000000..22bbfee86766 --- /dev/null +++ b/packages/shared/consoleWithStackDev.js @@ -0,0 +1,63 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import ReactSharedInternals from 'shared/ReactSharedInternals'; + +// In DEV, calls to console.warn and console.error get replaced +// by calls to these methods by a Babel plugin. +// +// In PROD (or in packages without access to React internals), +// they are left as they are instead. + +export function warn(format, ...args) { + if (__DEV__) { + printWarning('warn', format, args); + } +} + +export function error(format, ...args) { + if (__DEV__) { + printWarning('error', format, args); + } +} + +function printWarning(level, format, args) { + if (__DEV__) { + const hasExistingStack = + args.length > 0 && + typeof args[args.length - 1] === 'string' && + args[args.length - 1].indexOf('\n in') === 0; + + if (!hasExistingStack) { + const ReactDebugCurrentFrame = + ReactSharedInternals.ReactDebugCurrentFrame; + const stack = ReactDebugCurrentFrame.getStackAddendum(); + if (stack !== '') { + format += '%s'; + args = args.concat([stack]); + } + } + + const argsWithFormat = args.map(item => '' + item); + // Careful: RN currently depends on this prefix + argsWithFormat.unshift('Warning: ' + format); + // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + // eslint-disable-next-line react-internal/no-production-logging + Function.prototype.apply.call(console[level], console, argsWithFormat); + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + let argIndex = 0; + const message = + 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]); + throw new Error(message); + } catch (x) {} + } +} diff --git a/packages/shared/enqueueTask.js b/packages/shared/enqueueTask.js index ec2e53d0ae8c..5bf23c18f3a0 100644 --- a/packages/shared/enqueueTask.js +++ b/packages/shared/enqueueTask.js @@ -7,8 +7,6 @@ * @flow */ -import warningWithoutStack from 'shared/warningWithoutStack'; - let didWarnAboutMessageChannel = false; let enqueueTask; try { @@ -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 ' + diff --git a/packages/shared/forks/consoleWithStackDev.www.js b/packages/shared/forks/consoleWithStackDev.www.js new file mode 100644 index 000000000000..09c8f7fba7f7 --- /dev/null +++ b/packages/shared/forks/consoleWithStackDev.www.js @@ -0,0 +1,22 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// This refers to a WWW module. +const warningWWW = require('warning'); + +export function warn() { + // TODO: use different level for "warn". + const args = Array.prototype.slice.call(arguments); + args.unshift(false); + warningWWW.apply(null, args); +} + +export function error() { + const args = Array.prototype.slice.call(arguments); + args.unshift(false); + warningWWW.apply(null, args); +} diff --git a/packages/shared/forks/lowPriorityWarningWithoutStack.www.js b/packages/shared/forks/lowPriorityWarningWithoutStack.www.js deleted file mode 100644 index dd6f1ff82f33..000000000000 --- a/packages/shared/forks/lowPriorityWarningWithoutStack.www.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// This refers to a WWW module. -const lowPriorityWarningWWW = require('lowPriorityWarning'); - -export default function lowPriorityWarningWithoutStack(format, ...args) { - return lowPriorityWarningWWW(false, format, ...args); -} diff --git a/packages/shared/forks/warningWithoutStack.www.js b/packages/shared/forks/warningWithoutStack.www.js deleted file mode 100644 index 9f8c56c78ee7..000000000000 --- a/packages/shared/forks/warningWithoutStack.www.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// This refers to a WWW module. -const warningWWW = require('warning'); - -export default function warningWithoutStack(format, ...args) { - return warningWWW(false, format, ...args); -} diff --git a/packages/shared/getComponentName.js b/packages/shared/getComponentName.js index c11a356a27a1..4c86ee094a72 100644 --- a/packages/shared/getComponentName.js +++ b/packages/shared/getComponentName.js @@ -9,7 +9,6 @@ import type {LazyComponent} from 'shared/ReactLazyComponent'; -import warning from 'shared/warning'; import { REACT_CONTEXT_TYPE, REACT_FORWARD_REF_TYPE, @@ -44,7 +43,7 @@ function getComponentName(type: mixed): string | null { } if (__DEV__) { if (typeof (type: any).tag === 'number') { - warning( + console.error( 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.', ); diff --git a/packages/shared/lowPriorityWarning.js b/packages/shared/lowPriorityWarning.js deleted file mode 100644 index 6c81a82a3914..000000000000 --- a/packages/shared/lowPriorityWarning.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack'; -import ReactSharedInternals from 'shared/ReactSharedInternals'; - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -let lowPriorityWarning = lowPriorityWarningWithoutStack; - -if (__DEV__) { - lowPriorityWarning = function(format, ...args) { - let finalFormat = format; - let finalArgs = args; - - const hasExistingStack = - args.length > 0 && - typeof args[args.length - 1] === 'string' && - args[args.length - 1].indexOf('\n in') === 0; - - if (!hasExistingStack) { - const ReactDebugCurrentFrame = - ReactSharedInternals.ReactDebugCurrentFrame; - const stack = ReactDebugCurrentFrame.getStackAddendum(); - finalFormat += '%s'; - finalArgs.push(stack); - } - - // eslint-disable-next-line react-internal/warning-args - lowPriorityWarningWithoutStack(finalFormat, ...finalArgs); - }; -} - -export default lowPriorityWarning; diff --git a/packages/shared/lowPriorityWarningWithoutStack.js b/packages/shared/lowPriorityWarningWithoutStack.js deleted file mode 100644 index 35cdd4de1acb..000000000000 --- a/packages/shared/lowPriorityWarningWithoutStack.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * Forked from fbjs/warning: - * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js - * - * Only change is we use console.warn instead of console.error, - * and do nothing when 'console' is not supported. - * This really simplifies the code. - * --- - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -let lowPriorityWarningWithoutStack = function() {}; - -if (__DEV__) { - const printWarning = function(format, ...args) { - let argIndex = 0; - const message = 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]); - if (typeof console !== 'undefined') { - console.warn(message); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - lowPriorityWarningWithoutStack = function(format, ...args) { - if (format === undefined) { - throw new Error( - '`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning ' + - 'message argument', - ); - } - - printWarning(format, ...args); - }; -} - -export default lowPriorityWarningWithoutStack; diff --git a/packages/shared/warning.js b/packages/shared/warning.js deleted file mode 100644 index 189b651e5e65..000000000000 --- a/packages/shared/warning.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import warningWithoutStack from 'shared/warningWithoutStack'; -import ReactSharedInternals from 'shared/ReactSharedInternals'; - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -let warning = warningWithoutStack; - -if (__DEV__) { - warning = function(format, ...args) { - let finalFormat = format; - let finalArgs = args; - - const hasExistingStack = - args.length > 0 && - typeof args[args.length - 1] === 'string' && - args[args.length - 1].indexOf('\n in') === 0; - - if (!hasExistingStack) { - const ReactDebugCurrentFrame = - ReactSharedInternals.ReactDebugCurrentFrame; - const stack = ReactDebugCurrentFrame.getStackAddendum(); - finalFormat += '%s'; - finalArgs.push(stack); - } - - // eslint-disable-next-line react-internal/warning-args - warningWithoutStack(finalFormat, ...finalArgs); - }; -} - -export default warning; diff --git a/packages/shared/warningWithoutStack.js b/packages/shared/warningWithoutStack.js deleted file mode 100644 index 934de64e01f2..000000000000 --- a/packages/shared/warningWithoutStack.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -/** - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -let warningWithoutStack = () => {}; - -if (__DEV__) { - warningWithoutStack = function(format, ...args) { - if (format === undefined) { - throw new Error( - '`warningWithoutStack(condition, format, ...args)` requires a warning ' + - 'message argument', - ); - } - if (args.length > 8) { - // Check before the condition to catch violations early. - throw new Error( - 'warningWithoutStack() currently supports at most 8 arguments.', - ); - } - if (typeof console !== 'undefined') { - const argsWithFormat = args.map(item => '' + item); - argsWithFormat.unshift('Warning: ' + format); - - // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - Function.prototype.apply.call(console.error, console, argsWithFormat); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - let argIndex = 0; - const message = - 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]); - throw new Error(message); - } catch (x) {} - }; -} - -export default warningWithoutStack; diff --git a/scripts/babel/transform-replace-console-calls.js b/scripts/babel/transform-replace-console-calls.js new file mode 100644 index 000000000000..7c3e43930aba --- /dev/null +++ b/scripts/babel/transform-replace-console-calls.js @@ -0,0 +1,82 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + +const helperModuleImports = require('@babel/helper-module-imports'); + +module.exports = function replaceConsoleCalls(babel) { + let consoleErrors = new WeakMap(); + function getConsoleError(path, file) { + if (!consoleErrors.has(file)) { + consoleErrors.set( + file, + helperModuleImports.addNamed( + path, + 'error', + 'shared/consoleWithStackDev', + {nameHint: 'consoleError'} + ) + ); + } + return babel.types.cloneDeep(consoleErrors.get(file)); + } + + let consoleWarns = new WeakMap(); + function getConsoleWarn(path, file) { + if (!consoleWarns.has(file)) { + consoleWarns.set( + file, + helperModuleImports.addNamed( + path, + 'warn', + 'shared/consoleWithStackDev', + {nameHint: 'consoleWarn'} + ) + ); + } + return babel.types.cloneDeep(consoleWarns.get(file)); + } + + return { + visitor: { + CallExpression: function(path, pass) { + if (path.node.callee.type !== 'MemberExpression') { + return; + } + if (path.node.callee.property.type !== 'Identifier') { + // Don't process calls like console['error'](...) + // because they serve as an escape hatch. + return; + } + if (path.get('callee').matchesPattern('console.error')) { + if (this.opts.shouldError) { + throw path.buildCodeFrameError( + "This module has no access to the React object, so it can't " + + 'use console.error() with automatically appended stack. ' + + "As a workaround, you can use console['error'] which won't " + + 'be transformed.' + ); + } + const id = getConsoleError(path, pass.file); + path.node.callee = id; + } + if (path.get('callee').matchesPattern('console.warn')) { + if (this.opts.shouldError) { + throw path.buildCodeFrameError( + "This module has no access to the React object, so it can't " + + 'use console.warn() with automatically appended stack. ' + + "As a workaround, you can use console['warn'] which won't " + + 'be transformed.' + ); + } + const id = getConsoleWarn(path, pass.file); + path.node.callee = id; + } + }, + }, + }; +}; diff --git a/scripts/eslint-rules/__tests__/no-production-logging-test.internal.js b/scripts/eslint-rules/__tests__/no-production-logging-test.internal.js index 0c4ecbfe4ad2..c2d0d5572731 100644 --- a/scripts/eslint-rules/__tests__/no-production-logging-test.internal.js +++ b/scripts/eslint-rules/__tests__/no-production-logging-test.internal.js @@ -18,28 +18,35 @@ ruleTester.run('no-production-logging', rule, { { code: ` if (__DEV__) { - warning(test, 'Oh no'); + console.error('Oh no'); } `, }, { code: ` if (__DEV__) { - warningWithoutStack(test, 'Oh no'); + console.error('Hello %s', foo) } `, }, { code: ` if (__DEV__) { - lowPriorityWarning(test, 'Oh no'); + console.error('Hello %s %s', foo, bar) } `, }, { code: ` if (__DEV__) { - lowPriorityWarningWithoutStack(test, 'Oh no'); + console.warn('Oh no'); + } + `, + }, + { + code: ` + if (__DEV__) { + console.warn('Oh no'); } `, }, @@ -49,7 +56,7 @@ ruleTester.run('no-production-logging', rule, { if (__DEV__) { if (potato) { while (true) { - warning(test, 'Oh no'); + console.error('Oh no'); } } }`, @@ -61,7 +68,7 @@ ruleTester.run('no-production-logging', rule, { f = function() { if (potato) { while (true) { - warning(test, 'Oh no'); + console.error('Oh no'); } } }; @@ -88,116 +95,102 @@ ruleTester.run('no-production-logging', rule, { if (foo) { if (__DEV__) { } else { - warning(test, 'Oh no'); + console.error('Oh no'); } } }`, }, - ], - invalid: [ - { - code: 'warning(test);', - errors: [ - { - message: `Wrap warning() in an "if (__DEV__) {}" check`, - }, - ], - }, - { - code: 'warningWithoutStack(test)', - errors: [ - { - message: `Wrap warningWithoutStack() in an "if (__DEV__) {}" check`, - }, - ], - }, { + // This is an escape hatch that makes it fire in production. code: ` - if (potato) { - warningWithoutStack(test); - } + console['error']('Oh no'); `, + }, + ], + invalid: [ + { + code: "console.error('Oh no');", errors: [ { - message: `Wrap warningWithoutStack() in an "if (__DEV__) {}" check`, + message: `Wrap console.error() in an "if (__DEV__) {}" check`, }, ], }, { - code: 'lowPriorityWarning(test);', + code: "console.warn('Oh no');", errors: [ { - message: `Wrap lowPriorityWarning() in an "if (__DEV__) {}" check`, + message: `Wrap console.warn() in an "if (__DEV__) {}" check`, }, ], }, { - code: 'lowPriorityWarningWithoutStack(test)', + code: "console.warn('Oh no')", errors: [ { - message: `Wrap lowPriorityWarningWithoutStack() in an "if (__DEV__) {}" check`, + message: `Wrap console.warn() in an "if (__DEV__) {}" check`, }, ], }, { code: ` if (potato) { - lowPriorityWarningWithoutStack(test); + console.warn('Oh no'); } `, errors: [ { - message: `Wrap lowPriorityWarningWithoutStack() in an "if (__DEV__) {}" check`, + message: `Wrap console.warn() in an "if (__DEV__) {}" check`, }, ], }, { code: ` if (__DEV__ || potato && true) { - warning(test); + console.error('Oh no'); } `, errors: [ { - message: `Wrap warning() in an "if (__DEV__) {}" check`, + message: `Wrap console.error() in an "if (__DEV__) {}" check`, }, ], }, { code: ` if (banana && __DEV__ && potato && kitten) { - warning(test); + console.error('Oh no'); } `, // Technically this code is valid but we prefer // explicit standalone __DEV__ blocks that stand out. errors: [ { - message: `Wrap warning() in an "if (__DEV__) {}" check`, + message: `Wrap console.error() in an "if (__DEV__) {}" check`, }, ], }, { code: ` if (!__DEV__) { - warning(test); + console.error('Oh no'); } `, errors: [ { - message: `Wrap warning() in an "if (__DEV__) {}" check`, + message: `Wrap console.error() in an "if (__DEV__) {}" check`, }, ], }, { code: ` if (foo || x && __DEV__) { - warning(test); + console.error('Oh no'); } `, errors: [ { - message: `Wrap warning() in an "if (__DEV__) {}" check`, + message: `Wrap console.error() in an "if (__DEV__) {}" check`, }, ], }, @@ -205,12 +198,12 @@ ruleTester.run('no-production-logging', rule, { code: ` if (__DEV__) { } else { - warning(test); + console.error('Oh no'); } `, errors: [ { - message: `Wrap warning() in an "if (__DEV__) {}" check`, + message: `Wrap console.error() in an "if (__DEV__) {}" check`, }, ], }, @@ -220,13 +213,37 @@ ruleTester.run('no-production-logging', rule, { } else { if (__DEV__) { } else { - warning(test); + console.error('Oh no'); } } `, errors: [ { - message: `Wrap warning() in an "if (__DEV__) {}" check`, + message: `Wrap console.error() in an "if (__DEV__) {}" check`, + }, + ], + }, + { + code: ` + if (__DEV__) { + console.log('Oh no'); + } + `, + errors: [ + { + message: 'Unexpected use of console', + }, + ], + }, + { + code: ` + if (__DEV__) { + console.log.apply(console, 'Oh no'); + } + `, + errors: [ + { + message: 'Unexpected use of console', }, ], }, diff --git a/scripts/eslint-rules/__tests__/warning-args-test.internal.js b/scripts/eslint-rules/__tests__/warning-args-test.internal.js index cd50e2927a3f..66f51fc717c5 100644 --- a/scripts/eslint-rules/__tests__/warning-args-test.internal.js +++ b/scripts/eslint-rules/__tests__/warning-args-test.internal.js @@ -15,63 +15,74 @@ const ruleTester = new RuleTester(); ruleTester.run('eslint-rules/warning-args', rule, { valid: [ - "warning('hello, world');", - "warning('expected %s, got %s', 42, 24);", + "console.error('hello, world');", + "console.error('expected %s, got %s', 42, 24);", 'arbitraryFunction(a, b)', ], invalid: [ { - code: 'warning(null);', + code: 'console.error(null);', errors: [ { - message: 'The first argument to warning must be a string literal', + message: + 'The first argument to console.error must be a string literal', }, ], }, { - code: 'var g = 5; warning(g);', + code: 'console.warn(null);', errors: [ { - message: 'The first argument to warning must be a string literal', + message: + 'The first argument to console.warn must be a string literal', + }, + ], + }, + { + code: 'var g = 5; console.error(g);', + errors: [ + { + message: + 'The first argument to console.error must be a string literal', }, ], }, { - code: "warning('expected %s, got %s');", + code: "console.error('expected %s, got %s');", errors: [ { message: - 'Expected 3 arguments in call to warning based on the number of ' + + 'Expected 3 arguments in call to console.error based on the number of ' + '"%s" substitutions, but got 1', }, ], }, { - code: "warning('foo is a bar under foobar', 'junk argument');", + code: "console.error('foo is a bar under foobar', 'junk argument');", errors: [ { message: - 'Expected 1 arguments in call to warning based on the number of ' + + 'Expected 1 arguments in call to console.error based on the number of ' + '"%s" substitutions, but got 2', }, ], }, { - code: "warning('error!');", + code: "console.error('error!');", errors: [ { message: - 'The warning format should be able to uniquely identify this ' + + 'The console.error format should be able to uniquely identify this ' + 'warning. Please, use a more descriptive format than: error!', }, ], }, { - code: "warning('%s %s, %s %s: %s (%s)', 1, 2, 3, 4, 5, 6);", + code: "console.error('%s %s, %s %s: %s (%s)', 1, 2, 3, 4, 5, 6);", errors: [ { message: - 'The warning format should be able to uniquely identify this ' + + 'The console.error format should be able to uniquely identify this ' + 'warning. Please, use a more descriptive format than: ' + '%s %s, %s %s: %s (%s)', }, diff --git a/scripts/eslint-rules/no-production-logging.js b/scripts/eslint-rules/no-production-logging.js index 3732cf2387b5..c6a134951262 100644 --- a/scripts/eslint-rules/no-production-logging.js +++ b/scripts/eslint-rules/no-production-logging.js @@ -9,13 +9,6 @@ 'use strict'; -const LOGGER_FN_NAMES = [ - 'warning', - 'warningWithoutStack', - 'lowPriorityWarning', - 'lowPriorityWarningWithoutStack', -]; - module.exports = function(context) { function isInDEVBlock(node) { let done = false; @@ -38,12 +31,12 @@ module.exports = function(context) { } } - function report(node) { + function reportWrapInDEV(node) { context.report({ node: node, - message: `Wrap {{identifier}}() in an "if (__DEV__) {}" check`, + message: `Wrap console.{{identifier}}() in an "if (__DEV__) {}" check`, data: { - identifier: node.callee.name, + identifier: node.property.name, }, fix: function(fixer) { return [ @@ -54,18 +47,36 @@ module.exports = function(context) { }); } - const isLoggerFunctionName = name => LOGGER_FN_NAMES.includes(name); + function reportUnexpectedConsole(node) { + context.report({ + node: node, + message: `Unexpected use of console`, + }); + } return { meta: { fixable: 'code', }, - CallExpression: function(node) { - if (!isLoggerFunctionName(node.callee.name)) { - return; - } - if (!isInDEVBlock(node)) { - report(node); + MemberExpression: function(node) { + if ( + node.object.type === 'Identifier' && + node.object.name === 'console' && + node.property.type === 'Identifier' + ) { + switch (node.property.name) { + case 'error': + case 'warn': { + if (!isInDEVBlock(node)) { + reportWrapInDEV(node); + } + break; + } + default: { + reportUnexpectedConsole(node); + break; + } + } } }, }; diff --git a/scripts/eslint-rules/warning-args.js b/scripts/eslint-rules/warning-args.js index 59345b0a8a13..b3cd6cbc3805 100644 --- a/scripts/eslint-rules/warning-args.js +++ b/scripts/eslint-rules/warning-args.js @@ -44,17 +44,19 @@ module.exports = function(context) { // This could be a little smarter by checking context.getScope() to see // how warning/invariant was defined. const isWarning = - node.callee.type === 'Identifier' && - (node.callee.name === 'warning' || - node.callee.name === 'warningWithoutStack' || - node.callee.name === 'lowPriorityWarning' || - node.callee.name === 'lowPriorityWarningWithoutStack'); + node.callee.type === 'MemberExpression' && + node.callee.object.type === 'Identifier' && + node.callee.object.name === 'console' && + node.callee.property.type === 'Identifier' && + (node.callee.property.name === 'error' || + node.callee.property.name === 'warn'); if (!isWarning) { return; } + const name = 'console.' + node.callee.property.name; if (node.arguments.length < 1) { context.report(node, '{{name}} takes at least one argument', { - name: node.callee.name, + name, }); return; } @@ -63,7 +65,7 @@ module.exports = function(context) { context.report( node, 'The first argument to {{name}} must be a string literal', - {name: node.callee.name} + {name} ); return; } @@ -71,8 +73,8 @@ module.exports = function(context) { context.report( node, 'The {{name}} format should be able to uniquely identify this ' + - '{{name}}. Please, use a more descriptive format than: {{format}}', - {name: node.callee.name, format: format} + 'warning. Please, use a more descriptive format than: {{format}}', + {name, format} ); return; } @@ -85,7 +87,7 @@ module.exports = function(context) { 'the number of "%s" substitutions, but got {{length}}', { expectedNArgs: expectedNArgs, - name: node.callee.name, + name, length: node.arguments.length, } ); diff --git a/scripts/jest/preprocessor.js b/scripts/jest/preprocessor.js index 44f96c91e28f..9be5f5bbd451 100644 --- a/scripts/jest/preprocessor.js +++ b/scripts/jest/preprocessor.js @@ -16,6 +16,9 @@ const pathToBabel = path.join( const pathToBabelPluginDevWithCode = require.resolve( '../error-codes/transform-error-messages' ); +const pathToBabelPluginReplaceConsoleCalls = require.resolve( + '../babel/transform-replace-console-calls' +); const pathToBabelPluginAsyncToGenerator = require.resolve( '@babel/plugin-transform-async-to-generator' ); @@ -65,18 +68,22 @@ module.exports = { // for test files, we also apply the async-await transform, but we want to // make sure we don't accidentally apply that transform to product code. const isTestFile = !!filePath.match(/\/__tests__\//); + const testOnlyPlugins = [pathToBabelPluginAsyncToGenerator]; + const sourceOnlyPlugins = + process.env.NODE_ENV === 'development' + ? [pathToBabelPluginReplaceConsoleCalls] + : []; + const plugins = (isTestFile ? testOnlyPlugins : sourceOnlyPlugins).concat( + babelOptions.plugins + ); return babel.transform( src, Object.assign( {filename: path.relative(process.cwd(), filePath)}, babelOptions, - isTestFile - ? { - plugins: [pathToBabelPluginAsyncToGenerator].concat( - babelOptions.plugins - ), - } - : {} + { + plugins, + } ) ); } diff --git a/scripts/print-warnings/print-warnings.js b/scripts/print-warnings/print-warnings.js index 4ac866b03d8b..2e61598ad935 100644 --- a/scripts/print-warnings/print-warnings.js +++ b/scripts/print-warnings/print-warnings.js @@ -51,13 +51,16 @@ function transform(file, enc, cb) { exit: function(astPath) { const callee = astPath.get('callee'); if ( - callee.isIdentifier({name: 'warning'}) || - callee.isIdentifier({name: 'warningWithoutStack'}) || - callee.isIdentifier({name: 'lowPriorityWarning'}) || - callee.isIdentifier({name: 'lowPriorityWarningWithoutStack'}) + callee.matchesPattern('console.warn') || + callee.matchesPattern('console.error') ) { const node = astPath.node; - + if (node.callee.type !== 'MemberExpression') { + return; + } + if (node.callee.property.type !== 'Identifier') { + return; + } // warning messages can be concatenated (`+`) at runtime, so here's // a trivial partial evaluator that interprets the literal value try { @@ -82,8 +85,8 @@ function transform(file, enc, cb) { gs([ 'packages/**/*.js', - '!packages/shared/warning.js', - '!packages/shared/lowPriorityWarning.js', + '!packages/*/npm/**/*.js', + '!packages/shared/consoleWithStackDev.js', '!packages/react-devtools*/**/*.js', '!**/__tests__/**/*.js', '!**/__mocks__/**/*.js', diff --git a/scripts/rollup/build.js b/scripts/rollup/build.js index e527f755adc9..9606cda1efad 100644 --- a/scripts/rollup/build.js +++ b/scripts/rollup/build.js @@ -107,12 +107,31 @@ const closureOptions = { rewrite_polyfills: false, }; -function getBabelConfig(updateBabelOptions, bundleType, filename) { +function getBabelConfig( + updateBabelOptions, + bundleType, + packageName, + externals, + isDevelopment +) { + const canAccessReactObject = + packageName === 'react' || externals.indexOf('react') !== -1; let options = { exclude: '/**/node_modules/**', presets: [], plugins: [], }; + if (isDevelopment) { + options.plugins.push( + // Turn console.error/warn() into a custom wrapper + [ + require('../babel/transform-replace-console-calls'), + { + shouldError: !canAccessReactObject, + }, + ] + ); + } if (updateBabelOptions) { options = updateBabelOptions(options); } @@ -352,7 +371,15 @@ function getPlugins( exclude: 'node_modules/**/*', }), // Compile to ES5. - babel(getBabelConfig(updateBabelOptions, bundleType)), + babel( + getBabelConfig( + updateBabelOptions, + bundleType, + packageName, + externals, + !isProduction + ) + ), // Remove 'use strict' from individual source files. { transform(source) { diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index 8c94593ec838..b6d2fe5caf55 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -57,9 +57,7 @@ const forks = Object.freeze({ 'from "' + entry + '" because it does not declare "react" in the package ' + - 'dependencies or peerDependencies. For example, this can happen if you use ' + - 'warning() instead of warningWithoutStack() in a package that does not ' + - 'depend on React.' + 'dependencies or peerDependencies.' ); } return null; @@ -180,25 +178,10 @@ const forks = Object.freeze({ return 'scheduler/src/forks/SchedulerHostConfig.default'; }, - // This logic is forked on www to ignore some warnings. - 'shared/lowPriorityWarningWithoutStack': (bundleType, entry) => { + 'shared/consoleWithStackDev': (bundleType, entry) => { switch (bundleType) { case FB_WWW_DEV: - case FB_WWW_PROD: - case FB_WWW_PROFILING: - return 'shared/forks/lowPriorityWarningWithoutStack.www.js'; - default: - return null; - } - }, - - // This logic is forked on www to ignore some warnings. - 'shared/warningWithoutStack': (bundleType, entry) => { - switch (bundleType) { - case FB_WWW_DEV: - case FB_WWW_PROD: - case FB_WWW_PROFILING: - return 'shared/forks/warningWithoutStack.www.js'; + return 'shared/forks/consoleWithStackDev.www.js'; default: return null; } diff --git a/scripts/shared/evalToString.js b/scripts/shared/evalToString.js index f98e2f234cce..aad199da5d75 100644 --- a/scripts/shared/evalToString.js +++ b/scripts/shared/evalToString.js @@ -11,6 +11,7 @@ function evalToString(ast /* : Object */) /* : string */ { switch (ast.type) { case 'StringLiteral': + case 'Literal': // ESLint return ast.value; case 'BinaryExpression': // `+` if (ast.operator !== '+') {