Add enableSuspenseServerRenderer feature flag (#13573)
This commit is contained in:
parent
4e744be6ee
commit
34348a45b4
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @emails react-core
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils');
|
||||||
|
|
||||||
|
let React;
|
||||||
|
let ReactDOM;
|
||||||
|
let ReactDOMServer;
|
||||||
|
let ReactFeatureFlags;
|
||||||
|
|
||||||
|
function initModules() {
|
||||||
|
// Reset warning cache.
|
||||||
|
jest.resetModuleRegistry();
|
||||||
|
|
||||||
|
ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||||
|
ReactFeatureFlags.enableSuspense = true;
|
||||||
|
ReactFeatureFlags.enableSuspenseServerRenderer = true;
|
||||||
|
|
||||||
|
React = require('react');
|
||||||
|
ReactDOM = require('react-dom');
|
||||||
|
ReactDOMServer = require('react-dom/server');
|
||||||
|
|
||||||
|
// Make them available to the helpers.
|
||||||
|
return {
|
||||||
|
ReactDOM,
|
||||||
|
ReactDOMServer,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const {resetModules, serverRender} = ReactDOMServerIntegrationUtils(
|
||||||
|
initModules,
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('ReactDOMServerPlaceholders', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
resetModules();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should always render the fallback when a placeholder is encountered', async () => {
|
||||||
|
const Suspended = props => {
|
||||||
|
throw new Promise(() => {});
|
||||||
|
};
|
||||||
|
const e = await serverRender(
|
||||||
|
<React.Placeholder fallback={<div />}>
|
||||||
|
<Suspended />
|
||||||
|
</React.Placeholder>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(e.tagName).toBe('DIV');
|
||||||
|
});
|
||||||
|
});
|
|
@ -23,12 +23,17 @@ import warningWithoutStack from 'shared/warningWithoutStack';
|
||||||
import checkPropTypes from 'prop-types/checkPropTypes';
|
import checkPropTypes from 'prop-types/checkPropTypes';
|
||||||
import describeComponentFrame from 'shared/describeComponentFrame';
|
import describeComponentFrame from 'shared/describeComponentFrame';
|
||||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||||
import {warnAboutDeprecatedLifecycles} from 'shared/ReactFeatureFlags';
|
import {
|
||||||
|
warnAboutDeprecatedLifecycles,
|
||||||
|
enableSuspenseServerRenderer,
|
||||||
|
} from 'shared/ReactFeatureFlags';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
REACT_FORWARD_REF_TYPE,
|
REACT_FORWARD_REF_TYPE,
|
||||||
REACT_FRAGMENT_TYPE,
|
REACT_FRAGMENT_TYPE,
|
||||||
REACT_STRICT_MODE_TYPE,
|
REACT_STRICT_MODE_TYPE,
|
||||||
REACT_ASYNC_MODE_TYPE,
|
REACT_ASYNC_MODE_TYPE,
|
||||||
|
REACT_PLACEHOLDER_TYPE,
|
||||||
REACT_PORTAL_TYPE,
|
REACT_PORTAL_TYPE,
|
||||||
REACT_PROFILER_TYPE,
|
REACT_PROFILER_TYPE,
|
||||||
REACT_PROVIDER_TYPE,
|
REACT_PROVIDER_TYPE,
|
||||||
|
@ -911,6 +916,27 @@ class ReactDOMServerRenderer {
|
||||||
this.stack.push(frame);
|
this.stack.push(frame);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
case REACT_PLACEHOLDER_TYPE: {
|
||||||
|
if (enableSuspenseServerRenderer) {
|
||||||
|
const nextChildren = toArray(
|
||||||
|
// Always use the fallback when synchronously rendering to string.
|
||||||
|
((nextChild: any): ReactElement).props.fallback,
|
||||||
|
);
|
||||||
|
const frame: Frame = {
|
||||||
|
type: null,
|
||||||
|
domNamespace: parentNamespace,
|
||||||
|
children: nextChildren,
|
||||||
|
childIndex: 0,
|
||||||
|
context: context,
|
||||||
|
footer: '',
|
||||||
|
};
|
||||||
|
if (__DEV__) {
|
||||||
|
((frame: any): FrameDev).debugElementStack = [];
|
||||||
|
}
|
||||||
|
this.stack.push(frame);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
// eslint-disable-next-line-no-fallthrough
|
// eslint-disable-next-line-no-fallthrough
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -42,6 +42,9 @@ export const enableProfilerTimer = __PROFILE__;
|
||||||
// Track which interactions trigger each commit.
|
// Track which interactions trigger each commit.
|
||||||
export const enableSchedulerTracking = __PROFILE__;
|
export const enableSchedulerTracking = __PROFILE__;
|
||||||
|
|
||||||
|
// Only used in www builds.
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
invariant(false, 'Not implemented.');
|
invariant(false, 'Not implemented.');
|
||||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = __DEV__;
|
||||||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
||||||
export const enableProfilerTimer = __PROFILE__;
|
export const enableProfilerTimer = __PROFILE__;
|
||||||
export const enableSchedulerTracking = __PROFILE__;
|
export const enableSchedulerTracking = __PROFILE__;
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
||||||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
||||||
export const enableProfilerTimer = __PROFILE__;
|
export const enableProfilerTimer = __PROFILE__;
|
||||||
export const enableSchedulerTracking = __PROFILE__;
|
export const enableSchedulerTracking = __PROFILE__;
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
|
|
|
@ -27,6 +27,7 @@ export const enableUserTimingAPI = __DEV__;
|
||||||
export const warnAboutLegacyContextAPI = __DEV__;
|
export const warnAboutLegacyContextAPI = __DEV__;
|
||||||
export const enableProfilerTimer = __PROFILE__;
|
export const enableProfilerTimer = __PROFILE__;
|
||||||
export const enableSchedulerTracking = __PROFILE__;
|
export const enableSchedulerTracking = __PROFILE__;
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutDeprecatedLifecycles = false;
|
||||||
export const warnAboutLegacyContextAPI = false;
|
export const warnAboutLegacyContextAPI = false;
|
||||||
export const enableProfilerTimer = __PROFILE__;
|
export const enableProfilerTimer = __PROFILE__;
|
||||||
export const enableSchedulerTracking = __PROFILE__;
|
export const enableSchedulerTracking = __PROFILE__;
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
||||||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
|
||||||
export const enableProfilerTimer = __PROFILE__;
|
export const enableProfilerTimer = __PROFILE__;
|
||||||
export const enableSchedulerTracking = __PROFILE__;
|
export const enableSchedulerTracking = __PROFILE__;
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
||||||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
|
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
|
||||||
export const enableProfilerTimer = false;
|
export const enableProfilerTimer = false;
|
||||||
export const enableSchedulerTracking = false;
|
export const enableSchedulerTracking = false;
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
|
|
|
@ -22,6 +22,7 @@ export const warnAboutLegacyContextAPI = false;
|
||||||
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
|
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
|
||||||
export const enableProfilerTimer = false;
|
export const enableProfilerTimer = false;
|
||||||
export const enableSchedulerTracking = false;
|
export const enableSchedulerTracking = false;
|
||||||
|
export const enableSuspenseServerRenderer = false;
|
||||||
|
|
||||||
// Only used in www builds.
|
// Only used in www builds.
|
||||||
export function addUserTimingListener() {
|
export function addUserTimingListener() {
|
||||||
|
|
|
@ -16,6 +16,7 @@ export const {
|
||||||
debugRenderPhaseSideEffects,
|
debugRenderPhaseSideEffects,
|
||||||
debugRenderPhaseSideEffectsForStrictMode,
|
debugRenderPhaseSideEffectsForStrictMode,
|
||||||
enableGetDerivedStateFromCatch,
|
enableGetDerivedStateFromCatch,
|
||||||
|
enableSuspenseServerRenderer,
|
||||||
replayFailedUnitOfWorkWithInvokeGuardedCallback,
|
replayFailedUnitOfWorkWithInvokeGuardedCallback,
|
||||||
warnAboutDeprecatedLifecycles,
|
warnAboutDeprecatedLifecycles,
|
||||||
} = require('ReactFeatureFlags');
|
} = require('ReactFeatureFlags');
|
||||||
|
|
Loading…
Reference in New Issue