d1b0e9a30b
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47653 ## Context Currently, when `nativeSourceCodeFetching == false`, `inspector-proxy` attempts to pre-fetch source maps, given the URL from a `Debugger.scriptParsed` event, and embeds them into `Debugger.scriptParsed`'s `sourceMapURL` using a data URI. This was originally to support frontends that did not perform HTTP requests or were blocked (eg by CORS), but we're retaining it for the moment because it's more performant than lazy loading the source map. Similarly, we perform middleware->server fetches to respond to `Debugger.getScriptSource` events. To make these fetches for URLs that target `10.0.2.2` (ie, addressable from within an Android emulator) (etc), we rewrite `10.0.2.2`->`localhost` and perform a `fetch` from the Node process running dev-middleware. ## The problem Consider a setup where: - Metro is running on a remote server, listening on `8081`. - Dev machine tunnels `localhost:8082` -> remote `8081`. - An app is running on an Android emulator on the dev machine, with bundle URL configured to `10.0.2.2:8082`. In this case, we'll rewrite `10.0.2.2:8082` to `localhost:8082`, which *is* reachable and correct from the dev machine, but *not* from the machine where Metro is running, so the `fetch` of a source map from the inspector proxy will fail. ## Motivation This might seem like a niche case, but it's part of fixing a series of unsafe assumptions that currently prevent us from running DevTools on an arbitrary port. ## This fix Preserve the current behaviour (simple `10.0.2.2`<=>`localhost`) for URLs sent to the frontend, but construct a separate, server-relative URL, using the configured `serverBaseUrl`, for `fetch` calls within dev-middleware. Changelog: [General][Fixed] RN DevTools: Fix fetching sources and source maps when the dev-server is remote and not tunnelled via the same port+protocol. Reviewed By: huntie Differential Revision: D65993910 fbshipit-source-id: a0cdcf1644e97a2af3d8583f2da2aaa51276f68c |
||
---|---|---|
.. | ||
src | ||
.gitignore | ||
index.js.flow | ||
package.json | ||
README.md |
@react-native/dev-middleware
Dev server middleware supporting core React Native development features. This package is preconfigured in all React Native projects.
Usage
Middleware can be attached to a dev server (e.g. Metro) using the createDevMiddleware
API.
import { createDevMiddleware } from '@react-native/dev-middleware';
function myDevServerImpl(args) {
...
const {middleware, websocketEndpoints} = createDevMiddleware({
projectRoot: metroConfig.projectRoot,
serverBaseUrl: `http://${args.host}:${args.port}`,
logger,
});
await Metro.runServer(metroConfig, {
host: args.host,
...,
unstable_extraMiddleware: [
middleware,
// Optionally extend with additional HTTP middleware
],
websocketEndpoints: {
...websocketEndpoints,
// Optionally extend with additional WebSocket endpoints
},
});
}
Included middleware
@react-native/dev-middleware
is designed for integrators such as @expo/dev-server
and @react-native/community-cli-plugin
. It provides a common default implementation for core React Native dev server responsibilities.
We intend to keep this to a narrow set of functionality, based around:
- Debugging — The Chrome DevTools protocol (CDP) endpoints supported by React Native, including the Inspector Proxy, which facilitates connections with multiple devices.
- Dev actions — Endpoints implementing core Dev Menu actions, e.g. reloading the app, opening the debugger frontend.
HTTP endpoints
DevMiddlewareAPI.middleware
These are exposed as a connect
middleware handler, assignable to Metro.runServer
or other compatible HTTP servers.
GET /json/list
, /json
(CDP)
Returns the list of available WebSocket targets for all connected React Native app sessions.
GET /json/version
(CDP)
Returns version metadata used by Chrome DevTools.
GET /debugger-frontend
Subpaths of this endpoint are reserved to serve the JavaScript debugger frontend.
POST /open-debugger
Open the JavaScript debugger for a given CDP target. Must be provided with one of the following query params:
device
— An ID unique to a combination of device and app, stable across installs. Implemented bygetInspectorDeviceId
on each native platform.target
— The target page ID as returned by/json/list
for the current dev server session.appId
(deprecated, legacy only) — The application bundle identifier to match (non-unique across multiple connected devices). This param will only match legacy Hermes debugger targets.
Example
curl -X POST 'http://localhost:8081/open-debugger?target=<targetId>'
WebSocket endpoints
DevMiddlewareAPI.websocketEndpoints
/inspector/device
WebSocket handler for registering device connections.
/inspector/debug
WebSocket handler that proxies CDP messages to/from the corresponding device.
Contributing
Changes to this package can be made locally and tested against the rn-tester
app, per the Contributing guide. During development, this package is automatically run from source with no build step.