Skip to content

Commit 5b4b06c

Browse files
committed
Move client only exports to react-dom/client
This change updates the entrypoints for `react-dom` to only include exports which make sense in every runtime (Flight, Fizz, and Fiber). The main benefit to doing this is we stop including the entire client build when importing anything from `react-dom`. The server-rendering-stub was added as a manual way of doing this prior to the next major and now that stub simply reexports from `react-dom`. In a future major we will remove the stub altogether. This change affects the OSS channels but does not update how the meta entrypoints are organized
1 parent 08b7963 commit 5b4b06c

File tree

64 files changed

+511
-2336
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+511
-2336
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import {disableCommentsAsDOMContainers} from 'shared/ReactFeatureFlags';
11+
12+
import {
13+
ELEMENT_NODE,
14+
COMMENT_NODE,
15+
DOCUMENT_NODE,
16+
DOCUMENT_FRAGMENT_NODE,
17+
} from './HTMLNodeType';
18+
19+
export function isValidContainer(node: any): boolean {
20+
return !!(
21+
node &&
22+
(node.nodeType === ELEMENT_NODE ||
23+
node.nodeType === DOCUMENT_NODE ||
24+
node.nodeType === DOCUMENT_FRAGMENT_NODE ||
25+
(!disableCommentsAsDOMContainers &&
26+
node.nodeType === COMMENT_NODE &&
27+
(node: any).nodeValue === ' react-mount-point-unstable '))
28+
);
29+
}
30+
31+
// TODO: Remove this function which also includes comment nodes.
32+
// We only use it in places that are currently more relaxed.
33+
export function isValidContainerLegacy(node: any): boolean {
34+
return !!(
35+
node &&
36+
(node.nodeType === ELEMENT_NODE ||
37+
node.nodeType === DOCUMENT_NODE ||
38+
node.nodeType === DOCUMENT_FRAGMENT_NODE ||
39+
(node.nodeType === COMMENT_NODE &&
40+
(node: any).nodeValue === ' react-mount-point-unstable '))
41+
);
42+
}

packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
* @flow
88
*/
99

10-
import type {HostDispatcher} from 'react-dom/src/shared/ReactDOMTypes';
1110
import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';
1211
import type {DOMEventName} from '../events/DOMEventNames';
1312
import type {Fiber, FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
@@ -20,6 +19,7 @@ import type {ReactScopeInstance} from 'shared/ReactTypes';
2019
import type {AncestorInfoDev} from './validateDOMNesting';
2120
import type {FormStatus} from 'react-dom-bindings/src/shared/ReactDOMFormActions';
2221
import type {
22+
HostDispatcher,
2323
CrossOriginEnum,
2424
PreloadImplOptions,
2525
PreloadModuleImplOptions,
@@ -28,6 +28,10 @@ import type {
2828
PreinitModuleScriptOptions,
2929
} from 'react-dom/src/shared/ReactDOMTypes';
3030

31+
import {
32+
isAlreadyRendering,
33+
flushSync as flushSyncWithoutWarningIfAlreadyRendering,
34+
} from 'react-reconciler/src/ReactFiberReconciler';
3135
import {NotPending} from 'react-dom-bindings/src/shared/ReactDOMFormActions';
3236
import {getCurrentRootHostContainer} from 'react-reconciler/src/ReactFiberHostContext';
3337
import {DefaultEventPriority} from 'react-reconciler/src/ReactEventPriorities';
@@ -106,6 +110,9 @@ import {listenToAllSupportedEvents} from '../events/DOMPluginEventSystem';
106110
import {validateLinkPropsForStyleResource} from '../shared/ReactDOMResourceValidation';
107111
import escapeSelectorAttributeValueInsideDoubleQuotes from './escapeSelectorAttributeValueInsideDoubleQuotes';
108112

113+
import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
114+
const ReactDOMCurrentDispatcher = ReactDOMSharedInternals.Dispatcher;
115+
109116
export type Type = string;
110117
export type Props = {
111118
autoFocus?: boolean,
@@ -2083,19 +2090,44 @@ function getDocumentFromRoot(root: HoistableRoot): Document {
20832090
return root.ownerDocument || root;
20842091
}
20852092

2086-
// We want this to be the default dispatcher on ReactDOMSharedInternals but we don't want to mutate
2087-
// internals in Module scope. Instead we export it and Internals will import it. There is already a cycle
2088-
// from Internals -> ReactDOM -> HostConfig -> Internals so this doesn't introduce a new one.
2089-
export const ReactDOMClientDispatcher: HostDispatcher = {
2093+
const ReactDOMClientDispatcher: HostDispatcher = {
20902094
prefetchDNS,
20912095
preconnect,
20922096
preload,
20932097
preloadModule,
20942098
preinitStyle,
20952099
preinitScript,
20962100
preinitModuleScript,
2101+
flushSync,
2102+
nextDispatcher: null,
20972103
};
20982104

2105+
// We register the HostDispatcher on ReactDOMSharedInternals
2106+
if (ReactDOMCurrentDispatcher.current === null) {
2107+
ReactDOMCurrentDispatcher.current = ReactDOMClientDispatcher;
2108+
} else {
2109+
ReactDOMCurrentDispatcher.current.nextDispatcher = ReactDOMClientDispatcher;
2110+
}
2111+
2112+
function flushSync<R>(fn: void | (() => R)): void | R {
2113+
if (__DEV__) {
2114+
if (isAlreadyRendering()) {
2115+
console.error(
2116+
'flushSync was called from inside a lifecycle method. React cannot ' +
2117+
'flush when React is already rendering. Consider moving this call to ' +
2118+
'a scheduler task or micro task.',
2119+
);
2120+
}
2121+
}
2122+
if (ReactDOMClientDispatcher.nextDispatcher) {
2123+
return ReactDOMClientDispatcher.nextDispatcher.flushSync(() =>
2124+
flushSyncWithoutWarningIfAlreadyRendering(fn),
2125+
);
2126+
} else {
2127+
return flushSyncWithoutWarningIfAlreadyRendering(fn);
2128+
}
2129+
}
2130+
20992131
// We expect this to get inlined. It is a function mostly to communicate the special nature of
21002132
// how we resolve the HoistableRoot for ReactDOM.pre*() methods. Because we support calling
21012133
// these methods outside of render there is no way to know which Document or ShadowRoot is 'scoped'
@@ -2134,20 +2166,29 @@ function preconnectAs(
21342166
}
21352167
21362168
function prefetchDNS(href: string) {
2169+
if (ReactDOMClientDispatcher.nextDispatcher) {
2170+
ReactDOMClientDispatcher.nextDispatcher.prefetchDNS(href);
2171+
}
21372172
if (!enableFloat) {
21382173
return;
21392174
}
21402175
preconnectAs('dns-prefetch', href, null);
21412176
}
21422177
21432178
function preconnect(href: string, crossOrigin?: ?CrossOriginEnum) {
2179+
if (ReactDOMClientDispatcher.nextDispatcher) {
2180+
ReactDOMClientDispatcher.nextDispatcher.preconnect(href, crossOrigin);
2181+
}
21442182
if (!enableFloat) {
21452183
return;
21462184
}
21472185
preconnectAs('preconnect', href, crossOrigin);
21482186
}
21492187
21502188
function preload(href: string, as: string, options?: ?PreloadImplOptions) {
2189+
if (ReactDOMClientDispatcher.nextDispatcher) {
2190+
ReactDOMClientDispatcher.nextDispatcher.preload(href, as, options);
2191+
}
21512192
if (!enableFloat) {
21522193
return;
21532194
}
@@ -2228,6 +2269,9 @@ function preload(href: string, as: string, options?: ?PreloadImplOptions) {
22282269
}
22292270

22302271
function preloadModule(href: string, options?: ?PreloadModuleImplOptions) {
2272+
if (ReactDOMClientDispatcher.nextDispatcher) {
2273+
ReactDOMClientDispatcher.nextDispatcher.preloadModule(href, options);
2274+
}
22312275
if (!enableFloat) {
22322276
return;
22332277
}
@@ -2291,6 +2335,13 @@ function preinitStyle(
22912335
precedence: ?string,
22922336
options?: ?PreinitStyleOptions,
22932337
) {
2338+
if (ReactDOMClientDispatcher.nextDispatcher) {
2339+
ReactDOMClientDispatcher.nextDispatcher.preinitStyle(
2340+
href,
2341+
precedence,
2342+
options,
2343+
);
2344+
}
22942345
if (!enableFloat) {
22952346
return;
22962347
}
@@ -2367,6 +2418,9 @@ function preinitStyle(
23672418
}
23682419

23692420
function preinitScript(src: string, options?: ?PreinitScriptOptions) {
2421+
if (ReactDOMClientDispatcher.nextDispatcher) {
2422+
ReactDOMClientDispatcher.nextDispatcher.preinitScript(src, options);
2423+
}
23702424
if (!enableFloat) {
23712425
return;
23722426
}
@@ -2425,6 +2479,9 @@ function preinitModuleScript(
24252479
src: string,
24262480
options?: ?PreinitModuleScriptOptions,
24272481
) {
2482+
if (ReactDOMClientDispatcher.nextDispatcher) {
2483+
ReactDOMClientDispatcher.nextDispatcher.preinitModuleScript(src, options);
2484+
}
24282485
if (!enableFloat) {
24292486
return;
24302487
}

packages/react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,22 @@ export const ReactDOMFlightServerDispatcher: HostDispatcher = {
3333
preinitStyle,
3434
preinitScript,
3535
preinitModuleScript,
36+
flushSync,
37+
nextDispatcher: null,
3638
};
3739

40+
function flushSync<R>(fn: void | (() => R)): void | R {
41+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
42+
return ReactDOMFlightServerDispatcher.nextDispatcher.flushSync(fn);
43+
} else if (fn) {
44+
return fn();
45+
}
46+
}
47+
3848
function prefetchDNS(href: string) {
49+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
50+
ReactDOMFlightServerDispatcher.nextDispatcher.prefetchDNS(href);
51+
}
3952
if (enableFloat) {
4053
if (typeof href === 'string' && href) {
4154
const request = resolveRequest();
@@ -54,6 +67,9 @@ function prefetchDNS(href: string) {
5467
}
5568

5669
function preconnect(href: string, crossOrigin?: ?CrossOriginEnum) {
70+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
71+
ReactDOMFlightServerDispatcher.nextDispatcher.preconnect(href, crossOrigin);
72+
}
5773
if (enableFloat) {
5874
if (typeof href === 'string') {
5975
const request = resolveRequest();
@@ -77,6 +93,9 @@ function preconnect(href: string, crossOrigin?: ?CrossOriginEnum) {
7793
}
7894

7995
function preload(href: string, as: string, options?: ?PreloadImplOptions) {
96+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
97+
ReactDOMFlightServerDispatcher.nextDispatcher.preload(href, as, options);
98+
}
8099
if (enableFloat) {
81100
if (typeof href === 'string') {
82101
const request = resolveRequest();
@@ -110,6 +129,9 @@ function preload(href: string, as: string, options?: ?PreloadImplOptions) {
110129
}
111130

112131
function preloadModule(href: string, options?: ?PreloadModuleImplOptions) {
132+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
133+
ReactDOMFlightServerDispatcher.nextDispatcher.preloadModule(href, options);
134+
}
113135
if (enableFloat) {
114136
if (typeof href === 'string') {
115137
const request = resolveRequest();
@@ -138,6 +160,13 @@ function preinitStyle(
138160
precedence: ?string,
139161
options?: ?PreinitStyleOptions,
140162
) {
163+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
164+
ReactDOMFlightServerDispatcher.nextDispatcher.preinitStyle(
165+
href,
166+
precedence,
167+
options,
168+
);
169+
}
141170
if (enableFloat) {
142171
if (typeof href === 'string') {
143172
const request = resolveRequest();
@@ -168,6 +197,9 @@ function preinitStyle(
168197
}
169198

170199
function preinitScript(href: string, options?: ?PreinitScriptOptions) {
200+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
201+
ReactDOMFlightServerDispatcher.nextDispatcher.preinitScript(href, options);
202+
}
171203
if (enableFloat) {
172204
if (typeof href === 'string') {
173205
const request = resolveRequest();
@@ -195,6 +227,12 @@ function preinitModuleScript(
195227
href: string,
196228
options?: ?PreinitModuleScriptOptions,
197229
) {
230+
if (ReactDOMFlightServerDispatcher.nextDispatcher) {
231+
ReactDOMFlightServerDispatcher.nextDispatcher.preinitModuleScript(
232+
href,
233+
options,
234+
);
235+
}
198236
if (enableFloat) {
199237
if (typeof href === 'string') {
200238
const request = resolveRequest();

0 commit comments

Comments
 (0)