Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 68a25c1

Browse files
committed
Add option to load Fizz runtime from external file
When unstable_externalRuntimeSrc is provided, React will inject a script tag that points to the provided URL. Then, instead of emitting inline scripts, the Fizz stream will emit HTML nodes with data attributes that encode the instructions. The external runtime will detect these with a mutation observer and translate them into runtime commands. This part isn't implemented in this PR, though — all this does is set up the option to use an external runtime, and inject the script tag. The external runtime is injected at the same time as bootstrap scripts.
1 parent b6a5304 commit 68a25c1

File tree

6 files changed

+62
-1
lines changed

6 files changed

+62
-1
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
enableFilterEmptyStringAttributesDOM,
2424
enableCustomElementPropertySupport,
2525
enableFloat,
26+
enableFizzExternalRuntime,
2627
} from 'shared/ReactFeatureFlags';
2728

2829
import type {
@@ -156,6 +157,7 @@ export function createResponseState(
156157
bootstrapScriptContent: string | void,
157158
bootstrapScripts: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
158159
bootstrapModules: $ReadOnlyArray<string | BootstrapScriptDescriptor> | void,
160+
externalRuntimeConfig: string | BootstrapScriptDescriptor | void,
159161
): ResponseState {
160162
const idPrefix = identifierPrefix === undefined ? '' : identifierPrefix;
161163
const inlineScriptWithNonce =
@@ -172,6 +174,29 @@ export function createResponseState(
172174
endInlineScript,
173175
);
174176
}
177+
if (enableFizzExternalRuntime) {
178+
if (externalRuntimeConfig !== undefined) {
179+
const src =
180+
typeof externalRuntimeConfig === 'string'
181+
? externalRuntimeConfig
182+
: externalRuntimeConfig.src;
183+
const integrity =
184+
typeof externalRuntimeConfig === 'string'
185+
? undefined
186+
: externalRuntimeConfig.integrity;
187+
bootstrapChunks.push(
188+
startScriptSrc,
189+
stringToChunk(escapeTextForBrowser(src)),
190+
);
191+
if (integrity) {
192+
bootstrapChunks.push(
193+
scriptIntegirty,
194+
stringToChunk(escapeTextForBrowser(integrity)),
195+
);
196+
}
197+
bootstrapChunks.push(endAsyncScript);
198+
}
199+
}
175200
if (bootstrapScripts !== undefined) {
176201
for (let i = 0; i < bootstrapScripts.length; i++) {
177202
const scriptConfig = bootstrapScripts[i];

packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3546,6 +3546,36 @@ describe('ReactDOMFizzServer', () => {
35463546
});
35473547
});
35483548

3549+
// @gate enableFizzExternalRuntime
3550+
it('supports option to load runtime as an external script', async () => {
3551+
await actIntoEmptyDocument(() => {
3552+
const {pipe} = ReactDOMFizzServer.renderToPipeableStream(
3553+
<html>
3554+
<head />
3555+
<body>
3556+
<div>hello world</div>
3557+
</body>
3558+
</html>,
3559+
{
3560+
unstable_externalRuntimeSrc: 'src-of-external-runtime',
3561+
},
3562+
);
3563+
pipe(writable);
3564+
});
3565+
3566+
expect(getVisibleChildren(document)).toEqual(
3567+
<html>
3568+
<head />
3569+
<body>
3570+
<div>hello world</div>
3571+
</body>
3572+
</html>,
3573+
);
3574+
expect(
3575+
Array.from(document.getElementsByTagName('script')).map(n => n.outerHTML),
3576+
).toEqual(['<script src="src-of-external-runtime" async=""></script>']);
3577+
});
3578+
35493579
it('#24384: Suspending should halt hydration warnings and not emit any if hydration completes successfully after unsuspending', async () => {
35503580
const makeApp = () => {
35513581
let resolve, resolved;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type Options = {
3434
progressiveChunkSize?: number,
3535
signal?: AbortSignal,
3636
onError?: (error: mixed) => ?string,
37-
unstable_externalRuntimeSrc?: string,
37+
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
3838
};
3939

4040
// TODO: Move to sub-classing ReadableStream.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type Options = {
4747
onShellError?: (error: mixed) => void,
4848
onAllReady?: () => void,
4949
onError?: (error: mixed) => ?string,
50+
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
5051
};
5152

5253
type PipeableStream = {
@@ -65,6 +66,7 @@ function createRequestImpl(children: ReactNodeList, options: void | Options) {
6566
options ? options.bootstrapScriptContent : undefined,
6667
options ? options.bootstrapScripts : undefined,
6768
options ? options.bootstrapModules : undefined,
69+
options ? options.unstable_externalRuntimeSrc : undefined,
6870
),
6971
createRootFormatContext(options ? options.namespaceURI : undefined),
7072
options ? options.progressiveChunkSize : undefined,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type Options = {
3333
progressiveChunkSize?: number,
3434
signal?: AbortSignal,
3535
onError?: (error: mixed) => ?string,
36+
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
3637
};
3738

3839
type StaticResult = {
@@ -71,6 +72,7 @@ function prerender(
7172
options ? options.bootstrapScriptContent : undefined,
7273
options ? options.bootstrapScripts : undefined,
7374
options ? options.bootstrapModules : undefined,
75+
options ? options.unstable_externalRuntimeSrc : undefined,
7476
),
7577
createRootFormatContext(options ? options.namespaceURI : undefined),
7678
options ? options.progressiveChunkSize : undefined,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type Options = {
3535
progressiveChunkSize?: number,
3636
signal?: AbortSignal,
3737
onError?: (error: mixed) => ?string,
38+
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
3839
};
3940

4041
type StaticResult = {
@@ -86,6 +87,7 @@ function prerenderToNodeStreams(
8687
options ? options.bootstrapScriptContent : undefined,
8788
options ? options.bootstrapScripts : undefined,
8889
options ? options.bootstrapModules : undefined,
90+
options ? options.unstable_externalRuntimeSrc : undefined,
8991
),
9092
createRootFormatContext(options ? options.namespaceURI : undefined),
9193
options ? options.progressiveChunkSize : undefined,

0 commit comments

Comments
 (0)