From 9fbc29c10828f86c8cf04934d1bf67cca7bca9ac Mon Sep 17 00:00:00 2001 From: Josh Story Date: Thu, 15 Sep 2022 11:27:12 -0700 Subject: [PATCH 1/4] reorganize react-dom internals to match react --- packages/react-dom/index.classic.fb.js | 7 +++-- packages/react-dom/index.experimental.js | 2 +- packages/react-dom/index.js | 2 +- packages/react-dom/index.modern.fb.js | 2 +- packages/react-dom/index.stable.js | 2 +- packages/react-dom/src/ReactDOMInternals.js | 35 +++++++++++++++++++++ packages/react-dom/src/client/ReactDOM.js | 29 ++--------------- packages/shared/ReactDOMSharedInternals.js | 15 +++++++++ 8 files changed, 61 insertions(+), 33 deletions(-) create mode 100644 packages/react-dom/src/ReactDOMInternals.js create mode 100644 packages/shared/ReactDOMSharedInternals.js diff --git a/packages/react-dom/index.classic.fb.js b/packages/react-dom/index.classic.fb.js index 93cc883d0cded..b27f8ac268de8 100644 --- a/packages/react-dom/index.classic.fb.js +++ b/packages/react-dom/index.classic.fb.js @@ -9,17 +9,16 @@ import {isEnabled} from './src/events/ReactDOMEventListener'; -import {__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/client/ReactDOM'; +import Internals from './src/ReactDOMInternals'; // For classic WWW builds, include a few internals that are already in use. -Object.assign((__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any), { +Object.assign((Internals: any), { ReactBrowserEventEmitter: { isEnabled, }, }); export { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, createPortal, createRoot, hydrateRoot, @@ -36,3 +35,5 @@ export { unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. version, } from './src/client/ReactDOM'; + +export {Internals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED}; diff --git a/packages/react-dom/index.experimental.js b/packages/react-dom/index.experimental.js index 44f7dcfe0b1e2..2add7dde79754 100644 --- a/packages/react-dom/index.experimental.js +++ b/packages/react-dom/index.experimental.js @@ -7,8 +7,8 @@ * @flow */ +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; export { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, createPortal, createRoot, hydrateRoot, diff --git a/packages/react-dom/index.js b/packages/react-dom/index.js index 18dfcf43ca9d0..1865adfcc4e20 100644 --- a/packages/react-dom/index.js +++ b/packages/react-dom/index.js @@ -9,8 +9,8 @@ // Export all exports so that they're available in tests. // We can't use export * from in Flow for some reason. +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; export { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, createPortal, createRoot, hydrateRoot, diff --git a/packages/react-dom/index.modern.fb.js b/packages/react-dom/index.modern.fb.js index 866a5ebe31f62..0508b768583e0 100644 --- a/packages/react-dom/index.modern.fb.js +++ b/packages/react-dom/index.modern.fb.js @@ -7,8 +7,8 @@ * @flow */ +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; export { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, createPortal, createRoot, hydrateRoot, diff --git a/packages/react-dom/index.stable.js b/packages/react-dom/index.stable.js index 7d8b01be53e3d..7d750f3c80183 100644 --- a/packages/react-dom/index.stable.js +++ b/packages/react-dom/index.stable.js @@ -7,8 +7,8 @@ * @flow */ +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; export { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, createPortal, createRoot, hydrateRoot, diff --git a/packages/react-dom/src/ReactDOMInternals.js b/packages/react-dom/src/ReactDOMInternals.js new file mode 100644 index 0000000000000..6b4525cffca2a --- /dev/null +++ b/packages/react-dom/src/ReactDOMInternals.js @@ -0,0 +1,35 @@ +/** + * 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. + * + * @flow + */ + +import {batchedUpdates} from 'react-reconciler/src/ReactFiberReconciler'; +import { + enqueueStateRestore, + restoreStateIfNeeded, +} from './events/ReactDOMControlledComponent'; +import { + getInstanceFromNode, + getNodeFromInstance, + getFiberCurrentPropsFromNode, +} from './client/ReactDOMComponentTree'; + +const Internals = { + usingClientEntryPoint: false, + // Keep in sync with ReactTestUtils.js. + // This is an array for better minification. + Events: [ + getInstanceFromNode, + getNodeFromInstance, + getFiberCurrentPropsFromNode, + enqueueStateRestore, + restoreStateIfNeeded, + batchedUpdates, + ], +}; + +export default Internals; diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 406cda4f266a8..8e716ba112dcb 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -50,12 +50,7 @@ import {canUseDOM} from 'shared/ExecutionEnvironment'; import ReactVersion from 'shared/ReactVersion'; import {enableNewReconciler} from 'shared/ReactFeatureFlags'; -import { - getInstanceFromNode, - getNodeFromInstance, - getFiberCurrentPropsFromNode, - getClosestInstanceFromNode, -} from './ReactDOMComponentTree'; +import {getClosestInstanceFromNode} from './ReactDOMComponentTree'; import {restoreControlledState} from './ReactDOMComponent'; import { setAttemptSynchronousHydration, @@ -66,11 +61,8 @@ import { setAttemptHydrationAtPriority, } from '../events/ReactDOMEventReplaying'; import {setBatchingImplementation} from '../events/ReactDOMUpdateBatching'; -import { - setRestoreImplementation, - enqueueStateRestore, - restoreStateIfNeeded, -} from '../events/ReactDOMControlledComponent'; +import {setRestoreImplementation} from '../events/ReactDOMControlledComponent'; +import Internals from '../ReactDOMInternals'; setAttemptSynchronousHydration(attemptSynchronousHydration); setAttemptDiscreteHydration(attemptDiscreteHydration); @@ -133,20 +125,6 @@ function renderSubtreeIntoContainer( ); } -const Internals = { - usingClientEntryPoint: false, - // Keep in sync with ReactTestUtils.js. - // This is an array for better minification. - Events: [ - getInstanceFromNode, - getNodeFromInstance, - getFiberCurrentPropsFromNode, - enqueueStateRestore, - restoreStateIfNeeded, - batchedUpdates, - ], -}; - function createRoot( container: Element | Document | DocumentFragment, options?: CreateRootOptions, @@ -201,7 +179,6 @@ export { createPortal, batchedUpdates as unstable_batchedUpdates, flushSync, - Internals as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, ReactVersion as version, // Disabled behind disableLegacyReactDOMAPIs findDOMNode, diff --git a/packages/shared/ReactDOMSharedInternals.js b/packages/shared/ReactDOMSharedInternals.js new file mode 100644 index 0000000000000..4ba19d407f7fc --- /dev/null +++ b/packages/shared/ReactDOMSharedInternals.js @@ -0,0 +1,15 @@ +/** + * 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. + * + * @flow + */ + +import * as ReactDOM from 'react-dom'; + +const ReactDOMSharedInternals = + ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + +export default ReactDOMSharedInternals; From 4da1f580cbeda79abc0b379181b590fb35611944 Mon Sep 17 00:00:00 2001 From: Josh Story Date: Thu, 15 Sep 2022 12:09:03 -0700 Subject: [PATCH 2/4] refactor and make forks work for flow and internal imports --- packages/react-dom/index.classic.fb.js | 2 +- packages/react-dom/index.experimental.js | 2 +- packages/react-dom/index.js | 2 +- packages/react-dom/index.modern.fb.js | 2 +- packages/react-dom/index.stable.js | 2 +- ...nternals.js => ReactDOMSharedInternals.js} | 0 packages/react-dom/src/client/ReactDOM.js | 2 +- scripts/jest/setupHostConfigs.js | 6 +++++ scripts/rollup/forks.js | 27 +++++++++++++++++++ scripts/shared/inlinedHostConfigs.js | 3 +++ 10 files changed, 42 insertions(+), 6 deletions(-) rename packages/react-dom/src/{ReactDOMInternals.js => ReactDOMSharedInternals.js} (100%) diff --git a/packages/react-dom/index.classic.fb.js b/packages/react-dom/index.classic.fb.js index b27f8ac268de8..12ba9b064ab56 100644 --- a/packages/react-dom/index.classic.fb.js +++ b/packages/react-dom/index.classic.fb.js @@ -9,7 +9,7 @@ import {isEnabled} from './src/events/ReactDOMEventListener'; -import Internals from './src/ReactDOMInternals'; +import Internals from 'shared/ReactDOMSharedInternals'; // For classic WWW builds, include a few internals that are already in use. Object.assign((Internals: any), { diff --git a/packages/react-dom/index.experimental.js b/packages/react-dom/index.experimental.js index 2add7dde79754..b33ab2f3431f8 100644 --- a/packages/react-dom/index.experimental.js +++ b/packages/react-dom/index.experimental.js @@ -7,7 +7,7 @@ * @flow */ -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/index.js b/packages/react-dom/index.js index 1865adfcc4e20..07f17a0d116ff 100644 --- a/packages/react-dom/index.js +++ b/packages/react-dom/index.js @@ -9,7 +9,7 @@ // Export all exports so that they're available in tests. // We can't use export * from in Flow for some reason. -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/index.modern.fb.js b/packages/react-dom/index.modern.fb.js index 0508b768583e0..9eb028632fad4 100644 --- a/packages/react-dom/index.modern.fb.js +++ b/packages/react-dom/index.modern.fb.js @@ -7,7 +7,7 @@ * @flow */ -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/index.stable.js b/packages/react-dom/index.stable.js index 7d750f3c80183..722513f2857ee 100644 --- a/packages/react-dom/index.stable.js +++ b/packages/react-dom/index.stable.js @@ -7,7 +7,7 @@ * @flow */ -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/src/ReactDOMInternals.js b/packages/react-dom/src/ReactDOMSharedInternals.js similarity index 100% rename from packages/react-dom/src/ReactDOMInternals.js rename to packages/react-dom/src/ReactDOMSharedInternals.js diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 8e716ba112dcb..869ef1fc49184 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -62,7 +62,7 @@ import { } from '../events/ReactDOMEventReplaying'; import {setBatchingImplementation} from '../events/ReactDOMUpdateBatching'; import {setRestoreImplementation} from '../events/ReactDOMControlledComponent'; -import Internals from '../ReactDOMInternals'; +import Internals from 'shared/ReactDOMSharedInternals'; setAttemptSynchronousHydration(attemptSynchronousHydration); setAttemptDiscreteHydration(attemptDiscreteHydration); diff --git a/scripts/jest/setupHostConfigs.js b/scripts/jest/setupHostConfigs.js index 1dc72761e03ba..b82367f2f493d 100644 --- a/scripts/jest/setupHostConfigs.js +++ b/scripts/jest/setupHostConfigs.js @@ -148,4 +148,10 @@ jest.mock('shared/ReactSharedInternals', () => jest.requireActual('react/src/ReactSharedInternals') ); +// Make it possible to import this module inside +// the ReactDOM package itself. +jest.mock('shared/ReactDOMSharedInternals', () => + jest.requireActual('react-dom/src/ReactDOMSharedInternals') +); + jest.mock('scheduler', () => jest.requireActual('scheduler/unstable_mock')); diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index d45c41a74268d..7fe34598b5e77 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -67,6 +67,33 @@ const forks = Object.freeze({ return null; }, + // Without this fork, importing `shared/ReactDOMSharedInternals` inside + // the `react` package itself would not work due to a cyclical dependency. + './packages/shared/ReactDOMSharedInternals.js': ( + bundleType, + entry, + dependencies + ) => { + if (entry === 'react-dom') { + return './packages/react-dom/src/ReactDOMSharedInternals.js'; + } + if ( + !entry.startsWith('react-dom/') && + dependencies.indexOf('react-dom') === -1 + ) { + // React DOM internals are unavailable if we can't reference the package. + // We return an error because we only want to throw if this module gets used. + return new Error( + 'Cannot use a module that depends on ReactDOMSharedInternals ' + + 'from "' + + entry + + '" because it does not declare "react-dom" in the package ' + + 'dependencies or peerDependencies.' + ); + } + return null; + }, + // We have a few forks for different environments. './packages/shared/ReactFeatureFlags.js': (bundleType, entry) => { switch (entry) { diff --git a/scripts/shared/inlinedHostConfigs.js b/scripts/shared/inlinedHostConfigs.js index 458c5410eaf18..977a1cae2e6b2 100644 --- a/scripts/shared/inlinedHostConfigs.js +++ b/scripts/shared/inlinedHostConfigs.js @@ -36,6 +36,7 @@ module.exports = [ 'react-devtools-shell', 'react-devtools-shared', 'react-interactions', + 'shared/ReactDOMSharedInternals', ], isFlowTyped: true, isServerSupported: true, @@ -66,6 +67,7 @@ module.exports = [ 'react-devtools-core', 'react-devtools-shell', 'react-devtools-shared', + 'shared/ReactDOMSharedInternals', ], isFlowTyped: true, isServerSupported: true, @@ -85,6 +87,7 @@ module.exports = [ 'react-dom/src/server/ReactDOMLegacyServerNode.classic.fb.js', 'react-dom/src/server/ReactDOMLegacyServerNodeStream.js', // file indirection to support partial forking of some methods in *Node 'react-client/src/ReactFlightClientStream.js', // We can only type check this in streaming configurations. + 'shared/ReactDOMSharedInternals', ], isFlowTyped: true, isServerSupported: true, From 72b63e9b1aa46a7627394b72436d193b5d605f9f Mon Sep 17 00:00:00 2001 From: Josh Story Date: Thu, 15 Sep 2022 13:14:34 -0700 Subject: [PATCH 3/4] flew too close to the sun --- packages/react-dom/index.classic.fb.js | 2 +- packages/react-dom/index.experimental.js | 2 +- packages/react-dom/index.js | 2 +- packages/react-dom/index.modern.fb.js | 2 +- packages/react-dom/index.stable.js | 2 +- packages/react-dom/src/client/ReactDOM.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/react-dom/index.classic.fb.js b/packages/react-dom/index.classic.fb.js index 12ba9b064ab56..fddf873d48b60 100644 --- a/packages/react-dom/index.classic.fb.js +++ b/packages/react-dom/index.classic.fb.js @@ -9,7 +9,7 @@ import {isEnabled} from './src/events/ReactDOMEventListener'; -import Internals from 'shared/ReactDOMSharedInternals'; +import Internals from './src/ReactDOMSharedInternals'; // For classic WWW builds, include a few internals that are already in use. Object.assign((Internals: any), { diff --git a/packages/react-dom/index.experimental.js b/packages/react-dom/index.experimental.js index b33ab2f3431f8..11cb1a262f4d5 100644 --- a/packages/react-dom/index.experimental.js +++ b/packages/react-dom/index.experimental.js @@ -7,7 +7,7 @@ * @flow */ -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/index.js b/packages/react-dom/index.js index 07f17a0d116ff..905754e092976 100644 --- a/packages/react-dom/index.js +++ b/packages/react-dom/index.js @@ -9,7 +9,7 @@ // Export all exports so that they're available in tests. // We can't use export * from in Flow for some reason. -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/index.modern.fb.js b/packages/react-dom/index.modern.fb.js index 9eb028632fad4..3368a3f9c9eba 100644 --- a/packages/react-dom/index.modern.fb.js +++ b/packages/react-dom/index.modern.fb.js @@ -7,7 +7,7 @@ * @flow */ -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/index.stable.js b/packages/react-dom/index.stable.js index 722513f2857ee..c0a01d6662318 100644 --- a/packages/react-dom/index.stable.js +++ b/packages/react-dom/index.stable.js @@ -7,7 +7,7 @@ * @flow */ -export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from 'shared/ReactDOMSharedInternals'; +export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternals'; export { createPortal, createRoot, diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 869ef1fc49184..bfd300f7b4c39 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -62,7 +62,7 @@ import { } from '../events/ReactDOMEventReplaying'; import {setBatchingImplementation} from '../events/ReactDOMUpdateBatching'; import {setRestoreImplementation} from '../events/ReactDOMControlledComponent'; -import Internals from 'shared/ReactDOMSharedInternals'; +import Internals from '../ReactDOMSharedInternals'; setAttemptSynchronousHydration(attemptSynchronousHydration); setAttemptDiscreteHydration(attemptDiscreteHydration); From 0f2eafb8826b1faef451220ba1d4978c18ad829e Mon Sep 17 00:00:00 2001 From: Josh Story Date: Thu, 15 Sep 2022 15:13:01 -0700 Subject: [PATCH 4/4] typo --- scripts/rollup/forks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index 7fe34598b5e77..34345c80a1352 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -68,7 +68,7 @@ const forks = Object.freeze({ }, // Without this fork, importing `shared/ReactDOMSharedInternals` inside - // the `react` package itself would not work due to a cyclical dependency. + // the `react-dom` package itself would not work due to a cyclical dependency. './packages/shared/ReactDOMSharedInternals.js': ( bundleType, entry,