diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 5ff4085f4f79..b5e60ecf1c4a 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -29,7 +29,7 @@ import * as EventPluginRegistry from 'events/EventPluginRegistry'; import * as EventPropagators from 'events/EventPropagators'; import * as ReactInstanceMap from 'shared/ReactInstanceMap'; import ReactVersion from 'shared/ReactVersion'; -import {ReactCurrentOwner} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentName from 'shared/getComponentName'; import invariant from 'shared/invariant'; import lowPriorityWarning from 'shared/lowPriorityWarning'; @@ -46,6 +46,8 @@ import { } from '../shared/HTMLNodeType'; import {ROOT_ATTRIBUTE_NAME} from '../shared/DOMProperty'; +const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; + let topLevelUpdateWarnings; let warnOnInvalidCallback; let didWarnAboutUnstableCreatePortal = false; diff --git a/packages/react-dom/src/server/ReactPartialRenderer.js b/packages/react-dom/src/server/ReactPartialRenderer.js index 601131bf81e6..83e3b805a2a5 100644 --- a/packages/react-dom/src/server/ReactPartialRenderer.js +++ b/packages/react-dom/src/server/ReactPartialRenderer.js @@ -21,7 +21,7 @@ import lowPriorityWarning from 'shared/lowPriorityWarning'; import warning from 'shared/warning'; import checkPropTypes from 'prop-types/checkPropTypes'; import describeComponentFrame from 'shared/describeComponentFrame'; -import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import {warnAboutDeprecatedLifecycles} from 'shared/ReactFeatureFlags'; import { REACT_FORWARD_REF_TYPE, @@ -68,6 +68,7 @@ const toArray = ((React.Children.toArray: any): toArrayType); // Each stack is an array of frames which may contain nested stacks of elements. let currentDebugStacks = []; +let ReactDebugCurrentFrame; let prevGetCurrentStackImpl = null; let getCurrentServerStackImpl = () => ''; let describeStackFrame = element => ''; @@ -78,6 +79,8 @@ let pushElementToDebugStack = (element: ReactElement) => {}; let popCurrentDebugStack = () => {}; if (__DEV__) { + ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + validatePropertiesInDevelopment = function(type, props) { validateARIAProperties(type, props); validateInputProperties(type, props); diff --git a/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js b/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js index ebd5b9c35e02..bcc5c4b7585c 100644 --- a/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js +++ b/packages/react-dom/src/shared/ReactDOMInvalidARIAHook.js @@ -6,12 +6,14 @@ */ import warning from 'shared/warning'; -import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import {ATTRIBUTE_NAME_CHAR} from './DOMProperty'; import isCustomComponent from './isCustomComponent'; import validAriaProperties from './validAriaProperties'; +const ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + const warnedProperties = {}; const rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); const rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); diff --git a/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js b/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js index a7702f740811..71a14f81235d 100644 --- a/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js +++ b/packages/react-dom/src/shared/ReactDOMNullInputValuePropHook.js @@ -5,9 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import warning from 'shared/warning'; +let ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + let didWarnValueNull = false; export function validateProperties(type, props) { diff --git a/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js b/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js index 652fbb1c027c..891682fbb7be 100644 --- a/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js +++ b/packages/react-dom/src/shared/ReactDOMUnknownPropertyHook.js @@ -9,7 +9,7 @@ import { registrationNameModules, possibleRegistrationNames, } from 'events/EventPluginRegistry'; -import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import warning from 'shared/warning'; import { @@ -21,9 +21,13 @@ import { import isCustomComponent from './isCustomComponent'; import possibleStandardNames from './possibleStandardNames'; +let ReactDebugCurrentFrame = null; + let validateProperty = () => {}; if (__DEV__) { + ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + const warnedProperties = {}; const hasOwnProperty = Object.prototype.hasOwnProperty; const EVENT_NAME_REGEX = /^on./; diff --git a/packages/react-native-renderer/src/ReactFabric.js b/packages/react-native-renderer/src/ReactFabric.js index 8a34ac063f5e..2ceb95e36052 100644 --- a/packages/react-native-renderer/src/ReactFabric.js +++ b/packages/react-native-renderer/src/ReactFabric.js @@ -23,10 +23,11 @@ import ReactNativeComponent from './ReactNativeComponent'; import * as ReactFabricComponentTree from './ReactFabricComponentTree'; import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; -import {ReactCurrentOwner} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentName from 'shared/getComponentName'; import warning from 'shared/warning'; +const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; const findHostInstance = ReactFabricRenderer.findHostInstance; function findNodeHandle(componentOrHandle: any): ?number { diff --git a/packages/react-native-renderer/src/ReactNativeRenderer.js b/packages/react-native-renderer/src/ReactNativeRenderer.js index cced457703ef..af8f94d3f082 100644 --- a/packages/react-native-renderer/src/ReactNativeRenderer.js +++ b/packages/react-native-renderer/src/ReactNativeRenderer.js @@ -26,10 +26,11 @@ import ReactNativeComponent from './ReactNativeComponent'; import * as ReactNativeComponentTree from './ReactNativeComponentTree'; import {getInspectorDataForViewTag} from './ReactNativeFiberInspector'; -import {ReactCurrentOwner} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentName from 'shared/getComponentName'; import warning from 'shared/warning'; +const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; const findHostInstance = ReactNativeFiberRenderer.findHostInstance; function findNodeHandle(componentOrHandle: any): ?number { diff --git a/packages/react-reconciler/src/ReactCurrentFiber.js b/packages/react-reconciler/src/ReactCurrentFiber.js index 45cfc2150e08..0a47c6ba905d 100644 --- a/packages/react-reconciler/src/ReactCurrentFiber.js +++ b/packages/react-reconciler/src/ReactCurrentFiber.js @@ -7,7 +7,7 @@ * @flow */ -import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import { IndeterminateComponent, FunctionalComponent, @@ -17,6 +17,8 @@ import { import describeComponentFrame from 'shared/describeComponentFrame'; import getComponentName from 'shared/getComponentName'; +const ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + import type {Fiber} from './ReactFiber'; type LifeCyclePhase = 'render' | 'getChildContext'; diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index d22c27be9cc2..0f7d0c3b1816 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -38,7 +38,7 @@ import { Update, Ref, } from 'shared/ReactTypeOfSideEffect'; -import {ReactCurrentOwner} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import { enableGetDerivedStateFromCatch, enableSuspense, @@ -98,6 +98,8 @@ import { } from './ReactFiberClassComponent'; import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt'; +const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; + let didWarnAboutBadClass; let didWarnAboutGetDerivedStateOnFunctionalComponent; let didWarnAboutStatelessRefs; diff --git a/packages/react-reconciler/src/ReactFiberScheduler.js b/packages/react-reconciler/src/ReactFiberScheduler.js index f2d915b30fbe..e2b0653d6a1e 100644 --- a/packages/react-reconciler/src/ReactFiberScheduler.js +++ b/packages/react-reconciler/src/ReactFiberScheduler.js @@ -12,7 +12,7 @@ import type {FiberRoot, Batch} from './ReactFiberRoot'; import type {ExpirationTime} from './ReactFiberExpirationTime'; import ReactErrorUtils from 'shared/ReactErrorUtils'; -import {ReactCurrentOwner} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import ReactStrictModeWarnings from './ReactStrictModeWarnings'; import { NoEffect, @@ -155,6 +155,7 @@ export type Thenable = { then(resolve: () => mixed, reject?: () => mixed): mixed, }; +const {ReactCurrentOwner} = ReactSharedInternals; const { invokeGuardedCallback, hasCaughtError, diff --git a/packages/react-reconciler/src/ReactFiberTreeReflection.js b/packages/react-reconciler/src/ReactFiberTreeReflection.js index 9de1fc693010..7ee0ff5cc36f 100644 --- a/packages/react-reconciler/src/ReactFiberTreeReflection.js +++ b/packages/react-reconciler/src/ReactFiberTreeReflection.js @@ -13,7 +13,7 @@ import invariant from 'shared/invariant'; import warning from 'shared/warning'; import * as ReactInstanceMap from 'shared/ReactInstanceMap'; -import {ReactCurrentOwner} from 'shared/ReactGlobalSharedState'; +import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentName from 'shared/getComponentName'; import { ClassComponent, @@ -24,6 +24,8 @@ import { } from 'shared/ReactTypeOfWork'; import {NoEffect, Placement} from 'shared/ReactTypeOfSideEffect'; +const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; + const MOUNTING = 1; const MOUNTED = 2; const UNMOUNTED = 3; diff --git a/packages/react/src/React.js b/packages/react/src/React.js index 01df1b4ed6ec..15e10114dcd9 100644 --- a/packages/react/src/React.js +++ b/packages/react/src/React.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import assign from 'object-assign'; import ReactVersion from 'shared/ReactVersion'; import { REACT_ASYNC_MODE_TYPE, @@ -19,7 +18,6 @@ import {enableSuspense} from 'shared/ReactFeatureFlags'; import {Component, PureComponent} from './ReactBaseClasses'; import {createRef} from './ReactCreateRef'; import {forEach, map, count, toArray, only} from './ReactChildren'; -import ReactCurrentOwner from './ReactCurrentOwner'; import { createElement, createFactory, @@ -33,7 +31,7 @@ import { createFactoryWithValidation, cloneElementWithValidation, } from './ReactElementValidator'; -import ReactDebugCurrentFrame from './ReactDebugCurrentFrame'; +import ReactSharedInternals from './ReactSharedInternals'; const React = { Children: { @@ -63,25 +61,11 @@ const React = { version: ReactVersion, - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { - ReactCurrentOwner, - // Used by renderers to avoid bundling object-assign twice in UMD bundles: - assign, - }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals, }; if (enableSuspense) { React.Placeholder = REACT_PLACEHOLDER_TYPE; } -if (__DEV__) { - Object.assign(React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, { - // These should not be included in production. - ReactDebugCurrentFrame, - // Shim for React DOM 16.0.0 which still destructured (but not used) this. - // TODO: remove in React 17.0. - ReactComponentTreeHook: {}, - }); -} - export default React; diff --git a/packages/react/src/ReactSharedInternals.js b/packages/react/src/ReactSharedInternals.js new file mode 100644 index 000000000000..8b179aff8422 --- /dev/null +++ b/packages/react/src/ReactSharedInternals.js @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import assign from 'object-assign'; +import ReactCurrentOwner from './ReactCurrentOwner'; +import ReactDebugCurrentFrame from './ReactDebugCurrentFrame'; + +const ReactSharedInternals = { + ReactCurrentOwner, + // Used by renderers to avoid bundling object-assign twice in UMD bundles: + assign, +}; + +if (__DEV__) { + Object.assign(ReactSharedInternals, { + // These should not be included in production. + ReactDebugCurrentFrame, + // Shim for React DOM 16.0.0 which still destructured (but not used) this. + // TODO: remove in React 17.0. + ReactComponentTreeHook: {}, + }); +} + +export default ReactSharedInternals; diff --git a/packages/shared/ReactGlobalSharedState.js b/packages/shared/ReactGlobalSharedState.js deleted file mode 100644 index b911e90801ed..000000000000 --- a/packages/shared/ReactGlobalSharedState.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React from 'react'; - -const ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; - -export const ReactCurrentOwner = ReactInternals.ReactCurrentOwner; -export const ReactDebugCurrentFrame = __DEV__ - ? ReactInternals.ReactDebugCurrentFrame - : null; diff --git a/packages/shared/ReactSharedInternals.js b/packages/shared/ReactSharedInternals.js new file mode 100644 index 000000000000..7dbaa7de1687 --- /dev/null +++ b/packages/shared/ReactSharedInternals.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; + +const ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + +export default ReactSharedInternals; diff --git a/scripts/jest/setupHostConfigs.js b/scripts/jest/setupHostConfigs.js index b018f42d9271..888fade84819 100644 --- a/scripts/jest/setupHostConfigs.js +++ b/scripts/jest/setupHostConfigs.js @@ -56,3 +56,9 @@ inlinedHostConfigs.forEach(rendererInfo => { return renderer; }); }); + +// Make it possible to import this module inside +// the React package itself. +jest.mock('shared/ReactSharedInternals', () => + require.requireActual('react/src/ReactSharedInternals') +); diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index 682a4cd76739..74d4df6c364a 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -38,6 +38,15 @@ const forks = Object.freeze({ return 'shared/forks/object-assign.umd.js'; }, + // Without this fork, importing `shared/ReactSharedInternals` inside + // the `react` package itself would not work due to a cyclical dependency. + 'shared/ReactSharedInternals': (bundleType, entry) => { + if (entry === 'react') { + return 'react/src/ReactSharedInternals'; + } + return null; + }, + // We have a few forks for different environments. 'shared/ReactFeatureFlags': (bundleType, entry) => { switch (entry) {