Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove __self and __source location from elements #28265

Merged
merged 2 commits into from
Feb 7, 2024

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented Feb 7, 2024

Along with all the places using it like the _debugSource on Fiber. This still lets them be passed into createElement (and JSX dev runtime) since those can still be used in existing already compiled code and we don't want that to start spreading to DOM attributes.

We used to have a DEV mode that compiles the source location of JSX into the compiled output. This was nice because we could get the actual call site of the JSX (instead of just somewhere in the component). It had a bunch of issues though:

  • It only works with JSX.
  • The way this source location is compiled is different in all the pipelines along the way. It relies on this transform being first and the source location we want to extract but it doesn't get preserved along source maps and don't have a way to be connected to the source hosted by the source maps. Ideally it should just use the mechanism other source maps use.
  • Since it's expensive it only works in DEV so if it's used for component stacks it would vary between dev and prod.
  • It only captures the callsite of the JSX and not the stack between the component and that callsite. In the happy case it's in the component but not always.

Instead, we have another zero-cost trick to extract the call site of each component lazily only if it's needed. This ensures that component stacks are the same in DEV and PROD. At the cost of worse line number information.

The better way to get the JSX call site would be to get it from new Error() or console.createTask() inside the JSX runtime which can capture the whole stack in a consistent way with other source mappings. We might explore that in the future.

This removes source location info from React DevTools and React Native Inspector. The "jump to source code" feature or inspection can be made lazy instead by invoking the lazy component stack frame generation. That way it can be made to work in prod too. The filtering based on file path is a bit trickier.

When redesigned this UI should ideally also account for more than one stack frame.

With this change the DEV only Babel transforms are effectively deprecated since they're not necessary for anything.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Feb 7, 2024
@@ -23,7 +18,4 @@ export type ReactElement = {

// __DEV__
_store: {validated: boolean, ...},
_self: React$Element<any>,
_shadowChildren: any,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what this was about. Goes way back. #7504

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sebmarkbage sebmarkbage changed the title Remove __source location from elements Remove __self and __source location from elements Feb 7, 2024
@react-sizebot
Copy link

react-sizebot commented Feb 7, 2024

Comparing: a1ace9d...ee1b0bc

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js = 176.66 kB 176.64 kB = 55.01 kB 55.02 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 178.65 kB 178.63 kB = 55.59 kB 55.59 kB
facebook-www/ReactDOM-prod.classic.js = 591.78 kB 591.73 kB = 104.44 kB 104.44 kB
facebook-www/ReactDOM-prod.modern.js = 575.53 kB 575.51 kB = 101.54 kB 101.53 kB
facebook-react-native/react/cjs/React-dev.js = 129.98 kB 127.27 kB = 29.96 kB 29.44 kB
facebook-react-native/react/cjs/JSXRuntime-dev.js = 42.09 kB 40.60 kB = 11.04 kB 10.70 kB
facebook-react-native/react/cjs/JSXDEVRuntime-dev.js = 41.43 kB 39.94 kB = 10.86 kB 10.52 kB
test_utils/ReactAllWarnings.js Deleted 67.02 kB 0.00 kB Deleted 16.42 kB 0.00 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
react-native/implementations/ReactNativeRenderer-dev.fb.js = 1,022.86 kB 1,020.77 kB = 206.67 kB 206.12 kB
react-native/implementations/ReactFabric-dev.fb.js = 1,008.26 kB 1,006.17 kB = 202.84 kB 202.29 kB
react-native/implementations/ReactNativeRenderer-dev.js = 997.46 kB 995.37 kB = 202.66 kB 202.12 kB
oss-stable/react/umd/react.production.min.js = 11.91 kB 11.88 kB = 4.65 kB 4.65 kB
oss-stable/react/umd/react.profiling.min.js = 11.91 kB 11.88 kB = 4.65 kB 4.65 kB
oss-stable-semver/react/umd/react.production.min.js = 11.88 kB 11.86 kB +0.02% 4.63 kB 4.63 kB
oss-stable-semver/react/umd/react.profiling.min.js = 11.88 kB 11.86 kB +0.02% 4.63 kB 4.63 kB
react-native/implementations/ReactFabric-dev.js = 981.18 kB 979.09 kB = 198.37 kB 197.84 kB
facebook-react-native/react-test-renderer/cjs/ReactTestRenderer-dev.js = 939.38 kB 937.30 kB = 188.36 kB 187.82 kB
oss-experimental/react/cjs/react.react-server.production.min.js = 9.06 kB 9.04 kB = 3.68 kB 3.68 kB
oss-experimental/react/cjs/react.production.min.js = 9.05 kB 9.02 kB = 3.42 kB 3.41 kB
oss-stable/react/cjs/react.production.min.js = 8.12 kB 8.09 kB = 3.13 kB 3.13 kB
oss-stable-semver/react/cjs/react.production.min.js = 8.09 kB 8.06 kB = 3.11 kB 3.11 kB
oss-stable/react/cjs/react.react-server.production.min.js = 7.04 kB 7.01 kB = 3.00 kB 3.00 kB
oss-stable-semver/react/cjs/react.react-server.production.min.js = 7.02 kB 6.99 kB = 2.98 kB 2.98 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js = 67.18 kB 66.88 kB = 16.30 kB 16.27 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js = 67.15 kB 66.86 kB = 16.26 kB 16.23 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js = 66.29 kB 65.99 kB = 16.09 kB 16.06 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js = 66.26 kB 65.97 kB = 16.05 kB 16.02 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js = 64.86 kB 64.57 kB = 15.68 kB 15.65 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js = 64.83 kB 64.53 kB = 15.66 kB 15.63 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js = 63.05 kB 62.75 kB = 15.11 kB 15.08 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js = 62.13 kB 61.83 kB = 15.28 kB 15.25 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js = 62.13 kB 61.83 kB = 15.28 kB 15.25 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js = 62.10 kB 61.81 kB = 15.24 kB 15.21 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js = 62.10 kB 61.81 kB = 15.24 kB 15.21 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js = 61.24 kB 60.95 kB = 15.08 kB 15.05 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js = 61.24 kB 60.95 kB = 15.08 kB 15.05 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js = 61.22 kB 60.92 kB = 15.04 kB 15.01 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js = 61.22 kB 60.92 kB = 15.04 kB 15.01 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js = 60.74 kB 60.44 kB = 14.66 kB 14.63 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js = 60.23 kB 59.93 kB = 14.47 kB 14.45 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js = 59.82 kB 59.52 kB = 14.67 kB 14.64 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js = 59.82 kB 59.52 kB = 14.67 kB 14.64 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js = 59.78 kB 59.49 kB = 14.65 kB 14.62 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js = 59.78 kB 59.49 kB = 14.65 kB 14.62 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js = 64.60 kB 64.28 kB = 14.89 kB 14.87 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.development.js = 64.06 kB 63.74 kB = 14.71 kB 14.68 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js = 58.00 kB 57.70 kB = 14.10 kB 14.07 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js = 58.00 kB 57.70 kB = 14.10 kB 14.07 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js = 56.98 kB 56.68 kB = 13.51 kB 13.48 kB
oss-experimental/react-client/cjs/react-client-flight.development.js = 56.83 kB 56.53 kB = 13.85 kB 13.81 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js = 56.77 kB 56.48 kB = 13.44 kB 13.42 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js = 55.69 kB 55.39 kB = 13.66 kB 13.63 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js = 55.69 kB 55.39 kB = 13.66 kB 13.63 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js = 55.18 kB 54.88 kB = 13.47 kB 13.45 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js = 55.18 kB 54.88 kB = 13.47 kB 13.45 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js = 59.25 kB 58.93 kB = 13.88 kB 13.85 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js = 59.25 kB 58.93 kB = 13.88 kB 13.85 kB
oss-stable-semver/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.development.js = 58.70 kB 58.38 kB = 13.69 kB 13.67 kB
oss-stable/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.development.js = 58.70 kB 58.38 kB = 13.69 kB 13.67 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js = 51.93 kB 51.63 kB = 12.51 kB 12.48 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js = 51.93 kB 51.63 kB = 12.51 kB 12.48 kB
oss-stable-semver/react-client/cjs/react-client-flight.development.js = 51.78 kB 51.48 kB = 12.84 kB 12.81 kB
oss-stable/react-client/cjs/react-client-flight.development.js = 51.78 kB 51.48 kB = 12.84 kB 12.81 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js = 51.73 kB 51.43 kB = 12.44 kB 12.42 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js = 51.73 kB 51.43 kB = 12.44 kB 12.42 kB
oss-experimental/react/umd/react.development.js = 128.51 kB 127.37 kB = 32.87 kB 32.58 kB
oss-stable/react/umd/react.development.js = 125.87 kB 124.73 kB = 32.19 kB 31.91 kB
oss-stable-semver/react/umd/react.development.js = 125.84 kB 124.70 kB = 32.16 kB 31.88 kB
facebook-www/ReactFlightDOMClient-dev.modern.js = 35.00 kB 34.66 kB = 7.97 kB 7.95 kB
oss-experimental/react/cjs/react.development.js = 105.31 kB 104.21 kB = 28.09 kB 27.84 kB
oss-stable/react/cjs/react.development.js = 102.78 kB 101.68 kB = 27.45 kB 27.21 kB
oss-stable-semver/react/cjs/react.development.js = 102.75 kB 101.65 kB = 27.42 kB 27.18 kB
oss-stable-semver/react/cjs/react-jsx-runtime.react-server.development.js = 46.96 kB 46.40 kB = 13.68 kB 13.58 kB
oss-stable/react/cjs/react-jsx-runtime.react-server.development.js = 46.96 kB 46.40 kB = 13.68 kB 13.58 kB
oss-experimental/react/cjs/react-jsx-runtime.react-server.development.js = 46.94 kB 46.37 kB = 13.67 kB 13.57 kB
oss-stable-semver/react/cjs/react-jsx-runtime.development.js = 46.88 kB 46.31 kB = 13.64 kB 13.55 kB
oss-stable/react/cjs/react-jsx-runtime.development.js = 46.88 kB 46.31 kB = 13.64 kB 13.55 kB
oss-experimental/react/cjs/react-jsx-runtime.development.js = 46.85 kB 46.29 kB = 13.64 kB 13.54 kB
oss-stable-semver/react/cjs/react-jsx-dev-runtime.development.js = 46.28 kB 45.72 kB = 13.47 kB 13.37 kB
oss-stable/react/cjs/react-jsx-dev-runtime.development.js = 46.28 kB 45.72 kB = 13.47 kB 13.37 kB
oss-experimental/react/cjs/react-jsx-dev-runtime.development.js = 46.25 kB 45.69 kB = 13.46 kB 13.36 kB
oss-experimental/react/cjs/react.react-server.development.js = 84.94 kB 83.84 kB = 23.53 kB 23.29 kB
facebook-www/JSXDEVRuntime-dev.classic.js = 53.86 kB 53.15 kB = 13.98 kB 13.85 kB
facebook-www/JSXDEVRuntime-dev.modern.js = 53.86 kB 53.15 kB = 13.98 kB 13.85 kB
facebook-www/React-dev.classic.js = 143.26 kB 141.33 kB = 34.83 kB 34.20 kB
facebook-www/React-dev.modern.js = 142.03 kB 140.10 kB = 34.58 kB 33.94 kB
oss-stable/react/cjs/react.react-server.development.js = 78.51 kB 77.41 kB = 21.68 kB 21.42 kB
oss-stable-semver/react/cjs/react.react-server.development.js = 78.48 kB 77.38 kB = 21.65 kB 21.40 kB
oss-experimental/react/cjs/react.production.js = 38.03 kB 37.49 kB = 10.49 kB 10.34 kB
oss-experimental/react/cjs/react.react-server.production.js = 36.65 kB 36.11 kB = 10.76 kB 10.61 kB
react-native/shims/ReactNativeTypes.js = 8.34 kB 8.22 kB = 2.29 kB 2.26 kB
oss-stable/react/cjs/react.production.js = 35.42 kB 34.88 kB = 9.84 kB 9.70 kB
oss-stable-semver/react/cjs/react.production.js = 35.39 kB 34.85 kB = 9.82 kB 9.67 kB
facebook-www/ReactServer-dev.modern.js = 109.71 kB 107.78 kB = 26.38 kB 25.70 kB
oss-stable/react/cjs/react.react-server.production.js = 30.56 kB 30.02 kB = 9.11 kB 8.96 kB
oss-stable-semver/react/cjs/react.react-server.production.js = 30.53 kB 29.99 kB = 9.09 kB 8.94 kB
facebook-react-native/react/cjs/React-dev.js = 129.98 kB 127.27 kB = 29.96 kB 29.44 kB
facebook-react-native/react/cjs/JSXRuntime-dev.js = 42.09 kB 40.60 kB = 11.04 kB 10.70 kB
facebook-react-native/react/cjs/JSXDEVRuntime-dev.js = 41.43 kB 39.94 kB = 10.86 kB 10.52 kB
test_utils/ReactAllWarnings.js Deleted 67.02 kB 0.00 kB Deleted 16.42 kB 0.00 kB

Generated by 🚫 dangerJS against ee1b0bc

@sebmarkbage sebmarkbage force-pushed the rmsourceself branch 4 times, most recently from f6dac6f to 141a01a Compare February 7, 2024 03:06
Along with all the places using it like the _debugSource on Fiber.

This removes source location info from React DevTools and React Native Inspector.
Copy link
Contributor

@hoxyq hoxyq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Can we revert the changes for DevTools (except the test) and add $FlowFixMe and TODOs for migration from _debugSource field in fiber? So if we end up publishing new patch version of DevTools, the "go to source" feature will still work in DEV for previous versions of React
  2. What is the timeline for console.createTask? Is this currently in exploration phase?

@sebmarkbage
Copy link
Collaborator Author

I don’t think we’d do the console.createTask thing until Chrome fixes the UI and let custom UIs access the data.

For the devtools thing it would be better to do throw hack strategy that we use for prod component stacks.

@sebmarkbage
Copy link
Collaborator Author

Can we revert the changes for DevTools (except the test) and add $FlowFixMe and TODOs for migration from _debugSource field in fiber?

We could but it's a bit annoying to keep that code in sync with other parts of React. I also worry that it'll just not get done and encourage people to stay on old versions instead.

If we did do the lazy thing, it could also work on older versions of React.

This is fairly lazy in that only the selected instance calls this so
the slow component stack call is ok.
@sebmarkbage
Copy link
Collaborator Author

@rickhanlonii stamped verbally.

@sebmarkbage sebmarkbage merged commit 37d901e into facebook:main Feb 7, 2024
36 checks passed
github-actions bot pushed a commit that referenced this pull request Feb 7, 2024
Along with all the places using it like the `_debugSource` on Fiber.
This still lets them be passed into `createElement` (and JSX dev
runtime) since those can still be used in existing already compiled code
and we don't want that to start spreading to DOM attributes.

We used to have a DEV mode that compiles the source location of JSX into
the compiled output. This was nice because we could get the actual call
site of the JSX (instead of just somewhere in the component). It had a
bunch of issues though:

- It only works with JSX.
- The way this source location is compiled is different in all the
pipelines along the way. It relies on this transform being first and the
source location we want to extract but it doesn't get preserved along
source maps and don't have a way to be connected to the source hosted by
the source maps. Ideally it should just use the mechanism other source
maps use.
- Since it's expensive it only works in DEV so if it's used for
component stacks it would vary between dev and prod.
- It only captures the callsite of the JSX and not the stack between the
component and that callsite. In the happy case it's in the component but
not always.

Instead, we have another zero-cost trick to extract the call site of
each component lazily only if it's needed. This ensures that component
stacks are the same in DEV and PROD. At the cost of worse line number
information.

The better way to get the JSX call site would be to get it from `new
Error()` or `console.createTask()` inside the JSX runtime which can
capture the whole stack in a consistent way with other source mappings.
We might explore that in the future.

This removes source location info from React DevTools and React Native
Inspector. The "jump to source code" feature or inspection can be made
lazy instead by invoking the lazy component stack frame generation. That
way it can be made to work in prod too. The filtering based on file path
is a bit trickier.

When redesigned this UI should ideally also account for more than one
stack frame.

With this change the DEV only Babel transforms are effectively
deprecated since they're not necessary for anything.

DiffTrain build for [37d901e](37d901e)
Copy link
Member

@rickhanlonii rickhanlonii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ oops forgot to submit

hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

3 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265
3. Although `source` field is accumulated and stored, it is not displayed anywhere, see InspectorOverlay.js.

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

3 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265
3. Although `source` field is accumulated and stored, it is not displayed anywhere, see InspectorOverlay.js.

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
hoxyq added a commit to hoxyq/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Differential Revision: D53757524
facebook-github-bot pushed a commit to facebook/react-native that referenced this pull request Feb 14, 2024
Summary:
Changelog: [Internal]

Required for landing D53543159.

2 reasons for landing this:
1. Inspector is technically deprecated and will be removed once React DevTools are shipped with Chrome DevTools for RN debugging.
2. Long-term solution for source fetching is lazy loading based on component stacks - facebook/react#28265

Reviewed By: kassens

Differential Revision: D53757524

fbshipit-source-id: cbb2aab79ba40ea66da5c1ddde95d3fe374b6006
hoxyq added a commit that referenced this pull request Feb 22, 2024
…filters (#28417)

Following #28265, this should
disable location-based component filters.

```
// Following __debugSource removal from Fiber, the new approach for finding the source location
// of a component, represented by the Fiber, is based on lazily generating and parsing component stack frames
// To find the original location, React DevTools will perform symbolication, source maps are required for that.
// In order to start filtering Fibers, we need to find location for all of them, which can't be done lazily.
// Eager symbolication can become quite expensive for large applications.
```

I am planning to publish a patch version of RDT soon, so I think its
better to remove this feature, instead of shipping it in a broken state.

The reason for filtering out these filters is a potential cases, where
we load filters from the backend (like in RN, where we storing some
settings on device), or these filters can be stored in user land
(`window.__REACT_DEVTOOLS_COMPONENT_FILTERS__`).

Explicitly tested the case when:
1. Load current RDT extension, add location-based component filter
2. Reload the page and observe that previously created component filter
is preserved
3. Re-load RDT extension with these changes, observe there is no
previously created component filter and user can't create a new
location-based filter
4. Reload RDT extension without these changes, no location-based filters
saved, user can create location-based filters
hoxyq added a commit that referenced this pull request Feb 22, 2024
Full list of changes (not a public CHANGELOG):

* feature[REMOVED][devtools]: turn off / hide location based component
filters ([hoxyq](https://github.com/hoxyq) in
[#28417](#28417))
* Add useSyncExternalStore and useTransition to getPrimitiveStackCache
([jamesbvaughan](https://github.com/jamesbvaughan) in
[#28399](#28399))
* chore[devtools]: use react-window from npm and bump
react-virtualized-auto-sizer to ^1.0.23
([hoxyq](https://github.com/hoxyq) in
[#28408](#28408))
* Pass ref as normal prop ([acdlite](https://github.com/acdlite) in
[#28348](#28348))
* Combine createElement and JSX modules
([acdlite](https://github.com/acdlite) in
[#28320](#28320))
* [Debug Tools] Always use includeHooksSource option
([sebmarkbage](https://github.com/sebmarkbage) in
[#28309](#28309))
* Revert "[Tests] Reset modules by default"
([acdlite](https://github.com/acdlite) in
[#28318](#28318))
* Switch <Context> to mean <Context.Provider>
([gaearon](https://github.com/gaearon) in
[#28226](#28226))
* [Debug Tools] Introspect Promises in use()
([sebmarkbage](https://github.com/sebmarkbage) in
[#28297](#28297))
* fix[devtools/useModalDismissSignal]: use getRootNode for shadow root
case support ([hoxyq](https://github.com/hoxyq) in
[#28145](#28145))
* fix: define IS_ACT_ENVIRONMENT global for tests with concurrent mode
and synchronous act ([hoxyq](https://github.com/hoxyq) in
[#28296](#28296))
* chore: gate legacy apis for react-devtools-shell
([hoxyq](https://github.com/hoxyq) in
[#28273](#28273))
* DevTools: Add support for use(Context)
([eps1lon](https://github.com/eps1lon) in
[#28233](#28233))
* Remove __self and __source location from elements
([sebmarkbage](https://github.com/sebmarkbage) in
[#28265](#28265))
* chore: use versioned render in inspectedElement test
([hoxyq](https://github.com/hoxyq) in
[#28246](#28246))
* chore: use versioned render in TimelineProfiler test and gate some for
legacy rendering ([hoxyq](https://github.com/hoxyq) in
[#28218](#28218))
* [Tests] Reset modules by default
([rickhanlonii](https://github.com/rickhanlonii) in
[#28254](#28254))
* chore: use versioned render in preprocessData test and gate some for …
([hoxyq](https://github.com/hoxyq) in
[#28219](#28219))
* chore: use versioned render in storeStressSync test and gate them for
legacy rendering ([hoxyq](https://github.com/hoxyq) in
[#28216](#28216))
* Patch devtools before running useMemo function in strict mode
([gsathya](https://github.com/gsathya) in
[#28249](#28249))
* chore: use versioned render in storeComponentFilters test
([hoxyq](https://github.com/hoxyq) in
[#28241](#28241))
* chore: use versioned render in profilerContext test
([hoxyq](https://github.com/hoxyq) in
[#28243](#28243))
* chore: use versioned render in profilingCommitTreeBuilder test and
gate some for legacy rendering ([hoxyq](https://github.com/hoxyq) in
[#28236](#28236))
* chore: use versioned render in profilingHostRoot test and gate some
for legacy rendering ([hoxyq](https://github.com/hoxyq) in
[#28237](#28237))
* chore: use versioned render in profilingCache test
([hoxyq](https://github.com/hoxyq) in
[#28242](#28242))
* chore: use versioned render in ownersListContext test
([hoxyq](https://github.com/hoxyq) in
[#28240](#28240))
* chore: use versioned render in editing test
([hoxyq](https://github.com/hoxyq) in
[#28239](#28239))
* chore: use versioned render in treeContext test
([hoxyq](https://github.com/hoxyq) in
[#28245](#28245))
* chore: use versioned render in store test
([hoxyq](https://github.com/hoxyq) in
[#28244](#28244))
* chore: use versioned render in profilerStore test
([hoxyq](https://github.com/hoxyq) in
[#28238](#28238))
* chore: use versioned render in profilingCharts test
([hoxyq](https://github.com/hoxyq) in
[#28235](#28235))
* chore: use versioned render in profilerChangeDescriptions test
([hoxyq](https://github.com/hoxyq) in
[#28221](#28221))
* chore: use versioned render in storeOwners test
([hoxyq](https://github.com/hoxyq) in
[#28215](#28215))
* chore: use versioned render in componentStacks test
([hoxyq](https://github.com/hoxyq) in
[#28214](#28214))
* chore: use versioned render in console test
([hoxyq](https://github.com/hoxyq) in
[#28213](#28213))
* chore: use versioned render in useEditableValue test
([hoxyq](https://github.com/hoxyq) in
[#28212](#28212))
* chore: use versioned render in FastRefreshDevToolsIntegration test
([hoxyq](https://github.com/hoxyq) in
[#28211](#28211))
* chore: add versioned render implementation for DevTools tests
([hoxyq](https://github.com/hoxyq) in
[#28210](#28210))
* chore: add single versioned implementation of act for DevTools tests
([hoxyq](https://github.com/hoxyq) in
[#28186](#28186))
* DevTools: Add support for useFormState
([eps1lon](https://github.com/eps1lon) in
[#28232](#28232))
* DevTools: Add support for useOptimistic Hook
([eps1lon](https://github.com/eps1lon) in
[#27982](#27982))
* Add stable React.act export ([acdlite](https://github.com/acdlite) in
[#28160](#28160))
* [flow] upgrade to 0.225.1 ([kassens](https://github.com/kassens) in
[#27871](#27871))
* fix[devtools/e2e]: add fallback for act in integration tests
([hoxyq](https://github.com/hoxyq) in
[#27842](#27842))
* Add stable concurrent option to react-test-renderer
([jackpope](https://github.com/jackpope) in
[#27804](#27804))
* Update act references in tests ([gnoff](https://github.com/gnoff) in
[#27805](#27805))
* Flow: make more objects exact ([kassens](https://github.com/kassens)
in [#27790](#27790))
hoxyq added a commit that referenced this pull request Mar 5, 2024
… stacks (#28351)

`_debugSource` was removed in
#28265.

This PR migrates DevTools to define `source` for Fiber based on
component stacks. This will be done lazily for inspected elements, once
user clicks on the element in the tree.

`DevToolsComponentStackFrame.js` was just copy-pasted from the
implementation in `ReactComponentStackFrame`.

Symbolication part is done in
#28471 and stacked on this commit.
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
Along with all the places using it like the `_debugSource` on Fiber.
This still lets them be passed into `createElement` (and JSX dev
runtime) since those can still be used in existing already compiled code
and we don't want that to start spreading to DOM attributes.

We used to have a DEV mode that compiles the source location of JSX into
the compiled output. This was nice because we could get the actual call
site of the JSX (instead of just somewhere in the component). It had a
bunch of issues though:

- It only works with JSX.
- The way this source location is compiled is different in all the
pipelines along the way. It relies on this transform being first and the
source location we want to extract but it doesn't get preserved along
source maps and don't have a way to be connected to the source hosted by
the source maps. Ideally it should just use the mechanism other source
maps use.
- Since it's expensive it only works in DEV so if it's used for
component stacks it would vary between dev and prod.
- It only captures the callsite of the JSX and not the stack between the
component and that callsite. In the happy case it's in the component but
not always.

Instead, we have another zero-cost trick to extract the call site of
each component lazily only if it's needed. This ensures that component
stacks are the same in DEV and PROD. At the cost of worse line number
information.

The better way to get the JSX call site would be to get it from `new
Error()` or `console.createTask()` inside the JSX runtime which can
capture the whole stack in a consistent way with other source mappings.
We might explore that in the future.

This removes source location info from React DevTools and React Native
Inspector. The "jump to source code" feature or inspection can be made
lazy instead by invoking the lazy component stack frame generation. That
way it can be made to work in prod too. The filtering based on file path
is a bit trickier.

When redesigned this UI should ideally also account for more than one
stack frame.

With this change the DEV only Babel transforms are effectively
deprecated since they're not necessary for anything.
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
…filters (facebook#28417)

Following facebook#28265, this should
disable location-based component filters.

```
// Following __debugSource removal from Fiber, the new approach for finding the source location
// of a component, represented by the Fiber, is based on lazily generating and parsing component stack frames
// To find the original location, React DevTools will perform symbolication, source maps are required for that.
// In order to start filtering Fibers, we need to find location for all of them, which can't be done lazily.
// Eager symbolication can become quite expensive for large applications.
```

I am planning to publish a patch version of RDT soon, so I think its
better to remove this feature, instead of shipping it in a broken state.

The reason for filtering out these filters is a potential cases, where
we load filters from the backend (like in RN, where we storing some
settings on device), or these filters can be stored in user land
(`window.__REACT_DEVTOOLS_COMPONENT_FILTERS__`).

Explicitly tested the case when:
1. Load current RDT extension, add location-based component filter
2. Reload the page and observe that previously created component filter
is preserved
3. Re-load RDT extension with these changes, observe there is no
previously created component filter and user can't create a new
location-based filter
4. Reload RDT extension without these changes, no location-based filters
saved, user can create location-based filters
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
Full list of changes (not a public CHANGELOG):

* feature[REMOVED][devtools]: turn off / hide location based component
filters ([hoxyq](https://github.com/hoxyq) in
[facebook#28417](facebook#28417))
* Add useSyncExternalStore and useTransition to getPrimitiveStackCache
([jamesbvaughan](https://github.com/jamesbvaughan) in
[facebook#28399](facebook#28399))
* chore[devtools]: use react-window from npm and bump
react-virtualized-auto-sizer to ^1.0.23
([hoxyq](https://github.com/hoxyq) in
[facebook#28408](facebook#28408))
* Pass ref as normal prop ([acdlite](https://github.com/acdlite) in
[facebook#28348](facebook#28348))
* Combine createElement and JSX modules
([acdlite](https://github.com/acdlite) in
[facebook#28320](facebook#28320))
* [Debug Tools] Always use includeHooksSource option
([sebmarkbage](https://github.com/sebmarkbage) in
[facebook#28309](facebook#28309))
* Revert "[Tests] Reset modules by default"
([acdlite](https://github.com/acdlite) in
[facebook#28318](facebook#28318))
* Switch <Context> to mean <Context.Provider>
([gaearon](https://github.com/gaearon) in
[facebook#28226](facebook#28226))
* [Debug Tools] Introspect Promises in use()
([sebmarkbage](https://github.com/sebmarkbage) in
[facebook#28297](facebook#28297))
* fix[devtools/useModalDismissSignal]: use getRootNode for shadow root
case support ([hoxyq](https://github.com/hoxyq) in
[facebook#28145](facebook#28145))
* fix: define IS_ACT_ENVIRONMENT global for tests with concurrent mode
and synchronous act ([hoxyq](https://github.com/hoxyq) in
[facebook#28296](facebook#28296))
* chore: gate legacy apis for react-devtools-shell
([hoxyq](https://github.com/hoxyq) in
[facebook#28273](facebook#28273))
* DevTools: Add support for use(Context)
([eps1lon](https://github.com/eps1lon) in
[facebook#28233](facebook#28233))
* Remove __self and __source location from elements
([sebmarkbage](https://github.com/sebmarkbage) in
[facebook#28265](facebook#28265))
* chore: use versioned render in inspectedElement test
([hoxyq](https://github.com/hoxyq) in
[facebook#28246](facebook#28246))
* chore: use versioned render in TimelineProfiler test and gate some for
legacy rendering ([hoxyq](https://github.com/hoxyq) in
[facebook#28218](facebook#28218))
* [Tests] Reset modules by default
([rickhanlonii](https://github.com/rickhanlonii) in
[facebook#28254](facebook#28254))
* chore: use versioned render in preprocessData test and gate some for …
([hoxyq](https://github.com/hoxyq) in
[facebook#28219](facebook#28219))
* chore: use versioned render in storeStressSync test and gate them for
legacy rendering ([hoxyq](https://github.com/hoxyq) in
[facebook#28216](facebook#28216))
* Patch devtools before running useMemo function in strict mode
([gsathya](https://github.com/gsathya) in
[facebook#28249](facebook#28249))
* chore: use versioned render in storeComponentFilters test
([hoxyq](https://github.com/hoxyq) in
[facebook#28241](facebook#28241))
* chore: use versioned render in profilerContext test
([hoxyq](https://github.com/hoxyq) in
[facebook#28243](facebook#28243))
* chore: use versioned render in profilingCommitTreeBuilder test and
gate some for legacy rendering ([hoxyq](https://github.com/hoxyq) in
[facebook#28236](facebook#28236))
* chore: use versioned render in profilingHostRoot test and gate some
for legacy rendering ([hoxyq](https://github.com/hoxyq) in
[facebook#28237](facebook#28237))
* chore: use versioned render in profilingCache test
([hoxyq](https://github.com/hoxyq) in
[facebook#28242](facebook#28242))
* chore: use versioned render in ownersListContext test
([hoxyq](https://github.com/hoxyq) in
[facebook#28240](facebook#28240))
* chore: use versioned render in editing test
([hoxyq](https://github.com/hoxyq) in
[facebook#28239](facebook#28239))
* chore: use versioned render in treeContext test
([hoxyq](https://github.com/hoxyq) in
[facebook#28245](facebook#28245))
* chore: use versioned render in store test
([hoxyq](https://github.com/hoxyq) in
[facebook#28244](facebook#28244))
* chore: use versioned render in profilerStore test
([hoxyq](https://github.com/hoxyq) in
[facebook#28238](facebook#28238))
* chore: use versioned render in profilingCharts test
([hoxyq](https://github.com/hoxyq) in
[facebook#28235](facebook#28235))
* chore: use versioned render in profilerChangeDescriptions test
([hoxyq](https://github.com/hoxyq) in
[facebook#28221](facebook#28221))
* chore: use versioned render in storeOwners test
([hoxyq](https://github.com/hoxyq) in
[facebook#28215](facebook#28215))
* chore: use versioned render in componentStacks test
([hoxyq](https://github.com/hoxyq) in
[facebook#28214](facebook#28214))
* chore: use versioned render in console test
([hoxyq](https://github.com/hoxyq) in
[facebook#28213](facebook#28213))
* chore: use versioned render in useEditableValue test
([hoxyq](https://github.com/hoxyq) in
[facebook#28212](facebook#28212))
* chore: use versioned render in FastRefreshDevToolsIntegration test
([hoxyq](https://github.com/hoxyq) in
[facebook#28211](facebook#28211))
* chore: add versioned render implementation for DevTools tests
([hoxyq](https://github.com/hoxyq) in
[facebook#28210](facebook#28210))
* chore: add single versioned implementation of act for DevTools tests
([hoxyq](https://github.com/hoxyq) in
[facebook#28186](facebook#28186))
* DevTools: Add support for useFormState
([eps1lon](https://github.com/eps1lon) in
[facebook#28232](facebook#28232))
* DevTools: Add support for useOptimistic Hook
([eps1lon](https://github.com/eps1lon) in
[facebook#27982](facebook#27982))
* Add stable React.act export ([acdlite](https://github.com/acdlite) in
[facebook#28160](facebook#28160))
* [flow] upgrade to 0.225.1 ([kassens](https://github.com/kassens) in
[facebook#27871](facebook#27871))
* fix[devtools/e2e]: add fallback for act in integration tests
([hoxyq](https://github.com/hoxyq) in
[facebook#27842](facebook#27842))
* Add stable concurrent option to react-test-renderer
([jackpope](https://github.com/jackpope) in
[facebook#27804](facebook#27804))
* Update act references in tests ([gnoff](https://github.com/gnoff) in
[facebook#27805](facebook#27805))
* Flow: make more objects exact ([kassens](https://github.com/kassens)
in [facebook#27790](facebook#27790))
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
… stacks (facebook#28351)

`_debugSource` was removed in
facebook#28265.

This PR migrates DevTools to define `source` for Fiber based on
component stacks. This will be done lazily for inspected elements, once
user clicks on the element in the tree.

`DevToolsComponentStackFrame.js` was just copy-pasted from the
implementation in `ReactComponentStackFrame`.

Symbolication part is done in
facebook#28471 and stacked on this commit.
bigfootjon pushed a commit that referenced this pull request Apr 18, 2024
Along with all the places using it like the `_debugSource` on Fiber.
This still lets them be passed into `createElement` (and JSX dev
runtime) since those can still be used in existing already compiled code
and we don't want that to start spreading to DOM attributes.

We used to have a DEV mode that compiles the source location of JSX into
the compiled output. This was nice because we could get the actual call
site of the JSX (instead of just somewhere in the component). It had a
bunch of issues though:

- It only works with JSX.
- The way this source location is compiled is different in all the
pipelines along the way. It relies on this transform being first and the
source location we want to extract but it doesn't get preserved along
source maps and don't have a way to be connected to the source hosted by
the source maps. Ideally it should just use the mechanism other source
maps use.
- Since it's expensive it only works in DEV so if it's used for
component stacks it would vary between dev and prod.
- It only captures the callsite of the JSX and not the stack between the
component and that callsite. In the happy case it's in the component but
not always.

Instead, we have another zero-cost trick to extract the call site of
each component lazily only if it's needed. This ensures that component
stacks are the same in DEV and PROD. At the cost of worse line number
information.

The better way to get the JSX call site would be to get it from `new
Error()` or `console.createTask()` inside the JSX runtime which can
capture the whole stack in a consistent way with other source mappings.
We might explore that in the future.

This removes source location info from React DevTools and React Native
Inspector. The "jump to source code" feature or inspection can be made
lazy instead by invoking the lazy component stack frame generation. That
way it can be made to work in prod too. The filtering based on file path
is a bit trickier.

When redesigned this UI should ideally also account for more than one
stack frame.

With this change the DEV only Babel transforms are effectively
deprecated since they're not necessary for anything.

DiffTrain build for commit 37d901e.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants