Summary: `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. Differential Revision: D65974487
@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 bygetInspectorDeviceIdon each native platform.target— The target page ID as returned by/json/listfor 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.