Skip to content

Commit

Permalink
Warning system refactoring (part 1) (#16799)
Browse files Browse the repository at this point in the history
* Rename lowPriorityWarning to lowPriorityWarningWithoutStack

This maintains parity with the other warning-like functions.

* Duplicate the toWarnDev tests to test toLowPriorityWarnDev

* Make a lowPriorityWarning version of warning.js

* Extract both variants in print-warning

Avoids parsing lowPriorityWarning.js itself as the way it forwards the
call to lowPriorityWarningWithoutStack is not analyzable.
  • Loading branch information
Jessidhia authored and gaearon committed Sep 24, 2019
1 parent 8b580a8 commit 18d2e0c
Show file tree
Hide file tree
Showing 13 changed files with 291 additions and 50 deletions.
6 changes: 3 additions & 3 deletions packages/react-dom/src/client/ReactDOM.js
Expand Up @@ -61,7 +61,7 @@ import ReactVersion from 'shared/ReactVersion';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import getComponentName from 'shared/getComponentName';
import invariant from 'shared/invariant';
import lowPriorityWarning from 'shared/lowPriorityWarning';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';
import warningWithoutStack from 'shared/warningWithoutStack';
import {enableStableConcurrentModeAPIs} from 'shared/ReactFeatureFlags';

Expand Down Expand Up @@ -542,7 +542,7 @@ function legacyCreateRootFromDOMContainer(
if (__DEV__) {
if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
warnedAboutHydrateAPI = true;
lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' +
'will stop working in React v17. Replace the ReactDOM.render() call ' +
Expand Down Expand Up @@ -801,7 +801,7 @@ const ReactDOM: Object = {
unstable_createPortal(...args) {
if (!didWarnAboutUnstableCreatePortal) {
didWarnAboutUnstableCreatePortal = true;
lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'The ReactDOM.unstable_createPortal() alias has been deprecated, ' +
'and will be removed in React 17+. Update your code to use ' +
Expand Down
4 changes: 2 additions & 2 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Expand Up @@ -15,7 +15,7 @@ import type {ReactProvider, ReactContext} from 'shared/ReactTypes';
import React from 'react';
import invariant from 'shared/invariant';
import getComponentName from 'shared/getComponentName';
import lowPriorityWarning from 'shared/lowPriorityWarning';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';
import warning from 'shared/warning';
import warningWithoutStack from 'shared/warningWithoutStack';
import describeComponentFrame from 'shared/describeComponentFrame';
Expand Down Expand Up @@ -588,7 +588,7 @@ function resolve(
const componentName = getComponentName(Component) || 'Unknown';

if (!didWarnAboutDeprecatedWillMount[componentName]) {
lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
// keep this warning in sync with ReactStrictModeWarning.js
'componentWillMount has been renamed, and is not recommended for use. ' +
Expand Down
4 changes: 2 additions & 2 deletions packages/react-dom/src/test-utils/ReactTestUtils.js
Expand Up @@ -17,7 +17,7 @@ import {
} from 'shared/ReactWorkTags';
import SyntheticEvent from 'legacy-events/SyntheticEvent';
import invariant from 'shared/invariant';
import lowPriorityWarning from 'shared/lowPriorityWarning';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';
import {ELEMENT_NODE} from '../shared/HTMLNodeType';
import * as DOMTopLevelEventTypes from '../events/DOMTopLevelEventTypes';
import {PLUGIN_EVENT_SYSTEM} from 'legacy-events/EventSystemFlags';
Expand Down Expand Up @@ -361,7 +361,7 @@ const ReactTestUtils = {
mockComponent: function(module, mockTagName) {
if (!hasWarnedAboutDeprecatedMockComponent) {
hasWarnedAboutDeprecatedMockComponent = true;
lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'ReactTestUtils.mockComponent() is deprecated. ' +
'Use shallow rendering or jest.mock() instead.\n\n' +
Expand Down
4 changes: 2 additions & 2 deletions packages/react-is/src/ReactIs.js
Expand Up @@ -25,7 +25,7 @@ import {
REACT_SUSPENSE_TYPE,
} from 'shared/ReactSymbols';
import isValidElementType from 'shared/isValidElementType';
import lowPriorityWarning from 'shared/lowPriorityWarning';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';

export function typeOf(object: any) {
if (typeof object === 'object' && object !== null) {
Expand Down Expand Up @@ -88,7 +88,7 @@ export function isAsyncMode(object: any) {
if (__DEV__) {
if (!hasWarnedAboutDeprecatedIsAsyncMode) {
hasWarnedAboutDeprecatedIsAsyncMode = true;
lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'The ReactIs.isAsyncMode() alias has been deprecated, ' +
'and will be removed in React 17+. Update your code to use ' +
Expand Down
8 changes: 4 additions & 4 deletions packages/react-reconciler/src/ReactStrictModeWarnings.js
Expand Up @@ -13,7 +13,7 @@ import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';

import getComponentName from 'shared/getComponentName';
import {StrictMode} from './ReactTypeOfMode';
import lowPriorityWarning from 'shared/lowPriorityWarning';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';
import warningWithoutStack from 'shared/warningWithoutStack';

type FiberArray = Array<Fiber>;
Expand Down Expand Up @@ -237,7 +237,7 @@ if (__DEV__) {
if (componentWillMountUniqueNames.size > 0) {
const sortedNames = setToSortedString(componentWillMountUniqueNames);

lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'componentWillMount has been renamed, and is not recommended for use. ' +
'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' +
Expand All @@ -256,7 +256,7 @@ if (__DEV__) {
componentWillReceivePropsUniqueNames,
);

lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'componentWillReceiveProps has been renamed, and is not recommended for use. ' +
'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' +
Expand All @@ -276,7 +276,7 @@ if (__DEV__) {
if (componentWillUpdateUniqueNames.size > 0) {
const sortedNames = setToSortedString(componentWillUpdateUniqueNames);

lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'componentWillUpdate has been renamed, and is not recommended for use. ' +
'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' +
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/ReactBaseClasses.js
Expand Up @@ -6,7 +6,7 @@
*/

import invariant from 'shared/invariant';
import lowPriorityWarning from 'shared/lowPriorityWarning';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';

import ReactNoopUpdateQueue from './ReactNoopUpdateQueue';

Expand Down Expand Up @@ -105,7 +105,7 @@ if (__DEV__) {
const defineDeprecationWarning = function(methodName, info) {
Object.defineProperty(Component.prototype, methodName, {
get: function() {
lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'%s(...) is deprecated in plain JavaScript React classes. %s',
info[0],
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/ReactElementValidator.js
Expand Up @@ -12,7 +12,7 @@
* that support it.
*/

import lowPriorityWarning from 'shared/lowPriorityWarning';
import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';
import isValidElementType from 'shared/isValidElementType';
import getComponentName from 'shared/getComponentName';
import {
Expand Down Expand Up @@ -477,7 +477,7 @@ export function createFactoryWithValidation(type) {
Object.defineProperty(validatedFactory, 'type', {
enumerable: false,
get: function() {
lowPriorityWarning(
lowPriorityWarningWithoutStack(
false,
'Factory.type is deprecated. Access the class directly ' +
'before passing it to createFactory.',
Expand Down
Expand Up @@ -5,4 +5,5 @@
* LICENSE file in the root directory of this source tree.
*/

// This "lowPriorityWarning" is an external module
export default require('lowPriorityWarning');
40 changes: 10 additions & 30 deletions packages/shared/lowPriorityWarning.js
Expand Up @@ -5,47 +5,27 @@
* LICENSE file in the root directory of this source tree.
*/

import lowPriorityWarningWithoutStack from 'shared/lowPriorityWarningWithoutStack';
import ReactSharedInternals from 'shared/ReactSharedInternals';

/**
* 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 lowPriorityWarning = function() {};
let lowPriorityWarning = lowPriorityWarningWithoutStack;

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) {}
};

lowPriorityWarning = function(condition, format, ...args) {
if (format === undefined) {
throw new Error(
'`lowPriorityWarning(condition, format, ...args)` requires a warning ' +
'message argument',
);
}
if (!condition) {
printWarning(format, ...args);
if (condition) {
return;
}
const ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
const stack = ReactDebugCurrentFrame.getStackAddendum();
// eslint-disable-next-line react-internal/warning-and-invariant-args
lowPriorityWarningWithoutStack(false, format + '%s', ...args, stack);
};
}

Expand Down
52 changes: 52 additions & 0 deletions packages/shared/lowPriorityWarningWithoutStack.js
@@ -0,0 +1,52 @@
/**
* 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(condition, format, ...args) {
if (format === undefined) {
throw new Error(
'`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning ' +
'message argument',
);
}
if (!condition) {
printWarning(format, ...args);
}
};
}

export default lowPriorityWarningWithoutStack;

0 comments on commit 18d2e0c

Please sign in to comment.