diff --git a/flow-typed/npm/chrome-launcher_v0.15.x.js b/flow-typed/npm/chrome-launcher_v0.15.x.js index a0826994e9a..8f18f971b5c 100644 --- a/flow-typed/npm/chrome-launcher_v0.15.x.js +++ b/flow-typed/npm/chrome-launcher_v0.15.x.js @@ -42,6 +42,7 @@ declare module 'chrome-launcher' { }; declare class Launcher { + getChromePath(): string; launch(options: Options): Promise; } diff --git a/flow-typed/npm/chromium-edge-launcher_v1.x.x.js b/flow-typed/npm/chromium-edge-launcher_v1.x.x.js new file mode 100644 index 00000000000..dc3e9962ab8 --- /dev/null +++ b/flow-typed/npm/chromium-edge-launcher_v1.x.x.js @@ -0,0 +1,53 @@ +/** + * 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 + * @format + * @oncall react_native + */ + +declare module 'chromium-edge-launcher' { + import typeof fs from 'fs'; + import typeof childProcess from 'child_process'; + import type {ChildProcess} from 'child_process'; + + declare export type Options = { + startingUrl?: string, + edgeFlags?: Array, + prefs?: mixed, + port?: number, + handleSIGINT?: boolean, + edgePath?: string, + userDataDir?: string | boolean, + logLevel?: 'verbose' | 'info' | 'error' | 'warn' | 'silent', + ignoreDefaultFlags?: boolean, + connectionPollInterval?: number, + maxConnectionRetries?: number, + envVars?: {[key: string]: ?string}, + }; + + declare export type LaunchedEdge = { + pid: number, + port: number, + process: ChildProcess, + kill: () => void, + }; + + declare export type ModuleOverrides = { + fs?: fs, + spawn?: childProcess['spawn'], + }; + + declare class Launcher { + getFirstInstallation(): string; + launch(options: Options): Promise; + } + + declare module.exports: { + default: Launcher, + Launcher: Launcher, + }; +} diff --git a/packages/dev-middleware/package.json b/packages/dev-middleware/package.json index 7782439c471..36b0a29a1da 100644 --- a/packages/dev-middleware/package.json +++ b/packages/dev-middleware/package.json @@ -24,6 +24,7 @@ "dependencies": { "@isaacs/ttlcache": "^1.4.1", "chrome-launcher": "^0.15.2", + "chromium-edge-launcher": "^1.0.0", "connect": "^3.6.5", "debug": "^2.2.0", "node-fetch": "^2.2.0", diff --git a/packages/dev-middleware/src/utils/launchDebuggerAppWindow.js b/packages/dev-middleware/src/utils/launchDebuggerAppWindow.js index a2ae765ba36..5792006dec7 100644 --- a/packages/dev-middleware/src/utils/launchDebuggerAppWindow.js +++ b/packages/dev-middleware/src/utils/launchDebuggerAppWindow.js @@ -15,6 +15,7 @@ import path from 'path'; import osTempDir from 'temp-dir'; const ChromeLauncher = require('chrome-launcher'); +const {Launcher: EdgeLauncher} = require('chromium-edge-launcher'); /** * Attempt to open a debugger frontend URL as a Google Chrome app window. @@ -27,24 +28,37 @@ export default async function launchDebuggerAppWindow( */ intent: 'open-debugger', ): Promise { - const browserType = 'chrome'; + let browserType = 'chrome'; + let chromePath; + + try { + // Locate Chrome installation path, will throw if not found + chromePath = ChromeLauncher.getChromePath(); + } catch (e) { + browserType = 'edge'; + chromePath = EdgeLauncher.getFirstInstallation(); + + if (chromePath == null) { + throw new Error( + 'Unable to find a browser on the host to open the debugger. ' + + 'Supported browsers: Google Chrome, Microsoft Edge.\n' + + url, + ); + } + } + const userDataDir = await createTempDir( `react-native-${intent}-${browserType}`, ); - try { - return ChromeLauncher.launch({ - chromeFlags: [ - `--app=${url}`, - `--user-data-dir=${userDataDir}`, - '--window-size=1200,600', - ], - }); - } catch (e) { - throw new Error( - 'Unable to find a browser on the host to open the debugger. Supported browsers: Google Chrome', - ); - } + return ChromeLauncher.launch({ + chromePath, + chromeFlags: [ + `--app=${url}`, + `--user-data-dir=${userDataDir}`, + '--window-size=1200,600', + ], + }); } async function createTempDir(dirName: string): Promise { diff --git a/yarn.lock b/yarn.lock index fe0f796ba89..ffaf238981f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4665,6 +4665,18 @@ chrome-launcher@^0.15.0, chrome-launcher@^0.15.2: is-wsl "^2.2.0" lighthouse-logger "^1.0.0" +chromium-edge-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz#0443083074715a13c669530b35df7bfea33b1509" + integrity sha512-pgtgjNKZ7i5U++1g1PWv75umkHvhVTDOQIZ+sjeUX9483S7Y6MUvO0lrd7ShGlQlFHMN4SwKTCq/X8hWrbv2KA== + dependencies: + "@types/node" "*" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + mkdirp "^1.0.4" + rimraf "^3.0.2" + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -8698,7 +8710,7 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: dependencies: minimist "^1.2.6" -mkdirp@^1.0.3: +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==