Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51687
Changelog: [Internal]
# Context
This is the first of several commits that aim to implement a **standalone shell for React Native DevTools**. This will be a lightweight desktop app designed to host the debugger frontend, in much the same way as we currently use Chrome or Edge. The launch flow will otherwise remain **very similar** to the one that exists today.
## What's changing for users?
1. With this commit, nothing; we're merely setting up an experiment flag (for stage 1 - Meta-internal testing) and will make separate plans for open source rollout, coordinated with our framework maintainer partners.
2. If the experiment is successful, we aim to *eventually* phase out the use of Chrome/Edge in React Native DevTools and ship the standalone shell as standard to all React Native developers. This is to enable further improvements that will rely on the standalone shell to work.
3. The first iteration of the standalone shell aims to solve some concrete pain points such as the "dead window problem" - the fact that opening DevTools multiple times for the same target will leave behind a now-dead window (that would ideally have been reused).
## This diff
We amend the `unstable_experiments` and `unstable_browserLauncher` APIs in `dev-middleware` to add basic support for launching a standalone shell based on a frontend URL and a *window key* - the latter being an opaque string that the shell process can match against previous launches in order to reuse and foreground existing windows.
We leave it up to `BrowserLauncher` implementers ( = frameworks) to provide a working implementation of `unstable_showFuseboxShell`, and do not provide one with `DefaultBrowserLauncher`. This will effectively allow us to dependency-inject the actual shell implementation at stage 1 so we don't increase the download size of React Native unnecessarily.
Reviewed By: rickhanlonii, robhogan
Differential Revision: D74904547
fbshipit-source-id: fbc6eac97923062bda8892bc130b39051845ea82
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49552
Changelog:
[General][Internal] - expand debugger events to have DebuggerSessionIDs
Also moved the handling of these to a shared function
Reviewed By: huntie
Differential Revision: D69917817
fbshipit-source-id: 2374ac5b5dc0040b0e15028ab89fbe78026bc296
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49499
Changelog:
[General][Internal] - warn when user tries to open DevTools, when not in debug mode
Reviewed By: huntie
Differential Revision: D69784836
fbshipit-source-id: aa60762f08f5dea1f91f4fd1ffc86eeb7f94e2fc
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47628
`serverBaseUrl` is currently documented as:
> The base URL to the dev server, as addressible from the local developer machine
This is problematic in general because `dev-middleware` on a server doesn't necessarily know about where clients might be reaching it from, how tunnels or port-forwards are set up, etc., and this can change over the lifetime of the server and vary between clients.
Indeed, our own use of `serverBaseUrl` from both `community-cli-plugin` and internally simply sets it to the host and port the dev server is listening on - ie it's the address of the dev server accessible *from the server*.
This PR changes the docs, redefining `serverBaseUrl`, to match the way we currently specify it.
One usage where we *do* want the previously documented behaviour is in responses to `/json/list` (`getPageDescriptions`) where the URLs in the response should be reachable by a browser requesting `/json/list`.
Here, we use the request (host header, etc.) to attempt to get working base URL.
History:
It should be mentioned that this is the latest in a series of changes like this:
- https://github.com/facebook/react-native/pull/39394
- https://github.com/facebook/react-native/pull/39456
Learning from those:
- This change does *not* break Android emulators, which routes `10.0.2.2` to localhost, or other routed devices, because `/open-debugger` still uses server-relative URLs, and now formally delegates to `BrowserLauncher` to decide what to do with those URLs (internally, VSCode / `xdg-open` handles port forwarding)
- Middleware configuration is no longer required to specify how it is reachable from clients.
This sets up some subsequent changes for more robust handling of tunnelled connections.
Changelog:
[General][Breaking] dev-middleware: Frameworks should specify `serverBaseUrl` relative to the middleware host.
Reviewed By: huntie
Differential Revision: D65974487
fbshipit-source-id: 1face8fc7715df387f75b329e80932d8543ee419
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47120
Fixes no-op behaviour of the "Open DevTools" Dev Menu item (bug on `main` introduced with D63329456).
This was caused by a change to the `description` field contents in our CDP `/json/list` response, when under Fusebox. In the `/open-debugger` call from the Dev Menu, we were still using the older `appId` param.
This did not affect `j` to debug, which uses the `target` param.
{F1937186832}
Changes:
In short: Matching against the `description` string is now fully eliminated for modern debugger targets.
- Update native Dev Menu implementation to omit `appId` parameter (`device` param alone is sufficient and fully precise on these platforms).
- Update `/open-debugger` implementation to ignore the `appId` parameter for modern targets, and document this in the `dev-middleware` README.
Changelog: [Internal]
Reviewed By: robhogan
Differential Revision: D64597581
fbshipit-source-id: 46f536e7d0a4ececab0d52f4c0704e8698466cd0
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47098
Changelog: [Internal]
D63329456 updated the `description` field to be human-readable.
Unfortunately, InspectorProxy relies on this field to compare the incoming `/open-debugger` calls.
hoxyq discovered the symptom of Fusebox failing to launch with `No compatible apps connected. React Native DevTools can only be used with the Hermes engine.` in Metro
Reviewed By: hoxyq
Differential Revision: D64547367
fbshipit-source-id: deed6851f3ede2c74be2b492def1eba6e58c43e6
Summary:
This fixes an issue where `POST /open-debugger?appId&device&target` does not return a proper status code, meaning that the request will never be answered and clients might hang until the request timeout is hit.
## Changelog:
<!-- Help reviewers and the release process by writing your own changelog entry.
Pick one each for the category and type tags:
[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message
For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[GENERAL] [FIXED] - Respond with status code `200` when successfully launching RNDT
Pull Request resolved: https://github.com/facebook/react-native/pull/46814
Test Plan:
- `curl -v -X POST "<deviceUrl>"`
- This should show a proper response for the request.
before | after
--- | ---
 | 
Reviewed By: NickGerleman
Differential Revision: D63837025
Pulled By: huntie
fbshipit-source-id: ac72fc793e015f0eec498f4a35b4fb9e301c5b32
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46231
Removes this option from `npx react-native start`. Flipper will no longer be the default launch flow in 0.76.
The debugger frontend variant remains controlled by `target.reactNative.capabilities?.prefersFuseboxFrontend`. This will always be Fusebox, since D60893243.
Changelog:
[General][Changed] Remove `--experimental-debugger` option from start command
Reviewed By: robhogan
Differential Revision: D61852415
fbshipit-source-id: 3351f0e12c24717916a70dd1ea28f8690bb5509f
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45138
Add a new `/open-debugger` endpoint format that allows specifying `target` - the proxy-unique target `id`. This is logically equivalent to specifying both device and page.
Changelog:
[General][Added]: Inspector: Support `/open-debugger` specifying `target` param
Reviewed By: hoxyq
Differential Revision: D58950622
fbshipit-source-id: 9665f8a24ba2bb0561cc3c693dfb84bfffdeb4a4
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45140
Previously, if the `/open-debugger` endpoint was provided with both `device` and `appId` query params, we would:
- Try to find a target with a matching `device` (note that these logical "devices" are unique per-app) - if found, use it. Otherwise,
- Try to find a target with a matching `appId` - if found, use that.
This could go "wrong" in two ways:
- If a `device` is given with a spurious `appId`, we'd open to a target with an `appId` differing from the one specified.
- If the `device` has gone away but there is a different target with the same app, we'd use that as a fallback (right app, wrong device).
This applies the filters more strictly so that if both are given, both must match.
Changelog:
[General][Changed]: Inspector: Enforce device and appId filters if both are given to /open-debugger
Reviewed By: hoxyq
Differential Revision: D58951952
fbshipit-source-id: a95f1160e5c88f957445058f3273e922a5d28c1e
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45060
Currently, `j`, (i.e., `/open-debugger` with no parameters), connects the "first available" target, which in practice is the first page of the first connected device still connected.
In the absence of a target selection UI, a better guess at user intent is to use the *latest* target (most recently added page of most recently connected device).
Also slightly reduces CLI noise by not claiming that we're launching a debugger when there's no target, and not qualifying which target when there's only one.
Changelog:
[General][Changed] Debugger: `j` opens most recent (not first) target.
Reviewed By: huntie
Differential Revision: D58736151
fbshipit-source-id: 3d106a1fa958f9e5c91b16e04075609e1abf6e97
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44672
Swaps out and simplifies the internals of the debugger launch flow.
We observed that we could achieve better launch/windowing behaviour by passing the `--app` argument directly to the detected Chrome path.
This shares the user's default Chrome profile:
- Fixes unwanted behaviour such as a separate dock icon on macOS (which, when clicked, would launch an unwanted empty window).
- Enables settings persistence.
This change also removes the `LaunchedBrowser.kill` API.
Changelog: [Internal]
Reviewed By: hoxyq
Differential Revision: D57726649
fbshipit-source-id: fc3a715dc852a50559048d1d1c378f64aeb2013f
Summary: Changelog: [General][Removed] `launchId` query param for `/debugger-frontend` is no longer generated automatically for each `/open-debugger` call. Caller of `/open-debugger` is now responsible for generating the `launchId`, which will be passed along to `/debugger-frontend`.
Reviewed By: robhogan
Differential Revision: D55164645
fbshipit-source-id: b83303eda77b6fb86ebf50f699d9f308676533c6
Summary:
Supports the removal of Flipper from the template in 0.74, paried with additional blog post messaging: https://reactnative.dev/blog/2024/04/22/release-0.74#removal-of-flipper-react-native-plugin.
Changelog:
[General][Changed] - Update "Open Debugger" action to print extended Flipper guidance
Reviewed By: cipolleschi
Differential Revision: D56705236
fbshipit-source-id: d7e869625262ebb02bc2454c924f832cccfbcd31
Summary:
Changelog: [Internal]
Uses the capability introduced in https://github.com/facebookexperimental/rn-chrome-devtools-frontend/pull/4 to avoid repeating the dev server's host:port in the `ws` / `wss` parameter we pass to the Chrome DevTools frontend. This gives us more flexibility to handle port forwarding and redirects outside of `dev-middleware`. This is mostly useful in Meta's internal VS Code remoting setup, but this particular change should work equally well in open source.
Reviewed By: huntie
Differential Revision: D54107316
fbshipit-source-id: 68d4dbf4849ca431274bfb0dc8a4e05981bdd5b5
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42885
## Context
We're introducing the concept of **capability flags** to provide granular control of behaviours in the Inspector Proxy, to replace the recently added `type: 'Legacy' | 'Modern'` target switch.
A capability flag disables a specific feature/hack in the Inspector Proxy layer by indicating that the target supports one or more modern CDP features.
## This diff
Following D53355413, we're now able to remove the previous `type: 'Legacy' | 'Modern'` page concept, implemented in this diff.
Changelog: [Internal]
Reviewed By: robhogan
Differential Revision: D53358480
fbshipit-source-id: 62e53a1bd60760291ada3479121dfca9e1f6edbc
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42817
## Context
We're introducing the concept of **capability flags** to provide granular control of behaviours in the Inspector Proxy, to replace the recently added `type: 'Legacy' | 'Modern'` target switch.
A capability flag disables a specific feature/hack in the Inspector Proxy layer by indicating that the target supports one or more modern CDP features.
## This diff
- Implements capability flags in `InspectorProxy`, via an optional `"capabilities"` key returned by a device's CDP server.
- Wires up an initial flag, `nativePageReloads`, to disable the legacy "React Native Experimental (Improved Chrome Reloads)" page and emulated page reload behaviour.
Changelog: [Internal]
Reviewed By: robhogan
Differential Revision: D53352244
fbshipit-source-id: 622fc6028174919b9bf776e3ac52724d97ca2734
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42302
Changelog: [Internal][Added] Support launching experimental debugger frontend for CDP targets marked as "modern"
See the definition of "modern" targets in D50967795.
Reviewed By: hoxyq
Differential Revision: D52786332
fbshipit-source-id: 13718e9ddf3ec050049ef7ec9a77f6cf1a7f82ee
Summary:
This enables the network panel/inspector by passing the `unstable_enableNetworkPanel=true` to the React Native JS Inspector. (See https://github.com/facebookexperimental/rn-chrome-devtools-frontend/pull/2)
By setting this inside the `experiments`, we can enable/disable network related CDP handlers within the proxy.
## Changelog:
[GENERAL] [ADDED] - Add `enableNetworkInspector` experiment to enable Network panel and CDP handlers in inspector proxy
Pull Request resolved: https://github.com/facebook/react-native/pull/41787
Test Plan: TBD, will provide a repository using an Expo canary / RN 0.73.0-rc release.
Reviewed By: NickGerleman
Differential Revision: D51811892
Pulled By: huntie
fbshipit-source-id: 541d96b6f0735104a4050a24a152e1158871ed1d
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41154
Pull Request resolved: https://github.com/facebook/react-native/pull/41080
Building on byCedric's approach in https://github.com/facebook/metro/pull/991, adds support for passing a `device=...` argument to `/open-debugger` for more precise targeting.
Changelog: [Internal]
---
## Note on what "device" means in this context
In `dev-middleware` / `inspector-proxy`, "device" is something of a misnomer. It refers to a *logical device* containing one or more *pages*. In React Native, each app process forms its own logical device in which individual VMs register themselves as pages. An instance of `inspector-proxy` connects one or more *debuggers* (frontends) to one or more logical devices (one frontend to one page on one device).
The intent of the logical device ID is to help with target discovery and especially *re*discovery - to reduce the number of times users need to explicitly close and restart the debugger frontend (e.g. after an app crash).
If provided, the logical device ID:
1. SHOULD be stable for the current combination of physical device (or emulator instance) and app.
2. SHOULD be stable across installs/launches of the same app on the same device (or emulator instance), though it MAY be user-resettable (so as to not require any special privacy permissions).
3. MUST be unique across different apps on the same physical device (or emulator).
4. MUST be unique across physical devices (or emulators).
5. MUST be unique for each concurrent *instance* of the same app on the same physical device (or emulator).
NOTE: The uniqueness requirements are stronger (MUST) than the stability requirements (SHOULD). In particular, on platforms that allow multiple instances of the same app to run concurrently, requirements 1 and/or 2 MAY be violated in order to meet requirement 5. This will be relevant, for example, on desktop platforms.
In an upcoming diff, we will pass device IDs meeting these criteria from both iOS and Android.
Reviewed By: huntie, blakef
Differential Revision: D49954920
fbshipit-source-id: 45f2b50765dece34cbb93fa32abcdf3b0522391c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/40766
This changeset allows users to opt into the new debugger frontend experience by passing `--experimental-debugger` to `react-native start`. **We are defaulting this option to `true`** for now, but will continue to evaluate this feature before 0.73 ships. It restores Flipper (via `flipper://`) as the default handling for `/open-debugger` (matching 0.72 behaviour) when this flag is not enabled.
Detailed changes:
- Replaces `enableCustomDebuggerFrontend` experiment in `dev-middleware` with `enableNewDebugger`. The latter now hard-swaps between the Flipper and new launch flows.
- Removes now-unused switching of `devtoolsFrontendUrl`.
- Implements `deprecated_openFlipperMiddleware` (matching previous RN CLI implementation).
- Disables "`j` to debug" key handler by default.
- Marks "`j` to debug" and `/open-debugger` console logs as experimental.
Changelog:
[Changed][General] Gate new debugger frontend behind `--experimental-debugger` flag, restore Flipper as base launch flow
Reviewed By: motiz88
Differential Revision: D50084590
fbshipit-source-id: 5234634f20110cb7933b1787bd2c86f645411fff
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39456
**Fixes new debugger launch flow on Android:**
D49158227 aimed to improve proxy-safe behaviour for remote dev servers by auto-detecting the appropriate server URL for clients using the `Host` header (etc) from the HTTP request. However, this approach broke the local case for Android emulators and externally connected devices since they would originate from a device-relative server hostname — e.g. `10.0.2.2` for the stock Android emulator.
https://pxl.cl/3mVmR
This commit reverts to an explicit approach where callers specify the base URL to the dev server that should be addressible from the development machine — now as a single `serverBaseUrl` option.
**Changes**
- Adds new `serverBaseUrl` option to `createDevMiddleware`, designed to be the base URL value for constructing dev server URLs returned in endpoints such as `/json/list`.
- This changes little for the `localhost` case (now enabling `https://` URLs), but enables remote dev server setups to specify this cleanly.
- Updates call site in `community-cli-plugin`.
Changelog: [Internal]
Reviewed By: robhogan
Differential Revision: D49276125
fbshipit-source-id: 2b6a8507073649832993971aa9d0870f54c9bd44
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39418
Changelog: [Internal]
Adds the `enableOpenDebuggerRedirect` experiment flag. The flag enables the handling of GET requests in the `/open-debugger` endpoint, in addition to POST requests. GET requests respond by redirecting to the debugger frontend, instead of opening it using the `BrowserLauncher` interface.
This can be useful when integrating `dev-middleware` in highly customised environments (e.g. VS Code remoting) where things like automatic port forwarding interact poorly with the `BrowserLauncher` abstraction.
WARNING: As this is gated by an experiment flag, the functionality may change or go away unannounced. In separate work, we will look into a stable solution for this use case.
Reviewed By: huntie
Differential Revision: D49144733
fbshipit-source-id: 5af6c8b2ddaa7b6e7d14c792e49fe3d0849c7a25
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39423
D49158227 made the CDP WebSocket URLs returned from `/json` proxy-safe by using the Host header (etc) from the HTTP request. This did *not* fully fix the related `/open-debugger` endpoint, because the original headers were being lost in the internal `fetch('/json')` call.
Here, we eliminate that `fetch` call, and instead give the `/open-debugger` handler direct access to the method on `InspectorProxy` that backs the `/json` endpoint. This allows us to pass in an appropriate base URL derived from the headers seen by `/open-debugger`.
Changelog: [Internal]
Reviewed By: huntie
Differential Revision: D49229545
fbshipit-source-id: 9036ab295721e0d1fd3cdb608d0a7cc07b8f2eeb
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39227
Changelog: [Internal]
1. Adds an `unstable_experiments` option to `createDevMiddleware` in `react-native/dev-middleware`.
2. Adds `enableCustomDebuggerFrontend` (default `false` for now) as an experiment flag controlling whether the new debugger frontend (D48680624, D48682302) is in use. We plan to enable this by default in RN 0.73 after additional testing.
If enabled, the new debugger frontend will only be used for the `/open-debugger` flow
Reviewed By: huntie
Differential Revision: D48602725
fbshipit-source-id: 598865b559478df1f19420daf3633ee6c233362a
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39242
Reverts external behaviour of https://github.com/facebook/react-native/pull/39122.
- `/json/list` once again returns the built-in `devtools://devtools/bundled/js_app.html` URL — effectively freezing the current experience in Flipper.
- `/open-debugger` continues to use the *new* frontend via `getDevToolsFrontendUrl`.
- *Eventually*, we'll want to align this as the returned `devtoolsFrontendUrl` value once Flipper is out of the picture.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D48868767
fbshipit-source-id: 088ecebffa6ce45cb9bed44e3b02df4b7b471068
Summary:
Expose a `unstable_browserLauncher` option to `createDevMiddleware()`. This allows integrators to provide a custom implementation for opening URLs in a web browser, initially a `launchDebuggerAppWindow` method.
Customising the browser launcher implementation can be useful in cases where the dev server is running remotely and not on the developer's local machine.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D48647750
fbshipit-source-id: ebf34106ad27899024396b13b22ec4536aad05b9
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39122
Updates the `devtoolsFrontendUrl` value returned in the `/json/list` endpoint, to match the fixed DevTools frontend revision we set for `/open-debugger` — which now uses this as the source of truth.
Changelog: [Internal]
Reviewed By: motiz88
Differential Revision: D48561005
fbshipit-source-id: 19409d013366f82782a071a0ec01d1ce8fab8c38
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39091
Changelog: [Internal]
Adds a simple typed logging hook to `react-native/dev-middleware`. This is intended to allow integrators to receive events from the dev server, apply any relevant sampling/processing, and log them to a backend. (To be clear, the open source version of React Native does not and will not collect any data.)
WARNING: The API will evolve over the coming weeks/months and is *not guaranteed to be stable* - it might even break between patch releases.
Reviewed By: huntie
Differential Revision: D48466760
fbshipit-source-id: ed1e21fb0dac5d6199ff1ee26017a1d33d9b7d92