[Flight] Eval Fake Server Component Functions to Recreate Native Stacks (#29632)

We have three kinds of stacks that we send in the RSC protocol:

- The stack trace where a replayed `console.log` was called on the
server.
- The JSX callsite that created a Server Component which then later
called another component.
- The JSX callsite that created a Host or Client Component.

These stack frames disappear in native stacks on the client since
they're executed on the server. This evals a fake file which only has
one call in it on the same line/column as the server. Then we call
through these fake modules to "replay" the callstack. We then replay the
`console.log` within this stack, or call `console.createTask` in this
stack to recreate the stack.

The main concern with this approach is the performance. It adds
significant cost to create all these eval:ed functions but it should
eventually balance out.

This doesn't yet apply source maps to these. With source maps it'll be
able to show the server source code when clicking the links.

I don't love how these appear.

- Because we haven't yet initialized the client module we don't have the
name of the client component we're about to render yet which leads to
the `<...>` task name.
- The `(async)` suffix Chrome adds is still a problem.
- The VMxxxx prefix is used to disambiguate which is noisy. Might be
helped by source maps.
- The continuation of the async stacks end up rooted somewhere in the
bootstrapping of the app. This might be ok when the bootstrapping ends
up ignore listed but it's kind of a problem that you can't clear the
async stack.

<img width="927" alt="Screenshot 2024-05-28 at 11 58 56 PM"
src="https://github.com/facebook/react/assets/63648/1c9d32ce-e671-47c8-9d18-9fab3bffabd0">

<img width="431" alt="Screenshot 2024-05-28 at 11 58 07 PM"
src="https://github.com/facebook/react/assets/63648/52f57518-bbed-400e-952d-6650835ac6b6">
<img width="327" alt="Screenshot 2024-05-28 at 11 58 31 PM"
src="https://github.com/facebook/react/assets/63648/d311a639-79a1-457f-9a46-4f3298d07e65">

<img width="817" alt="Screenshot 2024-05-28 at 11 59 12 PM"
src="https://github.com/facebook/react/assets/63648/3aefd356-acf4-4daa-bdbf-b8c8345f6d4b">

DiffTrain build for commit https://github.com/facebook/react/commit/9d4fba078812de0363fe9514b943650fa479e8af.
This commit is contained in:
sebmarkbage
2024-05-30 16:05:37 +00:00
parent 214868dc50
commit 5a9565ddfb
13 changed files with 35 additions and 35 deletions
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<7ca4155a78e484bb791befb0a0483562>>
* @generated SignedSource<<f728e9da1208547ba05fd7713976abe0>>
*/
'use strict';
@@ -23471,7 +23471,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}
var ReactVersion = '19.0.0-rc-fb61a1b515-20240530';
var ReactVersion = '19.0.0-rc-9d4fba0788-20240530';
/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<3467ef5cc029c44f026f965d523ec535>>
* @generated SignedSource<<e95a40579c2846b96a6e76395f6d637a>>
*/
"use strict";
@@ -9298,7 +9298,7 @@ var devToolsConfig$jscomp$inline_1047 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-rc-fb61a1b515-20240530",
version: "19.0.0-rc-9d4fba0788-20240530",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1234 = {
@@ -9329,7 +9329,7 @@ var internals$jscomp$inline_1234 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-fb61a1b515-20240530"
reconcilerVersion: "19.0.0-rc-9d4fba0788-20240530"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1235 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<dcdf0ff67842ef74c5e2d1b33aa75828>>
* @generated SignedSource<<44794162c43d412b2b077d1e2d3b5640>>
*/
"use strict";
@@ -9920,7 +9920,7 @@ var devToolsConfig$jscomp$inline_1130 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-rc-fb61a1b515-20240530",
version: "19.0.0-rc-9d4fba0788-20240530",
rendererPackageName: "react-test-renderer"
};
(function (internals) {
@@ -9964,7 +9964,7 @@ var devToolsConfig$jscomp$inline_1130 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-fb61a1b515-20240530"
reconcilerVersion: "19.0.0-rc-9d4fba0788-20240530"
});
exports._Scheduler = Scheduler;
exports.act = act;
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<236832470786fa8d630f95ea59053100>>
* @generated SignedSource<<5a046d6d586a3f4fd58139e51aee7d61>>
*/
'use strict';
@@ -24,7 +24,7 @@ if (
}
var dynamicFlagsUntyped = require('ReactNativeInternalFeatureFlags');
var ReactVersion = '19.0.0-rc-fb61a1b515-20240530';
var ReactVersion = '19.0.0-rc-9d4fba0788-20240530';
// Re-export dynamic flags from the internal module.
var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<0ad7d99d0ddc3869ed760873fb4a1782>>
* @generated SignedSource<<976630610d17c5c0928e19c7ecf1e254>>
*/
"use strict";
@@ -604,4 +604,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-rc-fb61a1b515-20240530";
exports.version = "19.0.0-rc-9d4fba0788-20240530";
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<e486bd0359a6cb764eff1d066bebd329>>
* @generated SignedSource<<6f2282142152080634990c0581fe12b1>>
*/
"use strict";
@@ -608,7 +608,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactSharedInternals.H.useTransition();
};
exports.version = "19.0.0-rc-fb61a1b515-20240530";
exports.version = "19.0.0-rc-9d4fba0788-20240530";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
@@ -1 +1 @@
fb61a1b515c5ea0e31b0dac19184454a79c4baf1
9d4fba078812de0363fe9514b943650fa479e8af
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<995c3dc1c310eccb6e0c62c1d4d635a7>>
* @generated SignedSource<<5f62d0d6fc378ff4d01037e4c34b1105>>
*/
'use strict';
@@ -26206,7 +26206,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}
var ReactVersion = '19.0.0-rc-fb61a1b515-20240530';
var ReactVersion = '19.0.0-rc-9d4fba0788-20240530';
/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<845d34a6fb2bdf695a5050c565c6b6d8>>
* @generated SignedSource<<728a82421f8c901a2f76a809ae55617c>>
*/
"use strict";
@@ -10551,7 +10551,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1124 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "19.0.0-rc-fb61a1b515-20240530",
version: "19.0.0-rc-9d4fba0788-20240530",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -10594,7 +10594,7 @@ var internals$jscomp$inline_1350 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-fb61a1b515-20240530"
reconcilerVersion: "19.0.0-rc-9d4fba0788-20240530"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1351 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<e6d8bc91c13c8cda3989052069e1ea8f>>
* @generated SignedSource<<35f0f25bfc4e07afd6522eb43b4665b2>>
*/
"use strict";
@@ -11257,7 +11257,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1205 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "19.0.0-rc-fb61a1b515-20240530",
version: "19.0.0-rc-9d4fba0788-20240530",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -11313,7 +11313,7 @@ var roots = new Map(),
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-fb61a1b515-20240530"
reconcilerVersion: "19.0.0-rc-9d4fba0788-20240530"
});
exports.createPortal = function (children, containerTag) {
return createPortal$1(
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<e135c6377058b2f8f0688646d84a7ee7>>
* @generated SignedSource<<6b10942e6f7e436a8dde737bfe07431c>>
*/
'use strict';
@@ -26562,7 +26562,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}
var ReactVersion = '19.0.0-rc-fb61a1b515-20240530';
var ReactVersion = '19.0.0-rc-9d4fba0788-20240530';
/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<f87be2e9c8f672af7046ca562209db03>>
* @generated SignedSource<<008889e85529cc4966c3f8008644b355>>
*/
"use strict";
@@ -10696,11 +10696,11 @@ function traverseOwnerTreeUp(hierarchy, instance) {
traverseOwnerTreeUp(hierarchy, instance);
}
var isomorphicReactPackageVersion = React.version;
if ("19.0.0-rc-fb61a1b515-20240530" !== isomorphicReactPackageVersion)
if ("19.0.0-rc-9d4fba0788-20240530" !== isomorphicReactPackageVersion)
throw Error(
'Incompatible React versions: The "react" and "react-native-renderer" packages must have the exact same version. Instead got:\n - react: ' +
(isomorphicReactPackageVersion +
"\n - react-native-renderer: 19.0.0-rc-fb61a1b515-20240530\nLearn more: https://react.dev/warnings/version-mismatch")
"\n - react-native-renderer: 19.0.0-rc-9d4fba0788-20240530\nLearn more: https://react.dev/warnings/version-mismatch")
);
if (
"function" !==
@@ -10750,7 +10750,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1192 = {
findFiberByHostInstance: getInstanceFromTag,
bundleType: 0,
version: "19.0.0-rc-fb61a1b515-20240530",
version: "19.0.0-rc-9d4fba0788-20240530",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -10793,7 +10793,7 @@ var internals$jscomp$inline_1439 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-fb61a1b515-20240530"
reconcilerVersion: "19.0.0-rc-9d4fba0788-20240530"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1440 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<0cff48a4781a04f48ecdeb3be7565d9e>>
* @generated SignedSource<<1ce490a4a36486c993f44fb2e56dd056>>
*/
"use strict";
@@ -11403,11 +11403,11 @@ function traverseOwnerTreeUp(hierarchy, instance) {
traverseOwnerTreeUp(hierarchy, instance);
}
var isomorphicReactPackageVersion = React.version;
if ("19.0.0-rc-fb61a1b515-20240530" !== isomorphicReactPackageVersion)
if ("19.0.0-rc-9d4fba0788-20240530" !== isomorphicReactPackageVersion)
throw Error(
'Incompatible React versions: The "react" and "react-native-renderer" packages must have the exact same version. Instead got:\n - react: ' +
(isomorphicReactPackageVersion +
"\n - react-native-renderer: 19.0.0-rc-fb61a1b515-20240530\nLearn more: https://react.dev/warnings/version-mismatch")
"\n - react-native-renderer: 19.0.0-rc-9d4fba0788-20240530\nLearn more: https://react.dev/warnings/version-mismatch")
);
if (
"function" !==
@@ -11457,7 +11457,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1273 = {
findFiberByHostInstance: getInstanceFromTag,
bundleType: 0,
version: "19.0.0-rc-fb61a1b515-20240530",
version: "19.0.0-rc-9d4fba0788-20240530",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -11513,7 +11513,7 @@ var roots = new Map(),
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-fb61a1b515-20240530"
reconcilerVersion: "19.0.0-rc-9d4fba0788-20240530"
});
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {
computeComponentStackForErrorReporting: function (reactTag) {