[Flight] Add option to replay console logs or not (#30207)
Defaults to true in browser builds, otherwise defaults to false. The assumption is that the server logs will already contain a log from the original Flight server. We currently always replay console logs but this leads to duplicates on the server by default when you use SSR, because the Flight Client on the server replays the logs. This can be nice since those logs gets badged. It can also be nice if they're running in separate servers but when they're logging to the same stream it's annoying. Which is really the typical set up so we should just make that the default but leave it configurable.
Sebastian Markbåge committed
Jul 4, 2024 at 12:15 UTC
8e9de898d3a8a0945fcdc1a02959560bce2bbc30
11 files changed
+36
-1
packages/react-client/src/ReactFlightClient.js
+9
@@ -250,6 +250,7 @@ export type Response = {
250
_tempRefs: void | TemporaryReferenceSet, // the set temporary references can be resolved from
251
_debugRootTask?: null | ConsoleTask, // DEV-only
252
_debugFindSourceMapURL?: void | FindSourceMapURLCallback, // DEV-only
253
+ _replayConsole: boolean, // DEV-only
254
};
255
256
function readChunk<T>(chunk: SomeChunk<T>): T {
@@ -1278,6 +1279,7 @@ function ResponseInstance(
1279
nonce: void | string,
1280
temporaryReferences: void | TemporaryReferenceSet,
1281
findSourceMapURL: void | FindSourceMapURLCallback,
1282
+ replayConsole: boolean,
1283
) {
1284
const chunks: Map<number, SomeChunk<any>> = new Map();
1285
this._bundlerConfig = bundlerConfig;
@@ -1304,6 +1306,7 @@ function ResponseInstance(
1306
}
1307
if (__DEV__) {
1308
this._debugFindSourceMapURL = findSourceMapURL;
1309
+ this._replayConsole = replayConsole;
1310
}
1311
// Don't inline this call because it causes closure to outline the call above.
1312
this._fromJSON = createFromJSONCallback(this);
@@ -1317,6 +1320,7 @@ export function createResponse(
1320
nonce: void | string,
1321
temporaryReferences: void | TemporaryReferenceSet,
1322
findSourceMapURL: void | FindSourceMapURLCallback,
1323
+ replayConsole: boolean,
1324
): Response {
1325
// $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors
1326
return new ResponseInstance(
@@ -1327,6 +1331,7 @@ export function createResponse(
1331
nonce,
1332
temporaryReferences,
1333
findSourceMapURL,
1334
+ replayConsole,
1335
);
1336
}
1337
@@ -2034,6 +2039,10 @@ function resolveConsoleEntry(
2039
);
2040
}
2041
2042
+ if (!response._replayConsole) {
2043
+ return;
2044
+ }
2045
+
2046
const payload: [string, string, null | ReactComponentInfo, string, mixed] =
2047
parseModel(response, value);
2048
const methodName = payload[0];
packages/react-html/src/ReactHTMLServer.js
+1
@@ -179,6 +179,7 @@ export function renderToMarkup(
179
undefined,
180
undefined,
181
undefined,
182
+ false,
183
);
184
const resumableState = createResumableState(
185
options ? options.identifierPrefix : undefined,
packages/react-noop-renderer/src/ReactNoopFlightClient.js
+10
-1
@@ -50,7 +50,16 @@ const {createResponse, processBinaryChunk, getRoot, close} = ReactFlightClient({
50
});
51
52
function read<T>(source: Source): Thenable<T> {
53
- const response = createResponse(source, null);
53
+ const response = createResponse(
54
+ source,
55
+ null,
56
+ undefined,
57
+ undefined,
58
+ undefined,
59
+ undefined,
60
+ undefined,
61
+ true,
62
+ );
63
for (let i = 0; i < source.length; i++) {
64
processBinaryChunk(response, source[i], 0);
65
}
packages/react-server-dom-esm/src/ReactFlightDOMClientBrowser.js
+2
@@ -42,6 +42,7 @@ export type Options = {
42
callServer?: CallServerCallback,
43
temporaryReferences?: TemporaryReferenceSet,
44
findSourceMapURL?: FindSourceMapURLCallback,
45
+ replayConsoleLogs?: boolean,
46
};
47
48
function createResponseFromOptions(options: void | Options) {
@@ -57,6 +58,7 @@ function createResponseFromOptions(options: void | Options) {
58
__DEV__ && options && options.findSourceMapURL
59
? options.findSourceMapURL
60
: undefined,
61
+ __DEV__ ? (options ? options.replayConsoleLogs !== false : true) : false, // defaults to true
62
);
63
}
64
packages/react-server-dom-esm/src/ReactFlightDOMClientNode.js
+2
@@ -50,6 +50,7 @@ export type Options = {
50
nonce?: string,
51
encodeFormAction?: EncodeFormActionCallback,
52
findSourceMapURL?: FindSourceMapURLCallback,
53
+ replayConsoleLogs?: boolean,
54
};
55
56
function createFromNodeStream<T>(
@@ -68,6 +69,7 @@ function createFromNodeStream<T>(
69
__DEV__ && options && options.findSourceMapURL
70
? options.findSourceMapURL
71
: undefined,
72
+ __DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
73
);
74
stream.on('data', chunk => {
75
processBinaryChunk(response, chunk);
packages/react-server-dom-turbopack/src/ReactFlightDOMClientBrowser.js
+2
@@ -41,6 +41,7 @@ export type Options = {
41
callServer?: CallServerCallback,
42
temporaryReferences?: TemporaryReferenceSet,
43
findSourceMapURL?: FindSourceMapURLCallback,
44
+ replayConsoleLogs?: boolean,
45
};
46
47
function createResponseFromOptions(options: void | Options) {
@@ -56,6 +57,7 @@ function createResponseFromOptions(options: void | Options) {
57
__DEV__ && options && options.findSourceMapURL
58
? options.findSourceMapURL
59
: undefined,
60
+ __DEV__ ? (options ? options.replayConsoleLogs !== false : true) : false, // defaults to true
61
);
62
}
63
packages/react-server-dom-turbopack/src/ReactFlightDOMClientEdge.js
+2
@@ -71,6 +71,7 @@ export type Options = {
71
encodeFormAction?: EncodeFormActionCallback,
72
temporaryReferences?: TemporaryReferenceSet,
73
findSourceMapURL?: FindSourceMapURLCallback,
74
+ replayConsoleLogs?: boolean,
75
};
76
77
function createResponseFromOptions(options: Options) {
@@ -86,6 +87,7 @@ function createResponseFromOptions(options: Options) {
87
__DEV__ && options && options.findSourceMapURL
88
? options.findSourceMapURL
89
: undefined,
90
+ __DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
91
);
92
}
93
packages/react-server-dom-turbopack/src/ReactFlightDOMClientNode.js
+2
@@ -60,6 +60,7 @@ export type Options = {
60
nonce?: string,
61
encodeFormAction?: EncodeFormActionCallback,
62
findSourceMapURL?: FindSourceMapURLCallback,
63
+ replayConsoleLogs?: boolean,
64
};
65
66
function createFromNodeStream<T>(
@@ -77,6 +78,7 @@ function createFromNodeStream<T>(
78
__DEV__ && options && options.findSourceMapURL
79
? options.findSourceMapURL
80
: undefined,
81
+ __DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
82
);
83
stream.on('data', chunk => {
84
processBinaryChunk(response, chunk);
packages/react-server-dom-webpack/src/ReactFlightDOMClientBrowser.js
+2
@@ -41,6 +41,7 @@ export type Options = {
41
callServer?: CallServerCallback,
42
temporaryReferences?: TemporaryReferenceSet,
43
findSourceMapURL?: FindSourceMapURLCallback,
44
+ replayConsoleLogs?: boolean,
45
};
46
47
function createResponseFromOptions(options: void | Options) {
@@ -56,6 +57,7 @@ function createResponseFromOptions(options: void | Options) {
57
__DEV__ && options && options.findSourceMapURL
58
? options.findSourceMapURL
59
: undefined,
60
+ __DEV__ ? (options ? options.replayConsoleLogs !== false : true) : false, // defaults to true
61
);
62
}
63
packages/react-server-dom-webpack/src/ReactFlightDOMClientEdge.js
+2
@@ -71,6 +71,7 @@ export type Options = {
71
encodeFormAction?: EncodeFormActionCallback,
72
temporaryReferences?: TemporaryReferenceSet,
73
findSourceMapURL?: FindSourceMapURLCallback,
74
+ replayConsoleLogs?: boolean,
75
};
76
77
function createResponseFromOptions(options: Options) {
@@ -86,6 +87,7 @@ function createResponseFromOptions(options: Options) {
87
__DEV__ && options && options.findSourceMapURL
88
? options.findSourceMapURL
89
: undefined,
90
+ __DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
91
);
92
}
93
packages/react-server-dom-webpack/src/ReactFlightDOMClientNode.js
+2
@@ -61,6 +61,7 @@ export type Options = {
61
nonce?: string,
62
encodeFormAction?: EncodeFormActionCallback,
63
findSourceMapURL?: FindSourceMapURLCallback,
64
+ replayConsoleLogs?: boolean,
65
};
66
67
function createFromNodeStream<T>(
@@ -78,6 +79,7 @@ function createFromNodeStream<T>(
79
__DEV__ && options && options.findSourceMapURL
80
? options.findSourceMapURL
81
: undefined,
82
+ __DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
83
);
84
stream.on('data', chunk => {
85
if (typeof chunk === 'string') {