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.
This commit is contained in:
Dan Abramov
2020-02-13 20:33:53 +00:00
committed by GitHub
parent 58b8797b73
commit 8777b44e98
14 changed files with 143 additions and 49 deletions

View File

@@ -56,6 +56,7 @@ import ReactVersion from 'shared/ReactVersion';
import invariant from 'shared/invariant';
import {
exposeConcurrentModeAPIs,
disableLegacyReactDOMAPIs,
disableUnstableCreatePortal,
disableUnstableRenderSubtreeIntoContainer,
warnUnstableRenderSubtreeIntoContainer,
@@ -133,12 +134,6 @@ function createPortal(
const ReactDOM: Object = {
createPortal,
// Legacy
findDOMNode,
hydrate,
render,
unmountComponentAtNode,
unstable_batchedUpdates: batchedUpdates,
flushSync: flushSync,
@@ -166,6 +161,13 @@ const ReactDOM: Object = {
version: ReactVersion,
};
if (!disableLegacyReactDOMAPIs) {
ReactDOM.findDOMNode = findDOMNode;
ReactDOM.hydrate = hydrate;
ReactDOM.render = render;
ReactDOM.unmountComponentAtNode = unmountComponentAtNode;
}
if (exposeConcurrentModeAPIs) {
ReactDOM.createRoot = createRoot;
ReactDOM.createBlockingRoot = createBlockingRoot;

View File

@@ -13,19 +13,24 @@ import ReactDOM from './ReactDOM';
import {isEnabled} from '../events/ReactBrowserEventEmitter';
import {getClosestInstanceFromNode} from './ReactDOMComponentTree';
Object.assign(
(ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any),
{
// These are real internal dependencies that are trickier to remove:
ReactBrowserEventEmitter: {
isEnabled,
if (__EXPERIMENTAL__) {
// This is a modern WWW build.
// It should be the same as open source. Don't add new things here.
} else {
// For classic WWW builds, include a few internals that are already in use.
Object.assign(
(ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any),
{
ReactBrowserEventEmitter: {
isEnabled,
},
ReactDOMComponentTree: {
getClosestInstanceFromNode,
},
// Perf experiment
addUserTimingListener,
},
ReactDOMComponentTree: {
getClosestInstanceFromNode,
},
// Perf experiment
addUserTimingListener,
},
);
);
}
export default ReactDOM;

View File

@@ -425,7 +425,9 @@ export function createWorkInProgress(
if (__DEV__) {
// DEV-only fields
workInProgress._debugID = current._debugID;
if (enableUserTimingAPI) {
workInProgress._debugID = current._debugID;
}
workInProgress._debugSource = current._debugSource;
workInProgress._debugOwner = current._debugOwner;
workInProgress._debugHookTypes = current._debugHookTypes;
@@ -958,7 +960,9 @@ export function assignFiberPropertiesInDEV(
target.selfBaseDuration = source.selfBaseDuration;
target.treeBaseDuration = source.treeBaseDuration;
}
target._debugID = source._debugID;
if (enableUserTimingAPI) {
target._debugID = source._debugID;
}
target._debugSource = source._debugSource;
target._debugOwner = source._debugOwner;
target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;

View File

@@ -114,6 +114,9 @@ export const disableLegacyContext = false;
// Disables React.createFactory
export const disableCreateFactory = false;
// Disables hydrate, render, findDOMNode, unmountComponentAtNode
export const disableLegacyReactDOMAPIs = false;
// Disables children for <textarea> elements
export const disableTextareaChildren = false;

View File

@@ -10,7 +10,7 @@
import invariant from 'shared/invariant';
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-fb';
import typeof * as ExportsType from './ReactFeatureFlags.native-fb';
// Uncomment to re-export dynamic flags from the fbsource version.
export const {
@@ -46,6 +46,7 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
export const enableTrainModelFix = true;
export const enableTrustedTypesIntegration = false;
export const disableCreateFactory = false;
export const disableLegacyReactDOMAPIs = false;
export const disableTextareaChildren = false;
export const disableMapsAsChildren = false;
export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -63,4 +64,4 @@ export function addUserTimingListener() {
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<FeatureFlagsShimType, FeatureFlagsType>);
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -10,7 +10,7 @@
import invariant from 'shared/invariant';
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-oss';
import typeof * as ExportsType from './ReactFeatureFlags.native-oss';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
export const enableTrustedTypesIntegration = false;
export const enableNativeTargetAsInstance = false;
export const disableCreateFactory = false;
export const disableLegacyReactDOMAPIs = false;
export const disableTextareaChildren = false;
export const disableMapsAsChildren = false;
export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<FeatureFlagsShimType, FeatureFlagsType>);
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -10,7 +10,7 @@
import invariant from 'shared/invariant';
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
import typeof * as ExportsType from './ReactFeatureFlags.persistent';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
export const enableTrustedTypesIntegration = false;
export const enableNativeTargetAsInstance = false;
export const disableCreateFactory = false;
export const disableLegacyReactDOMAPIs = false;
export const disableTextareaChildren = false;
export const disableMapsAsChildren = false;
export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -10,7 +10,7 @@
import invariant from 'shared/invariant';
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
import typeof * as ExportsType from './ReactFeatureFlags.test-renderer';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
export const enableTrustedTypesIntegration = false;
export const enableNativeTargetAsInstance = false;
export const disableCreateFactory = false;
export const disableLegacyReactDOMAPIs = false;
export const disableTextareaChildren = false;
export const disableMapsAsChildren = false;
export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -10,7 +10,7 @@
import invariant from 'shared/invariant';
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
import typeof * as ExportsType from './ReactFeatureFlags.test-renderer.www';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableUserTimingAPI = __DEV__;
@@ -22,8 +22,10 @@ export const enableSuspenseServerRenderer = false;
export const enableSelectiveHydration = false;
export const enableChunksAPI = false;
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
export const warnAboutShorthandPropertyCollision = true;
export const enableSchedulerDebugging = false;
export const disableJavaScriptURLs = false;
export const disableInputAttributeSyncing = false;
export const enableDeprecatedFlareAPI = true;
export const enableFundamentalAPI = false;
export const enableScopeAPI = true;
@@ -39,6 +41,7 @@ export const enableTrainModelFix = true;
export const enableTrustedTypesIntegration = false;
export const enableNativeTargetAsInstance = false;
export const disableCreateFactory = false;
export const disableLegacyReactDOMAPIs = false;
export const disableTextareaChildren = false;
export const disableMapsAsChildren = false;
export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -56,4 +59,4 @@ export function addUserTimingListener() {
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -10,7 +10,7 @@
import invariant from 'shared/invariant';
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persistent';
import typeof * as ExportsType from './ReactFeatureFlags.testing';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableUserTimingAPI = __DEV__;
@@ -41,6 +41,7 @@ export const enableTrainModelFix = true;
export const enableTrustedTypesIntegration = false;
export const enableNativeTargetAsInstance = false;
export const disableCreateFactory = false;
export const disableLegacyReactDOMAPIs = false;
export const disableTextareaChildren = false;
export const disableMapsAsChildren = false;
export const disableUnstableRenderSubtreeIntoContainer = false;
@@ -58,4 +59,4 @@ export function addUserTimingListener() {
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<PersistentFeatureFlagsType, FeatureFlagsType>);
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -0,0 +1,62 @@
/**
* 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 invariant from 'shared/invariant';
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as ExportsType from './ReactFeatureFlags.testing.www';
export const debugRenderPhaseSideEffectsForStrictMode = false;
export const enableUserTimingAPI = false;
export const warnAboutDeprecatedLifecycles = true;
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
export const enableProfilerTimer = false;
export const enableSchedulerTracing = false;
export const enableSuspenseServerRenderer = true;
export const enableSelectiveHydration = true;
export const enableChunksAPI = true;
export const disableJavaScriptURLs = true;
export const disableInputAttributeSyncing = false;
export const exposeConcurrentModeAPIs = true;
export const warnAboutShorthandPropertyCollision = true;
export const enableSchedulerDebugging = false;
export const enableDeprecatedFlareAPI = true;
export const enableFundamentalAPI = false;
export const enableScopeAPI = true;
export const enableJSXTransformAPI = true;
export const warnAboutUnmockedScheduler = true;
export const flushSuspenseFallbacksInTests = true;
export const enableSuspenseCallback = true;
export const warnAboutDefaultPropsOnFunctionComponents = false;
export const warnAboutStringRefs = false;
export const disableLegacyContext = __EXPERIMENTAL__;
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
export const enableTrainModelFix = true;
export const enableTrustedTypesIntegration = false;
export const enableNativeTargetAsInstance = false;
export const disableCreateFactory = __EXPERIMENTAL__;
export const disableLegacyReactDOMAPIs = __EXPERIMENTAL__;
export const disableTextareaChildren = __EXPERIMENTAL__;
export const disableMapsAsChildren = __EXPERIMENTAL__;
export const disableUnstableRenderSubtreeIntoContainer = __EXPERIMENTAL__;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = __EXPERIMENTAL__;
export const deferPassiveEffectCleanupDuringUnmount = false;
export const isTestEnvironment = true;
// Only used in www builds.
export function addUserTimingListener() {
invariant(false, 'Not implemented.');
}
// Flow magic to verify the exports of this file match the original version.
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -8,7 +8,7 @@
*/
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.www';
import typeof * as ExportsType from './ReactFeatureFlags.www';
// Re-export dynamic flags from the www version.
export const {
@@ -19,13 +19,16 @@ export const {
warnAboutShorthandPropertyCollision,
} = require('ReactFeatureFlags');
// On WWW, __EXPERIMENTAL__ is used for a new modern build.
// It's not used anywhere in production yet.
// In www, we have experimental support for gathering data
// from User Timing API calls in production. By default, we
// only emit performance.mark/measure calls in __DEV__. But if
// somebody calls addUserTimingListener() which is exposed as an
// experimental FB-only export, we call performance.mark/measure
// as long as there is more than a single listener.
export let enableUserTimingAPI = __DEV__;
export let enableUserTimingAPI = __DEV__ && !__EXPERIMENTAL__;
export const enableProfilerTimer = __PROFILE__;
export const enableSchedulerTracing = __PROFILE__;
@@ -33,19 +36,19 @@ export const enableSchedulerDebugging = true;
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
export const warnAboutDeprecatedLifecycles = true;
export const disableLegacyContext = false;
export const disableLegacyContext = __EXPERIMENTAL__;
export const warnAboutStringRefs = false;
export const warnAboutDefaultPropsOnFunctionComponents = false;
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
export const enableTrainModelFix = true;
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
export const exposeConcurrentModeAPIs = true;
export const enableSuspenseServerRenderer = true;
export const enableSelectiveHydration = true;
export const enableChunksAPI = __EXPERIMENTAL__;
export const enableChunksAPI = true;
export const disableJavaScriptURLs = true;
@@ -92,17 +95,19 @@ export const flushSuspenseFallbacksInTests = true;
export const enableNativeTargetAsInstance = false;
export const disableCreateFactory = false;
export const disableCreateFactory = __EXPERIMENTAL__;
export const disableTextareaChildren = false;
export const disableLegacyReactDOMAPIs = __EXPERIMENTAL__;
export const disableMapsAsChildren = false;
export const disableTextareaChildren = __EXPERIMENTAL__;
export const disableUnstableRenderSubtreeIntoContainer = false;
export const disableMapsAsChildren = __EXPERIMENTAL__;
export const disableUnstableRenderSubtreeIntoContainer = __EXPERIMENTAL__;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const disableUnstableCreatePortal = false;
export const disableUnstableCreatePortal = __EXPERIMENTAL__;
export const isTestEnvironment = false;
@@ -110,4 +115,4 @@ export const isTestEnvironment = false;
// eslint-disable-next-line no-unused-vars
type Check<_X, Y: _X, X: Y = _X> = null;
// eslint-disable-next-line no-unused-expressions
(null: Check<FeatureFlagsShimType, FeatureFlagsType>);
(null: Check<ExportsType, FeatureFlagsType>);

View File

@@ -679,17 +679,17 @@ async function buildEverything() {
[bundle, NODE_DEV],
[bundle, NODE_PROD],
[bundle, NODE_PROFILING],
[bundle, FB_WWW_DEV],
[bundle, FB_WWW_PROD],
[bundle, FB_WWW_PROFILING],
[bundle, RN_OSS_DEV],
[bundle, RN_OSS_PROD],
[bundle, RN_OSS_PROFILING]
);
if (__EXPERIMENTAL__) {
// FB specific builds are experimental-only.
// FB-specific RN builds are experimental-only.
bundles.push(
[bundle, FB_WWW_DEV],
[bundle, FB_WWW_PROD],
[bundle, FB_WWW_PROFILING],
[bundle, RN_FB_DEV],
[bundle, RN_FB_PROD],
[bundle, RN_FB_PROFILING]

View File

@@ -107,8 +107,13 @@ const forks = Object.freeze({
}
return 'shared/forks/ReactFeatureFlags.test-renderer.js';
case 'react-dom/testing':
return 'shared/forks/ReactFeatureFlags.testing.js';
case 'react/testing':
switch (bundleType) {
case FB_WWW_DEV:
case FB_WWW_PROD:
case FB_WWW_PROFILING:
return 'shared/forks/ReactFeatureFlags.testing.www.js';
}
return 'shared/forks/ReactFeatureFlags.testing.js';
default:
switch (bundleType) {