Skip to content

Commit 269ac62

Browse files
committed
Previously it was possilbe to postpone in the shell during a prerender and then during a resume the bootstrap scripts would not be emitted leading to no hydration on the client. This change moves the bootstrap configuration to ResumableState where it can be serialized after postponing if it wasn't flushed as part of the static shell.
1 parent 88b00de commit 269ac62

11 files changed

Lines changed: 51 additions & 35 deletions

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

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,13 @@ export type ResumableState = {
245245
nextFormID: number,
246246
streamingFormat: StreamingFormat,
247247

248+
// We carry the bootstrap intializers in resumable state in case we postpone in the shell
249+
// of a prerender. On resume we will reinitialize the bootstrap scripts if necessary.
250+
// If we end up flushing the bootstrap scripts we void these on the resumable state
251+
bootstrapScriptContent?: string | void,
252+
bootstrapScripts?: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
253+
bootstrapModules?: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
254+
248255
// state for script streaming format, unused if using external runtime / data
249256
instructions: InstructionState,
250257

@@ -349,9 +356,6 @@ const DEFAULT_HEADERS_CAPACITY_IN_UTF16_CODE_UNITS = 2000;
349356
export function createRenderState(
350357
resumableState: ResumableState,
351358
nonce: string | void,
352-
bootstrapScriptContent: string | void,
353-
bootstrapScripts: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
354-
bootstrapModules: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
355359
externalRuntimeConfig: string | BootstrapScriptDescriptor | void,
356360
importMap: ImportMap | void,
357361
onHeaders: void | ((headers: HeadersDescriptor) => void),
@@ -367,6 +371,8 @@ export function createRenderState(
367371

368372
const bootstrapChunks: Array<Chunk | PrecomputedChunk> = [];
369373
let externalRuntimeScript: null | ExternalRuntimeScript = null;
374+
const {bootstrapScriptContent, bootstrapScripts, bootstrapModules} =
375+
resumableState;
370376
if (bootstrapScriptContent !== undefined) {
371377
bootstrapChunks.push(
372378
inlineScriptWithNonce,
@@ -612,9 +618,6 @@ export function resumeRenderState(
612618
return createRenderState(
613619
resumableState,
614620
nonce,
615-
// These should have already been flushed in the prerender.
616-
undefined,
617-
undefined,
618621
undefined,
619622
undefined,
620623
undefined,
@@ -625,6 +628,9 @@ export function resumeRenderState(
625628
export function createResumableState(
626629
identifierPrefix: string | void,
627630
externalRuntimeConfig: string | BootstrapScriptDescriptor | void,
631+
bootstrapScriptContent: string | void,
632+
bootstrapScripts: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
633+
bootstrapModules: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
628634
): ResumableState {
629635
const idPrefix = identifierPrefix === undefined ? '' : identifierPrefix;
630636

@@ -638,6 +644,9 @@ export function createResumableState(
638644
idPrefix: idPrefix,
639645
nextFormID: 0,
640646
streamingFormat,
647+
bootstrapScriptContent,
648+
bootstrapScripts,
649+
bootstrapModules,
641650
instructions: NothingSent,
642651
hasBody: false,
643652
hasHtml: false,
@@ -3714,7 +3723,11 @@ export function pushEndInstance(
37143723
function writeBootstrap(
37153724
destination: Destination,
37163725
renderState: RenderState,
3726+
resumableState: ResumableState,
37173727
): boolean {
3728+
resumableState.bootstrapScriptContent = undefined;
3729+
resumableState.bootstrapScripts = undefined;
3730+
resumableState.bootstrapModules = undefined;
37183731
const bootstrapChunks = renderState.bootstrapChunks;
37193732
let i = 0;
37203733
for (; i < bootstrapChunks.length - 1; i++) {
@@ -3731,8 +3744,9 @@ function writeBootstrap(
37313744
export function writeCompletedRoot(
37323745
destination: Destination,
37333746
renderState: RenderState,
3747+
resumableState: ResumableState,
37343748
): boolean {
3735-
return writeBootstrap(destination, renderState);
3749+
return writeBootstrap(destination, renderState, resumableState);
37363750
}
37373751

37383752
// Structural Nodes
@@ -4197,7 +4211,7 @@ export function writeCompletedBoundaryInstruction(
41974211
} else {
41984212
writeMore = writeChunkAndReturn(destination, completeBoundaryDataEnd);
41994213
}
4200-
return writeBootstrap(destination, renderState) && writeMore;
4214+
return writeBootstrap(destination, renderState, resumableState) && writeMore;
42014215
}
42024216

42034217
const clientRenderScript1Full = stringToPrecomputedChunk(

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ export function createRenderState(
9292
undefined,
9393
undefined,
9494
undefined,
95-
undefined,
96-
undefined,
9795
);
9896
return {
9997
// Keep this in sync with ReactFizzConfigDOM

packages/react-dom/src/server/ReactDOMFizzServerBrowser.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,16 @@ function renderToReadableStream(
114114
const resumableState = createResumableState(
115115
options ? options.identifierPrefix : undefined,
116116
options ? options.unstable_externalRuntimeSrc : undefined,
117+
options ? options.bootstrapScriptContent : undefined,
118+
options ? options.bootstrapScripts : undefined,
119+
options ? options.bootstrapModules : undefined,
117120
);
118121
const request = createRequest(
119122
children,
120123
resumableState,
121124
createRenderState(
122125
resumableState,
123126
options ? options.nonce : undefined,
124-
options ? options.bootstrapScriptContent : undefined,
125-
options ? options.bootstrapScripts : undefined,
126-
options ? options.bootstrapModules : undefined,
127127
options ? options.unstable_externalRuntimeSrc : undefined,
128128
options ? options.importMap : undefined,
129129
onHeadersImpl,

packages/react-dom/src/server/ReactDOMFizzServerBun.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,16 @@ function renderToReadableStream(
104104
const resumableState = createResumableState(
105105
options ? options.identifierPrefix : undefined,
106106
options ? options.unstable_externalRuntimeSrc : undefined,
107+
options ? options.bootstrapScriptContent : undefined,
108+
options ? options.bootstrapScripts : undefined,
109+
options ? options.bootstrapModules : undefined,
107110
);
108111
const request = createRequest(
109112
children,
110113
resumableState,
111114
createRenderState(
112115
resumableState,
113116
options ? options.nonce : undefined,
114-
options ? options.bootstrapScriptContent : undefined,
115-
options ? options.bootstrapScripts : undefined,
116-
options ? options.bootstrapModules : undefined,
117117
options ? options.unstable_externalRuntimeSrc : undefined,
118118
options ? options.importMap : undefined,
119119
onHeadersImpl,

packages/react-dom/src/server/ReactDOMFizzServerEdge.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,16 @@ function renderToReadableStream(
114114
const resumableState = createResumableState(
115115
options ? options.identifierPrefix : undefined,
116116
options ? options.unstable_externalRuntimeSrc : undefined,
117+
options ? options.bootstrapScriptContent : undefined,
118+
options ? options.bootstrapScripts : undefined,
119+
options ? options.bootstrapModules : undefined,
117120
);
118121
const request = createRequest(
119122
children,
120123
resumableState,
121124
createRenderState(
122125
resumableState,
123126
options ? options.nonce : undefined,
124-
options ? options.bootstrapScriptContent : undefined,
125-
options ? options.bootstrapScripts : undefined,
126-
options ? options.bootstrapModules : undefined,
127127
options ? options.unstable_externalRuntimeSrc : undefined,
128128
options ? options.importMap : undefined,
129129
onHeadersImpl,

packages/react-dom/src/server/ReactDOMFizzServerNode.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,16 @@ function createRequestImpl(children: ReactNodeList, options: void | Options) {
8888
const resumableState = createResumableState(
8989
options ? options.identifierPrefix : undefined,
9090
options ? options.unstable_externalRuntimeSrc : undefined,
91+
options ? options.bootstrapScriptContent : undefined,
92+
options ? options.bootstrapScripts : undefined,
93+
options ? options.bootstrapModules : undefined,
9194
);
9295
return createRequest(
9396
children,
9497
resumableState,
9598
createRenderState(
9699
resumableState,
97100
options ? options.nonce : undefined,
98-
options ? options.bootstrapScriptContent : undefined,
99-
options ? options.bootstrapScripts : undefined,
100-
options ? options.bootstrapModules : undefined,
101101
options ? options.unstable_externalRuntimeSrc : undefined,
102102
options ? options.importMap : undefined,
103103
options ? options.onHeaders : undefined,

packages/react-dom/src/server/ReactDOMFizzStaticBrowser.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,16 @@ function prerender(
9494
const resources = createResumableState(
9595
options ? options.identifierPrefix : undefined,
9696
options ? options.unstable_externalRuntimeSrc : undefined,
97+
options ? options.bootstrapScriptContent : undefined,
98+
options ? options.bootstrapScripts : undefined,
99+
options ? options.bootstrapModules : undefined,
97100
);
98101
const request = createPrerenderRequest(
99102
children,
100103
resources,
101104
createRenderState(
102105
resources,
103106
undefined, // nonce is not compatible with prerendered bootstrap scripts
104-
options ? options.bootstrapScriptContent : undefined,
105-
options ? options.bootstrapScripts : undefined,
106-
options ? options.bootstrapModules : undefined,
107107
options ? options.unstable_externalRuntimeSrc : undefined,
108108
options ? options.importMap : undefined,
109109
onHeadersImpl,

packages/react-dom/src/server/ReactDOMFizzStaticEdge.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,16 @@ function prerender(
9393
const resources = createResumableState(
9494
options ? options.identifierPrefix : undefined,
9595
options ? options.unstable_externalRuntimeSrc : undefined,
96+
options ? options.bootstrapScriptContent : undefined,
97+
options ? options.bootstrapScripts : undefined,
98+
options ? options.bootstrapModules : undefined,
9699
);
97100
const request = createPrerenderRequest(
98101
children,
99102
resources,
100103
createRenderState(
101104
resources,
102105
undefined, // nonce is not compatible with prerendered bootstrap scripts
103-
options ? options.bootstrapScriptContent : undefined,
104-
options ? options.bootstrapScripts : undefined,
105-
options ? options.bootstrapModules : undefined,
106106
options ? options.unstable_externalRuntimeSrc : undefined,
107107
options ? options.importMap : undefined,
108108
onHeadersImpl,

packages/react-dom/src/server/ReactDOMFizzStaticNode.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,16 @@ function prerenderToNodeStream(
9494
const resumableState = createResumableState(
9595
options ? options.identifierPrefix : undefined,
9696
options ? options.unstable_externalRuntimeSrc : undefined,
97+
options ? options.bootstrapScriptContent : undefined,
98+
options ? options.bootstrapScripts : undefined,
99+
options ? options.bootstrapModules : undefined,
97100
);
98101
const request = createPrerenderRequest(
99102
children,
100103
resumableState,
101104
createRenderState(
102105
resumableState,
103106
undefined, // nonce is not compatible with prerendered bootstrap scripts
104-
options ? options.bootstrapScriptContent : undefined,
105-
options ? options.bootstrapScripts : undefined,
106-
options ? options.bootstrapModules : undefined,
107107
options ? options.unstable_externalRuntimeSrc : undefined,
108108
options ? options.importMap : undefined,
109109
options ? options.onHeaders : undefined,

packages/react-server-dom-fb/src/ReactDOMServerFB.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,16 @@ function renderToStream(children: ReactNodeList, options: Options): Stream {
5353
const resumableState = createResumableState(
5454
options ? options.identifierPrefix : undefined,
5555
options ? options.unstable_externalRuntimeSrc : undefined,
56+
options ? options.bootstrapScriptContent : undefined,
57+
options ? options.bootstrapScripts : undefined,
58+
options ? options.bootstrapModules : undefined,
5659
);
5760
const request = createRequest(
5861
children,
5962
resumableState,
6063
createRenderState(
6164
resumableState,
6265
undefined,
63-
options ? options.bootstrapScriptContent : undefined,
64-
options ? options.bootstrapScripts : undefined,
65-
options ? options.bootstrapModules : undefined,
6666
options ? options.unstable_externalRuntimeSrc : undefined,
6767
),
6868
createRootFormatContext(undefined),

0 commit comments

Comments
 (0)