1*edeec536SEvan Baconimport os from 'os'; 2*edeec536SEvan Bacon 3*edeec536SEvan Baconimport { LaunchBrowserTypes, type LaunchBrowserInstance } from './LaunchBrowser.types'; 4*edeec536SEvan Baconimport LaunchBrowserImplLinux from './LaunchBrowserImplLinux'; 5*edeec536SEvan Baconimport LaunchBrowserImplMacOS from './LaunchBrowserImplMacOS'; 6*edeec536SEvan Baconimport LaunchBrowserImplWindows from './LaunchBrowserImplWindows'; 7*edeec536SEvan Bacon 8*edeec536SEvan Baconexport type { LaunchBrowserInstance }; 9*edeec536SEvan Bacon 10*edeec536SEvan Baconconst IS_WSL = require('is-wsl') && !require('is-docker')(); 11*edeec536SEvan Bacon 12*edeec536SEvan Bacon/** 13*edeec536SEvan Bacon * Launch a browser for JavaScript inspector 14*edeec536SEvan Bacon */ 15*edeec536SEvan Baconexport async function launchBrowserAsync(url: string): Promise<LaunchBrowserInstance> { 16*edeec536SEvan Bacon const browser = createBrowser(); 17*edeec536SEvan Bacon const tempBrowserDir = await browser.createTempBrowserDir('expo-inspector'); 18*edeec536SEvan Bacon 19*edeec536SEvan Bacon // For dev-client connecting metro in LAN, the request to fetch sourcemaps may be blocked by Chromium 20*edeec536SEvan Bacon // with insecure-content (https page send xhr for http resource). 21*edeec536SEvan Bacon // Adding `--allow-running-insecure-content` to overcome this limitation 22*edeec536SEvan Bacon // without users manually allow insecure-content in site settings. 23*edeec536SEvan Bacon // However, if there is existing chromium browser process, the argument will not take effect. 24*edeec536SEvan Bacon // We also pass a `--user-data-dir=` as temporary profile and force chromium to create new browser process. 25*edeec536SEvan Bacon const launchArgs = [ 26*edeec536SEvan Bacon `--app=${url}`, 27*edeec536SEvan Bacon '--allow-running-insecure-content', 28*edeec536SEvan Bacon `--user-data-dir=${tempBrowserDir}`, 29*edeec536SEvan Bacon '--no-first-run', 30*edeec536SEvan Bacon '--no-default-browser-check', 31*edeec536SEvan Bacon ]; 32*edeec536SEvan Bacon 33*edeec536SEvan Bacon for (const browserType of [LaunchBrowserTypes.CHROME, LaunchBrowserTypes.EDGE]) { 34*edeec536SEvan Bacon const isSupported = await browser.isSupportedBrowser(browserType); 35*edeec536SEvan Bacon if (isSupported) { 36*edeec536SEvan Bacon return browser.launchAsync(browserType, launchArgs); 37*edeec536SEvan Bacon } 38*edeec536SEvan Bacon } 39*edeec536SEvan Bacon 40*edeec536SEvan Bacon throw new Error( 41*edeec536SEvan Bacon '[LaunchBrowser] Unable to find a browser on the host to open the inspector. Supported browsers: Google Chrome, Microsoft Edge' 42*edeec536SEvan Bacon ); 43*edeec536SEvan Bacon} 44*edeec536SEvan Bacon 45*edeec536SEvan Baconfunction createBrowser() { 46*edeec536SEvan Bacon if (os.platform() === 'darwin') { 47*edeec536SEvan Bacon return new LaunchBrowserImplMacOS(); 48*edeec536SEvan Bacon } 49*edeec536SEvan Bacon if (os.platform() === 'win32' || IS_WSL) { 50*edeec536SEvan Bacon return new LaunchBrowserImplWindows(); 51*edeec536SEvan Bacon } 52*edeec536SEvan Bacon if (os.platform() === 'linux') { 53*edeec536SEvan Bacon return new LaunchBrowserImplLinux(); 54*edeec536SEvan Bacon } 55*edeec536SEvan Bacon throw new Error('[LaunchBrowser] Unsupported host platform'); 56*edeec536SEvan Bacon} 57