mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
37b61aca1b
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53464 Changelog: [Internal] Minor followup from D78351937 - the Fusebox console notice still mentions that RNDT requires Chrome or Edge. Let's remove this mention for users opted into the standalone shell experiment. Reviewed By: huntie Differential Revision: D81040965 fbshipit-source-id: a290d3164261f8a1087229edfe3f69a2a9b49960
213 lines
6.4 KiB
JavaScript
213 lines
6.4 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
*/
|
|
|
|
import type {CreateCustomMessageHandlerFn} from './inspector-proxy/CustomMessageHandler';
|
|
import type {BrowserLauncher} from './types/BrowserLauncher';
|
|
import type {EventReporter, ReportableEvent} from './types/EventReporter';
|
|
import type {Experiments, ExperimentsConfig} from './types/Experiments';
|
|
import type {Logger} from './types/Logger';
|
|
import type {NextHandleFunction} from 'connect';
|
|
|
|
import InspectorProxy from './inspector-proxy/InspectorProxy';
|
|
import openDebuggerMiddleware from './middleware/openDebuggerMiddleware';
|
|
import DefaultBrowserLauncher from './utils/DefaultBrowserLauncher';
|
|
import reactNativeDebuggerFrontendPath from '@react-native/debugger-frontend';
|
|
import connect from 'connect';
|
|
import path from 'path';
|
|
import serveStaticMiddleware from 'serve-static';
|
|
|
|
type Options = $ReadOnly<{
|
|
projectRoot: string,
|
|
|
|
/**
|
|
* The base URL to the dev server, as reachable from the machine on which
|
|
* dev-middleware is hosted. Typically `http://localhost:${metroPort}`.
|
|
*/
|
|
serverBaseUrl: string,
|
|
|
|
logger?: Logger,
|
|
|
|
/**
|
|
* An interface for integrators to provide a custom implementation for
|
|
* opening URLs in a web browser.
|
|
*
|
|
* This is an unstable API with no semver guarantees.
|
|
*/
|
|
unstable_browserLauncher?: BrowserLauncher,
|
|
|
|
/**
|
|
* An interface for logging events.
|
|
*
|
|
* This is an unstable API with no semver guarantees.
|
|
*/
|
|
unstable_eventReporter?: EventReporter,
|
|
|
|
/**
|
|
* The set of experimental features to enable.
|
|
*
|
|
* This is an unstable API with no semver guarantees.
|
|
*/
|
|
unstable_experiments?: ExperimentsConfig,
|
|
|
|
/**
|
|
* Create custom handler to add support for unsupported CDP events, or debuggers.
|
|
* This handler is instantiated per logical device and debugger pair.
|
|
*
|
|
* This is an unstable API with no semver guarantees.
|
|
*/
|
|
unstable_customInspectorMessageHandler?: CreateCustomMessageHandlerFn,
|
|
|
|
/**
|
|
* Whether to measure the event loop performance of inspector proxy and log report it via the event reporter.
|
|
*
|
|
* This is an unstable API with no semver guarantees.
|
|
*/
|
|
unstable_trackInspectorProxyEventLoopPerf?: boolean,
|
|
}>;
|
|
|
|
type DevMiddlewareAPI = $ReadOnly<{
|
|
middleware: NextHandleFunction,
|
|
websocketEndpoints: {[path: string]: ws$WebSocketServer},
|
|
}>;
|
|
|
|
export default function createDevMiddleware({
|
|
projectRoot,
|
|
serverBaseUrl,
|
|
logger,
|
|
// $FlowFixMe[incompatible-type]
|
|
unstable_browserLauncher = DefaultBrowserLauncher,
|
|
unstable_eventReporter,
|
|
unstable_experiments: experimentConfig = {},
|
|
unstable_customInspectorMessageHandler,
|
|
unstable_trackInspectorProxyEventLoopPerf = false,
|
|
}: Options): DevMiddlewareAPI {
|
|
const experiments = getExperiments(experimentConfig);
|
|
const eventReporter = createWrappedEventReporter(
|
|
unstable_eventReporter,
|
|
logger,
|
|
experiments,
|
|
);
|
|
|
|
const inspectorProxy = new InspectorProxy(
|
|
projectRoot,
|
|
serverBaseUrl,
|
|
eventReporter,
|
|
experiments,
|
|
logger,
|
|
unstable_customInspectorMessageHandler,
|
|
unstable_trackInspectorProxyEventLoopPerf,
|
|
);
|
|
|
|
const middleware = connect()
|
|
.use(
|
|
'/open-debugger',
|
|
openDebuggerMiddleware({
|
|
serverBaseUrl,
|
|
inspectorProxy,
|
|
browserLauncher: unstable_browserLauncher,
|
|
eventReporter,
|
|
experiments,
|
|
logger,
|
|
}),
|
|
)
|
|
.use(
|
|
'/debugger-frontend/embedder-static/embedderScript.js',
|
|
(_req, res) => {
|
|
res.setHeader('Content-Type', 'application/javascript');
|
|
res.end('');
|
|
},
|
|
)
|
|
.use(
|
|
'/debugger-frontend',
|
|
serveStaticMiddleware(path.join(reactNativeDebuggerFrontendPath), {
|
|
fallthrough: false,
|
|
}),
|
|
)
|
|
.use((...args) => inspectorProxy.processRequest(...args));
|
|
|
|
return {
|
|
middleware,
|
|
websocketEndpoints: inspectorProxy.createWebSocketListeners(),
|
|
};
|
|
}
|
|
|
|
function getExperiments(config: ExperimentsConfig): Experiments {
|
|
return {
|
|
enableOpenDebuggerRedirect: config.enableOpenDebuggerRedirect ?? false,
|
|
enableNetworkInspector: config.enableNetworkInspector ?? false,
|
|
enableStandaloneFuseboxShell: config.enableStandaloneFuseboxShell ?? false,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a wrapped EventReporter that locally intercepts events to
|
|
* log to the terminal.
|
|
*/
|
|
function createWrappedEventReporter(
|
|
reporter: ?EventReporter,
|
|
logger: ?Logger,
|
|
experiments: Experiments,
|
|
): EventReporter {
|
|
return {
|
|
logEvent(event: ReportableEvent) {
|
|
switch (event.type) {
|
|
case 'profiling_target_registered':
|
|
logger?.info(
|
|
"Profiling build target '%s' registered for debugging",
|
|
event.appId ?? 'unknown',
|
|
);
|
|
break;
|
|
case 'fusebox_console_notice':
|
|
logger?.info(
|
|
'\u001B[1m\u001B[7m💡 JavaScript logs have moved!\u001B[22m They can now be ' +
|
|
'viewed in React Native DevTools. Tip: Type \u001B[1mj\u001B[22m in ' +
|
|
'the terminal to open' +
|
|
(experiments.enableStandaloneFuseboxShell
|
|
? ''
|
|
: ' (requires Google Chrome or Microsoft Edge)') +
|
|
'.\u001B[27m',
|
|
);
|
|
break;
|
|
case 'fusebox_shell_preparation_attempt':
|
|
switch (event.result.code) {
|
|
case 'success':
|
|
case 'not_implemented':
|
|
break;
|
|
case 'unexpected_error': {
|
|
let message =
|
|
event.result.humanReadableMessage ??
|
|
'An unknown error occurred while installing React Native DevTools.';
|
|
if (event.result.verboseInfo != null) {
|
|
message += ` Details:\n\n${event.result.verboseInfo}`;
|
|
} else {
|
|
message += '.';
|
|
}
|
|
logger?.error(message);
|
|
break;
|
|
}
|
|
case 'possible_corruption':
|
|
case 'platform_not_supported':
|
|
case 'likely_offline':
|
|
logger?.warn(
|
|
event.result.humanReadableMessage ??
|
|
`An error of type ${event.result.code} occurred while installing React Native DevTools.`,
|
|
);
|
|
break;
|
|
default:
|
|
(event.result.code: empty);
|
|
break;
|
|
}
|
|
}
|
|
|
|
reporter?.logEvent(event);
|
|
},
|
|
};
|
|
}
|