@samitouri / QOS-React / commits / 8777b44e98

Add Modern WWW build (#18028)

* Build both stable and experimental WWW builds * Flip already experimental WWW flags to true * Remove FB-specific internals from modern FB builds We think we're not going to need these. * Disable classic features in modern WWW builds * Disable legacy ReactDOM API for modern WWW build * Don’t include user timing in prod * Fix bad copy paste and add missing flags to test renderer * Add testing WWW feature flag file We need it because WWW has a different meaning of experimental now.

Dan Abramov committed Feb 13, 2020 at 20:33 UTC 8777b44e982e7ddedda62aee02f1fd370795db44
14 files changed +143 -49
packages/react-dom/src/client/ReactDOM.js
+8 -6
@@ -56,6 +56,7 @@ import ReactVersion from 'shared/ReactVersion';
56 import invariant from 'shared/invariant';
57 import {
58 exposeConcurrentModeAPIs,
59 + disableLegacyReactDOMAPIs,
60 disableUnstableCreatePortal,
61 disableUnstableRenderSubtreeIntoContainer,
62 warnUnstableRenderSubtreeIntoContainer,
@@ -133,12 +134,6 @@ function createPortal(
134 const ReactDOM: Object = {
135 createPortal,
136
136 - // Legacy
137 - findDOMNode,
138 - hydrate,
139 - render,
140 - unmountComponentAtNode,
141 -
137 unstable_batchedUpdates: batchedUpdates,
138
139 flushSync: flushSync,
@@ -166,6 +161,13 @@ const ReactDOM: Object = {
161 version: ReactVersion,
162 };
163
164 +if (!disableLegacyReactDOMAPIs) {
165 + ReactDOM.findDOMNode = findDOMNode;
166 + ReactDOM.hydrate = hydrate;
167 + ReactDOM.render = render;
168 + ReactDOM.unmountComponentAtNode = unmountComponentAtNode;
169 +}
170 +
171 if (exposeConcurrentModeAPIs) {
172 ReactDOM.createRoot = createRoot;
173 ReactDOM.createBlockingRoot = createBlockingRoot;
packages/react-dom/src/client/ReactDOMFB.js
+18 -13
@@ -13,19 +13,24 @@ import ReactDOM from './ReactDOM';
13 import {isEnabled} from '../events/ReactBrowserEventEmitter';
14 import {getClosestInstanceFromNode} from './ReactDOMComponentTree';
15
16 -Object.assign(
17 - (ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any),
18 - {
19 - // These are real internal dependencies that are trickier to remove:
20 - ReactBrowserEventEmitter: {
21 - isEnabled,
16 +if (__EXPERIMENTAL__) {
17 + // This is a modern WWW build.
18 + // It should be the same as open source. Don't add new things here.
19 +} else {
20 + // For classic WWW builds, include a few internals that are already in use.
21 + Object.assign(
22 + (ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any),
23 + {
24 + ReactBrowserEventEmitter: {
25 + isEnabled,
26 + },
27 + ReactDOMComponentTree: {
28 + getClosestInstanceFromNode,
29 + },
30 + // Perf experiment
31 + addUserTimingListener,
32 },
23 - ReactDOMComponentTree: {
24 - getClosestInstanceFromNode,
25 - },
26 - // Perf experiment
27 - addUserTimingListener,
28 - },
29 -);
33 + );
34 +}
35
36 export default ReactDOM;
packages/react-reconciler/src/ReactFiber.js
+6 -2
@@ -425,7 +425,9 @@ export function createWorkInProgress(
425
426 if (__DEV__) {
427 // DEV-only fields
428 - workInProgress._debugID = current._debugID;
428 + if (enableUserTimingAPI) {
429 + workInProgress._debugID = current._debugID;
430 + }
431 workInProgress._debugSource = current._debugSource;
432 workInProgress._debugOwner = current._debugOwner;
433 workInProgress._debugHookTypes = current._debugHookTypes;
@@ -958,7 +960,9 @@ export function assignFiberPropertiesInDEV(
960 target.selfBaseDuration = source.selfBaseDuration;
961 target.treeBaseDuration = source.treeBaseDuration;
962 }
961 - target._debugID = source._debugID;
963 + if (enableUserTimingAPI) {
964 + target._debugID = source._debugID;
965 + }
966 target._debugSource = source._debugSource;
967 target._debugOwner = source._debugOwner;
968 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
packages/shared/ReactFeatureFlags.js
+3
@@ -114,6 +114,9 @@ export const disableLegacyContext = false;
114 // Disables React.createFactory
115 export const disableCreateFactory = false;
116
117 +// Disables hydrate, render, findDOMNode, unmountComponentAtNode
118 +export const disableLegacyReactDOMAPIs = false;
119 +
120 // Disables children for <textarea> elements
121 export const disableTextareaChildren = false;
122
packages/shared/forks/ReactFeatureFlags.native-fb.js
+3 -2
@@ -10,7 +10,7 @@
10 import invariant from 'shared/invariant';
11
12 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13 -import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-fb';
13 +import typeof * as ExportsType from './ReactFeatureFlags.native-fb';
14
15 // Uncomment to re-export dynamic flags from the fbsource version.
16 export const {
@@ -46,6 +46,7 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
46 export const enableTrainModelFix = true;
47 export const enableTrustedTypesIntegration = false;
48 export const disableCreateFactory = false;
49 +export const disableLegacyReactDOMAPIs = false;
50 export const disableTextareaChildren = false;
51 export const disableMapsAsChildren = false;
52 export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -63,4 +64,4 @@ export function addUserTimingListener() {
64 // eslint-disable-next-line no-unused-vars
65 type Check<_X, Y: _X, X: Y = _X> = null;
66 // eslint-disable-next-line no-unused-expressions
66 -(null: Check<FeatureFlagsShimType, FeatureFlagsType>);
67 +(null: Check<ExportsType, FeatureFlagsType>);
packages/shared/forks/ReactFeatureFlags.native-oss.js
+3 -2
@@ -10,7 +10,7 @@
10 import invariant from 'shared/invariant';
11
12 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13 -import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-oss';
13 +import typeof * as ExportsType from './ReactFeatureFlags.native-oss';
14
15 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
41 export const enableTrustedTypesIntegration = false;
42 export const enableNativeTargetAsInstance = false;
43 export const disableCreateFactory = false;
44 +export const disableLegacyReactDOMAPIs = false;
45 export const disableTextareaChildren = false;
46 export const disableMapsAsChildren = false;
47 export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
59 // eslint-disable-next-line no-unused-vars
60 type Check<_X, Y: _X, X: Y = _X> = null;
61 // eslint-disable-next-line no-unused-expressions
61 -(null: Check<FeatureFlagsShimType, FeatureFlagsType>);
62 +(null: Check<ExportsType, FeatureFlagsType>);
packages/shared/forks/ReactFeatureFlags.persistent.js
+3 -2
@@ -10,7 +10,7 @@
10 import invariant from 'shared/invariant';
11
12 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13 -import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
13 +import typeof * as ExportsType from './ReactFeatureFlags.persistent';
14
15 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
41 export const enableTrustedTypesIntegration = false;
42 export const enableNativeTargetAsInstance = false;
43 export const disableCreateFactory = false;
44 +export const disableLegacyReactDOMAPIs = false;
45 export const disableTextareaChildren = false;
46 export const disableMapsAsChildren = false;
47 export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
59 // eslint-disable-next-line no-unused-vars
60 type Check<_X, Y: _X, X: Y = _X> = null;
61 // eslint-disable-next-line no-unused-expressions
61 -(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
62 +(null: Check<ExportsType, FeatureFlagsType>);
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+3 -2
@@ -10,7 +10,7 @@
10 import invariant from 'shared/invariant';
11
12 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13 -import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
13 +import typeof * as ExportsType from './ReactFeatureFlags.test-renderer';
14
15 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
41 export const enableTrustedTypesIntegration = false;
42 export const enableNativeTargetAsInstance = false;
43 export const disableCreateFactory = false;
44 +export const disableLegacyReactDOMAPIs = false;
45 export const disableTextareaChildren = false;
46 export const disableMapsAsChildren = false;
47 export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
59 // eslint-disable-next-line no-unused-vars
60 type Check<_X, Y: _X, X: Y = _X> = null;
61 // eslint-disable-next-line no-unused-expressions
61 -(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
62 +(null: Check<ExportsType, FeatureFlagsType>);
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+5 -2
@@ -10,7 +10,7 @@
10 import invariant from 'shared/invariant';
11
12 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13 -import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
13 +import typeof * as ExportsType from './ReactFeatureFlags.test-renderer.www';
14
15 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 export const enableUserTimingAPI = __DEV__;
@@ -22,8 +22,10 @@ export const enableSuspenseServerRenderer = false;
22 export const enableSelectiveHydration = false;
23 export const enableChunksAPI = false;
24 export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
25 +export const warnAboutShorthandPropertyCollision = true;
26 export const enableSchedulerDebugging = false;
27 export const disableJavaScriptURLs = false;
28 +export const disableInputAttributeSyncing = false;
29 export const enableDeprecatedFlareAPI = true;
30 export const enableFundamentalAPI = false;
31 export const enableScopeAPI = true;
@@ -39,6 +41,7 @@ export const enableTrainModelFix = true;
41 export const enableTrustedTypesIntegration = false;
42 export const enableNativeTargetAsInstance = false;
43 export const disableCreateFactory = false;
44 +export const disableLegacyReactDOMAPIs = false;
45 export const disableTextareaChildren = false;
46 export const disableMapsAsChildren = false;
47 export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -56,4 +59,4 @@ export function addUserTimingListener() {
59 // eslint-disable-next-line no-unused-vars
60 type Check<_X, Y: _X, X: Y = _X> = null;
61 // eslint-disable-next-line no-unused-expressions
59 -(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
62 +(null: Check<ExportsType, FeatureFlagsType>);
packages/shared/forks/ReactFeatureFlags.testing.js
+3 -2
@@ -10,7 +10,7 @@
10 import invariant from 'shared/invariant';
11
12 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13 -import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
13 +import typeof * as ExportsType from './ReactFeatureFlags.testing';
14
15 export const debugRenderPhaseSideEffectsForStrictMode = false;
16 export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
41 export const enableTrustedTypesIntegration = false;
42 export const enableNativeTargetAsInstance = false;
43 export const disableCreateFactory = false;
44 +export const disableLegacyReactDOMAPIs = false;
45 export const disableTextareaChildren = false;
46 export const disableMapsAsChildren = false;
47 export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
59 // eslint-disable-next-line no-unused-vars
60 type Check<_X, Y: _X, X: Y = _X> = null;
61 // eslint-disable-next-line no-unused-expressions
61 -(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
62 +(null: Check<ExportsType, FeatureFlagsType>);
packages/shared/forks/ReactFeatureFlags.testing.www.js new
+62
@@ -0,0 +1,62 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its 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 invariant from 'shared/invariant';
11 +
12 +import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
13 +import typeof * as ExportsType from './ReactFeatureFlags.testing.www';
14 +
15 +export const debugRenderPhaseSideEffectsForStrictMode = false;
16 +export const enableUserTimingAPI = false;
17 +export const warnAboutDeprecatedLifecycles = true;
18 +export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
19 +export const enableProfilerTimer = false;
20 +export const enableSchedulerTracing = false;
21 +export const enableSuspenseServerRenderer = true;
22 +export const enableSelectiveHydration = true;
23 +export const enableChunksAPI = true;
24 +export const disableJavaScriptURLs = true;
25 +export const disableInputAttributeSyncing = false;
26 +export const exposeConcurrentModeAPIs = true;
27 +export const warnAboutShorthandPropertyCollision = true;
28 +export const enableSchedulerDebugging = false;
29 +export const enableDeprecatedFlareAPI = true;
30 +export const enableFundamentalAPI = false;
31 +export const enableScopeAPI = true;
32 +export const enableJSXTransformAPI = true;
33 +export const warnAboutUnmockedScheduler = true;
34 +export const flushSuspenseFallbacksInTests = true;
35 +export const enableSuspenseCallback = true;
36 +export const warnAboutDefaultPropsOnFunctionComponents = false;
37 +export const warnAboutStringRefs = false;
38 +export const disableLegacyContext = __EXPERIMENTAL__;
39 +export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
40 +export const enableTrainModelFix = true;
41 +export const enableTrustedTypesIntegration = false;
42 +export const enableNativeTargetAsInstance = false;
43 +export const disableCreateFactory = __EXPERIMENTAL__;
44 +export const disableLegacyReactDOMAPIs = __EXPERIMENTAL__;
45 +export const disableTextareaChildren = __EXPERIMENTAL__;
46 +export const disableMapsAsChildren = __EXPERIMENTAL__;
47 +export const disableUnstableRenderSubtreeIntoContainer = __EXPERIMENTAL__;
48 +export const warnUnstableRenderSubtreeIntoContainer = false;
49 +export const disableUnstableCreatePortal = __EXPERIMENTAL__;
50 +export const deferPassiveEffectCleanupDuringUnmount = false;
51 +export const isTestEnvironment = true;
52 +
53 +// Only used in www builds.
54 +export function addUserTimingListener() {
55 + invariant(false, 'Not implemented.');
56 +}
57 +
58 +// Flow magic to verify the exports of this file match the original version.
59 +// eslint-disable-next-line no-unused-vars
60 +type Check<_X, Y: _X, X: Y = _X> = null;
61 +// eslint-disable-next-line no-unused-expressions
62 +(null: Check<ExportsType, FeatureFlagsType>);
packages/shared/forks/ReactFeatureFlags.www.js
+16 -11
@@ -8,7 +8,7 @@
8 */
9
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 -import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.www';
11 +import typeof * as ExportsType from './ReactFeatureFlags.www';
12
13 // Re-export dynamic flags from the www version.
14 export const {
@@ -19,13 +19,16 @@ export const {
19 warnAboutShorthandPropertyCollision,
20 } = require('ReactFeatureFlags');
21
22 +// On WWW, __EXPERIMENTAL__ is used for a new modern build.
23 +// It's not used anywhere in production yet.
24 +
25 // In www, we have experimental support for gathering data
26 // from User Timing API calls in production. By default, we
27 // only emit performance.mark/measure calls in __DEV__. But if
28 // somebody calls addUserTimingListener() which is exposed as an
29 // experimental FB-only export, we call performance.mark/measure
30 // as long as there is more than a single listener.
28 -export let enableUserTimingAPI = __DEV__;
31 +export let enableUserTimingAPI = __DEV__ && !__EXPERIMENTAL__;
32
33 export const enableProfilerTimer = __PROFILE__;
34 export const enableSchedulerTracing = __PROFILE__;
@@ -33,19 +36,19 @@ export const enableSchedulerDebugging = true;
36
37 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
38 export const warnAboutDeprecatedLifecycles = true;
36 -export const disableLegacyContext = false;
39 +export const disableLegacyContext = __EXPERIMENTAL__;
40 export const warnAboutStringRefs = false;
41 export const warnAboutDefaultPropsOnFunctionComponents = false;
42 export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
43
44 export const enableTrainModelFix = true;
45
43 -export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
46 +export const exposeConcurrentModeAPIs = true;
47
48 export const enableSuspenseServerRenderer = true;
49 export const enableSelectiveHydration = true;
50
48 -export const enableChunksAPI = __EXPERIMENTAL__;
51 +export const enableChunksAPI = true;
52
53 export const disableJavaScriptURLs = true;
54
@@ -92,17 +95,19 @@ export const flushSuspenseFallbacksInTests = true;
95
96 export const enableNativeTargetAsInstance = false;
97
95 -export const disableCreateFactory = false;
98 +export const disableCreateFactory = __EXPERIMENTAL__;
99 +
100 +export const disableLegacyReactDOMAPIs = __EXPERIMENTAL__;
101
97 -export const disableTextareaChildren = false;
102 +export const disableTextareaChildren = __EXPERIMENTAL__;
103
99 -export const disableMapsAsChildren = false;
104 +export const disableMapsAsChildren = __EXPERIMENTAL__;
105
101 -export const disableUnstableRenderSubtreeIntoContainer = false;
106 +export const disableUnstableRenderSubtreeIntoContainer = __EXPERIMENTAL__;
107
108 export const warnUnstableRenderSubtreeIntoContainer = false;
109
105 -export const disableUnstableCreatePortal = false;
110 +export const disableUnstableCreatePortal = __EXPERIMENTAL__;
111
112 export const isTestEnvironment = false;
113
@@ -110,4 +115,4 @@ export const isTestEnvironment = false;
115 // eslint-disable-next-line no-unused-vars
116 type Check<_X, Y: _X, X: Y = _X> = null;
117 // eslint-disable-next-line no-unused-expressions
113 -(null: Check<FeatureFlagsShimType, FeatureFlagsType>);
118 +(null: Check<ExportsType, FeatureFlagsType>);
scripts/rollup/build.js
+4 -4
@@ -679,17 +679,17 @@ async function buildEverything() {
679 [bundle, NODE_DEV],
680 [bundle, NODE_PROD],
681 [bundle, NODE_PROFILING],
682 + [bundle, FB_WWW_DEV],
683 + [bundle, FB_WWW_PROD],
684 + [bundle, FB_WWW_PROFILING],
685 [bundle, RN_OSS_DEV],
686 [bundle, RN_OSS_PROD],
687 [bundle, RN_OSS_PROFILING]
688 );
689
690 if (__EXPERIMENTAL__) {
688 - // FB specific builds are experimental-only.
691 + // FB-specific RN builds are experimental-only.
692 bundles.push(
690 - [bundle, FB_WWW_DEV],
691 - [bundle, FB_WWW_PROD],
692 - [bundle, FB_WWW_PROFILING],
693 [bundle, RN_FB_DEV],
694 [bundle, RN_FB_PROD],
695 [bundle, RN_FB_PROFILING]
scripts/rollup/forks.js
+6 -1
@@ -107,8 +107,13 @@ const forks = Object.freeze({
107 }
108 return 'shared/forks/ReactFeatureFlags.test-renderer.js';
109 case 'react-dom/testing':
110 - return 'shared/forks/ReactFeatureFlags.testing.js';
110 case 'react/testing':
111 + switch (bundleType) {
112 + case FB_WWW_DEV:
113 + case FB_WWW_PROD:
114 + case FB_WWW_PROFILING:
115 + return 'shared/forks/ReactFeatureFlags.testing.www.js';
116 + }
117 return 'shared/forks/ReactFeatureFlags.testing.js';
118 default:
119 switch (bundleType) {