@expo/cli 55.0.13 → 55.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/cli +1 -1
- package/build/src/events/index.js +1 -1
- package/build/src/export/embed/exportEmbedAsync.js +4 -1
- package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
- package/build/src/export/embed/index.js +5 -0
- package/build/src/export/embed/index.js.map +1 -1
- package/build/src/export/embed/resolveOptions.js +2 -1
- package/build/src/export/embed/resolveOptions.js.map +1 -1
- package/build/src/export/exportStaticAsync.js +3 -2
- package/build/src/export/exportStaticAsync.js.map +1 -1
- package/build/src/start/platforms/ios/devicectl.js +1 -0
- package/build/src/start/platforms/ios/devicectl.js.map +1 -1
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +6 -4
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +5 -4
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/runServer-fork.js +1 -1
- package/build/src/start/server/metro/runServer-fork.js.map +1 -1
- package/build/src/start/server/metro/serializeHtml.js +16 -1
- package/build/src/start/server/metro/serializeHtml.js.map +1 -1
- package/build/src/start/startAsync.js +6 -1
- package/build/src/start/startAsync.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/platforms/ios/devicectl.ts"],"sourcesContent":["/**\n * Copyright © 2024 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport JsonFile from '@expo/json-file';\nimport spawnAsync, { SpawnOptions, SpawnResult } from '@expo/spawn-async';\nimport chalk from 'chalk';\nimport { spawn, execSync } from 'child_process';\nimport fs from 'fs';\nimport assert from 'node:assert';\nimport { Ora } from 'ora';\nimport { EOL } from 'os';\nimport path from 'path';\n\nimport { xcrunAsync } from './xcrun';\nimport { getExpoHomeDirectory } from '../../../api/user/UserSettings';\nimport * as Log from '../../../log';\nimport { createTempFilePath } from '../../../utils/createTempPath';\nimport { CommandError } from '../../../utils/errors';\nimport { installExitHooks } from '../../../utils/exit';\nimport { isInteractive } from '../../../utils/interactive';\nimport { ora } from '../../../utils/ora';\nimport { confirmAsync } from '../../../utils/prompts';\n\nconst DEVICE_CTL_EXISTS_PATH = path.join(getExpoHomeDirectory(), 'devicectl-exists');\n\nconst debug = require('debug')('expo:devicectl') as typeof console.log;\n\ntype AnyEnum<T extends string = string> = T | (string & object);\n\ntype DeviceCtlDevice = {\n capabilities: DeviceCtlDeviceCapability[];\n connectionProperties: DeviceCtlConnectionProperties;\n deviceProperties: DeviceCtlDeviceProperties;\n hardwareProperties: DeviceCtlHardwareProperties;\n /** \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A\" */\n identifier: string;\n visibilityClass: AnyEnum<'default'>;\n};\n\ntype DeviceCtlHardwareProperties = {\n cpuType: DeviceCtlCpuType;\n deviceType: AnyEnum<'iPhone'>;\n /** 1114404411111111 */\n ecid: number;\n /** \"D74AP\" */\n hardwareModel: string;\n /** 512000000000 */\n internalStorageCapacity: number;\n /** true */\n isProductionFused: boolean;\n /** \"iPhone 14 Pro Max\" */\n marketingName: string;\n /** \"iOS\" */\n platform: AnyEnum<'iOS' | 'xrOS'>;\n /** \"iPhone15,3\" */\n productType: AnyEnum<'iPhone13,4' | 'iPhone15,3'>;\n reality: AnyEnum<'physical'>;\n /** \"X2X1CC1XXX\" */\n serialNumber: string;\n supportedCPUTypes: DeviceCtlCpuType[];\n /** [1] */\n supportedDeviceFamilies: number[];\n thinningProductType: AnyEnum<'iPhone15,3'>;\n /** \"00001110-001111110110101A\" */\n udid: string;\n};\n\ntype DeviceCtlDeviceProperties = {\n /** true */\n bootedFromSnapshot: boolean;\n /** \"com.apple.os.update-AD0CF111ACFF11A11111A76A3D1262AE42A3F56F305AF5AE1135393A7A14A7D1\" */\n bootedSnapshotName: string;\n /** false */\n ddiServicesAvailable: boolean;\n\n developerModeStatus: AnyEnum<'enabled'>;\n /** false */\n hasInternalOSBuild: boolean;\n /** \"Evan's phone\" */\n name: string;\n /** \"21E236\" */\n osBuildUpdate: string;\n /** \"17.4.1\" */\n osVersionNumber: string;\n /** false */\n rootFileSystemIsWritable: boolean;\n};\n\ntype DeviceCtlDeviceCapability =\n | {\n name: AnyEnum;\n featureIdentifier: AnyEnum;\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.connectdevice';\n name: 'Connect to Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.unpairdevice';\n name: 'Unpair Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.acquireusageassertion';\n name: 'Acquire Usage Assertion';\n };\n\ntype DeviceCtlConnectionProperties = {\n authenticationType: AnyEnum<'manualPairing'>;\n isMobileDeviceOnly: boolean;\n /** \"2024-04-20T22:50:04.244Z\" */\n lastConnectionDate: string;\n pairingState: AnyEnum<'paired'>;\n /** [\"00001111-001111110110101A.coredevice.local\", \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A.coredevice.local\"] */\n potentialHostnames: string[];\n transportType: AnyEnum<'localNetwork' | 'wired'>;\n tunnelState: AnyEnum<'disconnected' | 'unavailable'>;\n tunnelTransportProtocol: AnyEnum<'tcp'>;\n};\n\ntype DeviceCtlCpuType = {\n name: AnyEnum<'arm64e' | 'arm64' | 'arm64_32'>;\n subType: number;\n /** 16777228 */\n type: number;\n};\n\n/** Run a `devicectl` command. */\nexport async function devicectlAsync(\n args: (string | undefined)[],\n options?: SpawnOptions\n): Promise<SpawnResult> {\n try {\n return await xcrunAsync(['devicectl', ...args], options);\n } catch (error: any) {\n if (error instanceof CommandError) {\n throw error;\n }\n if ('stderr' in error) {\n const errorCodes = getDeviceCtlErrorCodes(error.stderr);\n if (errorCodes.includes('Locked')) {\n throw new CommandError('APPLE_DEVICE_LOCKED', 'Device is locked, unlock and try again.');\n }\n }\n throw error;\n }\n}\n\nexport async function getConnectedAppleDevicesAsync() {\n if (!hasDevicectlEverBeenInstalled()) {\n debug('devicectl not found, skipping remote Apple devices.');\n return [];\n }\n\n const tmpPath = createTempFilePath();\n const devices = await devicectlAsync([\n 'list',\n 'devices',\n '--json-output',\n tmpPath,\n // Give two seconds before timing out: between 5 and 9223372036854775807\n '--timeout',\n '5',\n ]);\n debug(devices.stdout);\n const devicesJson = await JsonFile.readAsync(tmpPath);\n\n if (![2, 3].includes((devicesJson as any)?.info?.jsonVersion)) {\n Log.warn(\n 'Unexpected devicectl JSON version output from devicectl. Connecting to physical Apple devices may not work as expected.'\n );\n }\n\n assertDevicesJson(devicesJson);\n\n return devicesJson.result.devices as DeviceCtlDevice[];\n}\n\nfunction assertDevicesJson(\n results: any\n): asserts results is { result: { devices: DeviceCtlDevice[] } } {\n assert(\n results != null && 'result' in results && Array.isArray(results?.result?.devices),\n 'Malformed JSON output from devicectl: ' + JSON.stringify(results, null, 2)\n );\n}\n\nexport async function launchBinaryOnMacAsync(\n bundleId: string,\n appBinaryPath: string\n): Promise<void> {\n const args = ['-b', bundleId, appBinaryPath];\n try {\n await spawnAsync('open', args);\n } catch (error: any) {\n if ('code' in error) {\n if (error.code === 1) {\n throw new CommandError(\n 'MACOS_LAUNCH',\n 'Failed to launch the compatible binary on macOS: open ' +\n args.join(' ') +\n '\\n\\n' +\n error.message\n );\n }\n }\n throw error;\n }\n}\n\nasync function installAppWithDeviceCtlAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void\n): Promise<void> {\n const maxAttempts = 3;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n await installAppWithDeviceCtlInternalAsync(uuid, bundleIdOrAppPath, onProgress, attempt);\n return;\n } catch (error: any) {\n if (error.code === 'detached') {\n throw error;\n }\n const isTransientDisconnect =\n error.message &&\n (error.message.includes('CoreDeviceError') || error.message.includes('0xFA0'));\n\n if (!isTransientDisconnect || attempt === maxAttempts) {\n throw error;\n }\n const backoffDelay = 500 + Math.pow(2, attempt - 1) * 500;\n await new Promise((resolve) => setTimeout(resolve, backoffDelay));\n }\n }\n}\n\nasync function installAppWithDeviceCtlInternalAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void,\n attempt: number\n): Promise<void> {\n // 𝝠 xcrun devicectl device install app --device 00001110-001111110110101A /Users/evanbacon/Library/Developer/Xcode/DerivedData/Router-hgbqaxzhrhkiftfweydvhgttadvn/Build/Products/Debug-iphoneos/Router.app --verbose\n return new Promise((resolve, reject) => {\n const args: string[] = [\n 'devicectl',\n 'device',\n 'install',\n 'app',\n '--device',\n uuid,\n bundleIdOrAppPath,\n ];\n const childProcess = spawn('xcrun', args);\n debug('xcrun ' + args.join(' '));\n\n let currentProgress = 0;\n let hasStarted = false;\n\n function updateProgress(progress: number) {\n hasStarted = true;\n if (progress <= currentProgress) {\n return;\n }\n currentProgress = progress;\n const statusPrefix = attempt > 1 ? `Installing (attempt ${attempt})` : 'Installing';\n onProgress({\n progress,\n isComplete: progress === 100,\n status: statusPrefix,\n });\n }\n\n childProcess.stdout.on('data', (data: Buffer) => {\n // Sometimes more than one chunk comes at a time, here we split by system newline,\n // then trim and filter.\n const strings = data\n .toString()\n .split(EOL)\n .map((value) => value.trim());\n\n strings.forEach((str) => {\n // Match the progress percentage:\n // - '34%... 35%...' -> 34\n // - '31%...' -> 31\n // - 'Complete!' -> 100\n\n const match = str.match(/(\\d+)%\\.\\.\\./);\n if (match) {\n updateProgress(parseInt(match[1], 10));\n } else if (hasStarted) {\n updateProgress(100);\n }\n });\n\n debug('[stdout]:', strings);\n });\n\n let stderrBuffer = '';\n childProcess.stderr.on('data', (data: Buffer) => {\n stderrBuffer += data.toString();\n });\n\n childProcess.on('close', (code) => {\n debug('[close]: ' + code);\n if (code === 0) {\n resolve();\n } else {\n const err = new Error(stderrBuffer || `Command failed with exit code ${code}`);\n (err as any).code = code;\n detach(err);\n }\n });\n\n const detach = async (err?: Error) => {\n off?.();\n if (childProcess) {\n return new Promise<void>((resolve) => {\n childProcess?.on('close', () => resolve());\n childProcess?.kill();\n reject(err ?? new CommandError('detached'));\n });\n }\n };\n\n const off = installExitHooks(() => detach());\n });\n}\n\nexport async function launchAppWithDeviceCtl(deviceId: string, bundleId: string) {\n await devicectlAsync(['device', 'process', 'launch', '--device', deviceId, bundleId]);\n}\n\n/** Find all error codes from the output log */\nfunction getDeviceCtlErrorCodes(log: string): string[] {\n return [...log.matchAll(/BSErrorCodeDescription\\s+=\\s+(.*)$/gim)].map(([_line, code]) => code);\n}\n\nlet hasEverBeenInstalled: boolean | undefined;\n\nexport function hasDevicectlEverBeenInstalled() {\n if (hasEverBeenInstalled) return hasEverBeenInstalled;\n // It doesn't appear possible for devicectl to ever be uninstalled. We can just check once and store this result forever\n // to prevent cold boots of devicectl from slowing down all invocations of `expo run ios`\n if (fs.existsSync(DEVICE_CTL_EXISTS_PATH)) {\n hasEverBeenInstalled = true;\n return true;\n }\n\n const isInstalled = isDevicectlInstalled();\n\n if (isInstalled) {\n fs.writeFileSync(DEVICE_CTL_EXISTS_PATH, '1');\n }\n hasEverBeenInstalled = isInstalled;\n return isInstalled;\n}\n\nfunction isDevicectlInstalled() {\n try {\n execSync('xcrun devicectl --version', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wraps the apple device method for installing and running an app,\n * adds indicator and retry loop for when the device is locked.\n */\nexport async function installAndLaunchAppAsync(props: {\n bundle: string;\n bundleIdentifier: string;\n udid: string;\n deviceName: string;\n}): Promise<void> {\n debug('Running on device:', props);\n const { bundle, bundleIdentifier, udid, deviceName } = props;\n let indicator: Ora | undefined;\n\n try {\n if (!indicator) {\n indicator = ora(`Connecting to: ${props.deviceName}`).start();\n }\n\n await installAppWithDeviceCtlAsync(\n udid,\n bundle,\n ({\n status,\n isComplete,\n progress,\n }: {\n status: string;\n isComplete: boolean;\n progress: number;\n }) => {\n if (!indicator) {\n indicator = ora(status).start();\n }\n indicator.text = `${chalk.bold(status)} ${progress}%`;\n if (isComplete) {\n indicator.succeed();\n }\n }\n );\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n throw error;\n }\n\n async function launchAppOptionally() {\n try {\n await launchAppWithDeviceCtl(udid, bundleIdentifier);\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n if (error.code === 'APPLE_DEVICE_LOCKED') {\n // Get the app name from the binary path.\n const appName = path.basename(bundle).split('.')[0] ?? 'app';\n if (\n isInteractive() &&\n (await confirmAsync({\n message: `Cannot launch ${appName} because the device is locked. Unlock ${deviceName} to continue...`,\n initial: true,\n }))\n ) {\n return launchAppOptionally();\n }\n throw new CommandError(\n `Cannot launch ${appName} on ${deviceName} because the device is locked.`\n );\n }\n throw error;\n }\n }\n\n await launchAppOptionally();\n}\n"],"names":["devicectlAsync","getConnectedAppleDevicesAsync","hasDevicectlEverBeenInstalled","installAndLaunchAppAsync","launchAppWithDeviceCtl","launchBinaryOnMacAsync","DEVICE_CTL_EXISTS_PATH","path","join","getExpoHomeDirectory","debug","require","args","options","xcrunAsync","error","CommandError","errorCodes","getDeviceCtlErrorCodes","stderr","includes","tmpPath","createTempFilePath","devices","stdout","devicesJson","JsonFile","readAsync","info","jsonVersion","Log","warn","assertDevicesJson","result","results","assert","Array","isArray","JSON","stringify","bundleId","appBinaryPath","spawnAsync","code","message","installAppWithDeviceCtlAsync","uuid","bundleIdOrAppPath","onProgress","maxAttempts","attempt","installAppWithDeviceCtlInternalAsync","isTransientDisconnect","backoffDelay","Math","pow","Promise","resolve","setTimeout","reject","childProcess","spawn","currentProgress","hasStarted","updateProgress","progress","statusPrefix","isComplete","status","on","data","strings","toString","split","EOL","map","value","trim","forEach","str","match","parseInt","stderrBuffer","err","Error","detach","off","kill","installExitHooks","deviceId","log","matchAll","_line","hasEverBeenInstalled","fs","existsSync","isInstalled","isDevicectlInstalled","writeFileSync","execSync","stdio","props","bundle","bundleIdentifier","udid","deviceName","indicator","ora","start","text","chalk","bold","succeed","fail","launchAppOptionally","appName","basename","isInteractive","confirmAsync","initial"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/platforms/ios/devicectl.ts"],"sourcesContent":["/**\n * Copyright © 2024 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport JsonFile from '@expo/json-file';\nimport spawnAsync, { SpawnOptions, SpawnResult } from '@expo/spawn-async';\nimport chalk from 'chalk';\nimport { spawn, execSync } from 'child_process';\nimport fs from 'fs';\nimport assert from 'node:assert';\nimport { Ora } from 'ora';\nimport { EOL } from 'os';\nimport path from 'path';\n\nimport { xcrunAsync } from './xcrun';\nimport { getExpoHomeDirectory } from '../../../api/user/UserSettings';\nimport * as Log from '../../../log';\nimport { createTempFilePath } from '../../../utils/createTempPath';\nimport { CommandError } from '../../../utils/errors';\nimport { installExitHooks } from '../../../utils/exit';\nimport { isInteractive } from '../../../utils/interactive';\nimport { ora } from '../../../utils/ora';\nimport { confirmAsync } from '../../../utils/prompts';\n\nconst DEVICE_CTL_EXISTS_PATH = path.join(getExpoHomeDirectory(), 'devicectl-exists');\n\nconst debug = require('debug')('expo:devicectl') as typeof console.log;\n\ntype AnyEnum<T extends string = string> = T | (string & object);\n\ntype DeviceCtlDevice = {\n capabilities: DeviceCtlDeviceCapability[];\n connectionProperties: DeviceCtlConnectionProperties;\n deviceProperties: DeviceCtlDeviceProperties;\n hardwareProperties: DeviceCtlHardwareProperties;\n /** \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A\" */\n identifier: string;\n visibilityClass: AnyEnum<'default'>;\n};\n\ntype DeviceCtlHardwareProperties = {\n cpuType: DeviceCtlCpuType;\n deviceType: AnyEnum<'iPhone'>;\n /** 1114404411111111 */\n ecid: number;\n /** \"D74AP\" */\n hardwareModel: string;\n /** 512000000000 */\n internalStorageCapacity: number;\n /** true */\n isProductionFused: boolean;\n /** \"iPhone 14 Pro Max\" */\n marketingName: string;\n /** \"iOS\" */\n platform: AnyEnum<'iOS' | 'xrOS'>;\n /** \"iPhone15,3\" */\n productType: AnyEnum<'iPhone13,4' | 'iPhone15,3'>;\n reality: AnyEnum<'physical'>;\n /** \"X2X1CC1XXX\" */\n serialNumber: string;\n supportedCPUTypes: DeviceCtlCpuType[];\n /** [1] */\n supportedDeviceFamilies: number[];\n thinningProductType: AnyEnum<'iPhone15,3'>;\n /** \"00001110-001111110110101A\" */\n udid: string;\n};\n\ntype DeviceCtlDeviceProperties = {\n /** true */\n bootedFromSnapshot: boolean;\n /** \"com.apple.os.update-AD0CF111ACFF11A11111A76A3D1262AE42A3F56F305AF5AE1135393A7A14A7D1\" */\n bootedSnapshotName: string;\n /** false */\n ddiServicesAvailable: boolean;\n\n developerModeStatus: AnyEnum<'enabled'>;\n /** false */\n hasInternalOSBuild: boolean;\n /** \"Evan's phone\" */\n name: string;\n /** \"21E236\" */\n osBuildUpdate: string;\n /** \"17.4.1\" */\n osVersionNumber: string;\n /** false */\n rootFileSystemIsWritable: boolean;\n};\n\ntype DeviceCtlDeviceCapability =\n | {\n name: AnyEnum;\n featureIdentifier: AnyEnum;\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.connectdevice';\n name: 'Connect to Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.unpairdevice';\n name: 'Unpair Device';\n }\n | {\n featureIdentifier: 'com.apple.coredevice.feature.acquireusageassertion';\n name: 'Acquire Usage Assertion';\n };\n\ntype DeviceCtlConnectionProperties = {\n authenticationType: AnyEnum<'manualPairing'>;\n isMobileDeviceOnly: boolean;\n /** \"2024-04-20T22:50:04.244Z\" */\n lastConnectionDate: string;\n pairingState: AnyEnum<'paired'>;\n /** [\"00001111-001111110110101A.coredevice.local\", \"A1A1AAA1-0011-1AA1-11A1-10A1111AA11A.coredevice.local\"] */\n potentialHostnames: string[];\n transportType: AnyEnum<'localNetwork' | 'wired'>;\n tunnelState: AnyEnum<'disconnected' | 'unavailable'>;\n tunnelTransportProtocol: AnyEnum<'tcp'>;\n};\n\ntype DeviceCtlCpuType = {\n name: AnyEnum<'arm64e' | 'arm64' | 'arm64_32'>;\n subType: number;\n /** 16777228 */\n type: number;\n};\n\n/** Run a `devicectl` command. */\nexport async function devicectlAsync(\n args: (string | undefined)[],\n options?: SpawnOptions\n): Promise<SpawnResult> {\n try {\n return await xcrunAsync(['devicectl', ...args], options);\n } catch (error: any) {\n if (error instanceof CommandError) {\n throw error;\n }\n if ('stderr' in error) {\n const errorCodes = getDeviceCtlErrorCodes(error.stderr);\n if (errorCodes.includes('Locked')) {\n throw new CommandError('APPLE_DEVICE_LOCKED', 'Device is locked, unlock and try again.');\n }\n }\n throw error;\n }\n}\n\nexport async function getConnectedAppleDevicesAsync() {\n if (!hasDevicectlEverBeenInstalled()) {\n debug('devicectl not found, skipping remote Apple devices.');\n return [];\n }\n\n const tmpPath = createTempFilePath();\n const devices = await devicectlAsync([\n 'list',\n 'devices',\n '--json-output',\n tmpPath,\n // Give two seconds before timing out: between 5 and 9223372036854775807\n '--timeout',\n '5',\n ]);\n debug(devices.stdout);\n const devicesJson = await JsonFile.readAsync(tmpPath);\n\n if (![2, 3].includes((devicesJson as any)?.info?.jsonVersion)) {\n Log.warn(\n 'Unexpected devicectl JSON version output from devicectl. Connecting to physical Apple devices may not work as expected.'\n );\n }\n\n assertDevicesJson(devicesJson);\n\n return devicesJson.result.devices as DeviceCtlDevice[];\n}\n\nfunction assertDevicesJson(\n results: any\n): asserts results is { result: { devices: DeviceCtlDevice[] } } {\n assert(\n results != null && 'result' in results && Array.isArray(results?.result?.devices),\n 'Malformed JSON output from devicectl: ' + JSON.stringify(results, null, 2)\n );\n}\n\nexport async function launchBinaryOnMacAsync(\n bundleId: string,\n appBinaryPath: string\n): Promise<void> {\n const args = ['-b', bundleId, appBinaryPath];\n try {\n await spawnAsync('open', args);\n } catch (error: any) {\n if ('code' in error) {\n if (error.code === 1) {\n throw new CommandError(\n 'MACOS_LAUNCH',\n 'Failed to launch the compatible binary on macOS: open ' +\n args.join(' ') +\n '\\n\\n' +\n error.message\n );\n }\n }\n throw error;\n }\n}\n\nasync function installAppWithDeviceCtlAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void\n): Promise<void> {\n const maxAttempts = 3;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n await installAppWithDeviceCtlInternalAsync(uuid, bundleIdOrAppPath, onProgress, attempt);\n return;\n } catch (error: any) {\n if (error.code === 'detached') {\n throw error;\n }\n const isTransientDisconnect =\n error.message &&\n (error.message.includes('CoreDeviceError') || error.message.includes('0xFA0'));\n\n if (!isTransientDisconnect || attempt === maxAttempts) {\n throw error;\n }\n const backoffDelay = 500 + Math.pow(2, attempt - 1) * 500;\n await new Promise((resolve) => setTimeout(resolve, backoffDelay));\n }\n }\n}\n\nasync function installAppWithDeviceCtlInternalAsync(\n uuid: string,\n bundleIdOrAppPath: string,\n onProgress: (event: { status: string; isComplete: boolean; progress: number }) => void,\n attempt: number\n): Promise<void> {\n // 𝝠 xcrun devicectl device install app --device 00001110-001111110110101A /Users/evanbacon/Library/Developer/Xcode/DerivedData/Router-hgbqaxzhrhkiftfweydvhgttadvn/Build/Products/Debug-iphoneos/Router.app --verbose\n return new Promise((resolve, reject) => {\n const args: string[] = [\n 'devicectl',\n 'device',\n 'install',\n 'app',\n '--device',\n uuid,\n bundleIdOrAppPath,\n ];\n const childProcess = spawn('xcrun', args);\n debug('xcrun ' + args.join(' '));\n\n let currentProgress = 0;\n let hasStarted = false;\n\n function updateProgress(progress: number) {\n hasStarted = true;\n if (progress <= currentProgress) {\n return;\n }\n currentProgress = progress;\n const statusPrefix = attempt > 1 ? `Installing (attempt ${attempt})` : 'Installing';\n onProgress({\n progress,\n isComplete: progress === 100,\n status: statusPrefix,\n });\n }\n\n childProcess.stdout.on('data', (data: Buffer) => {\n // Sometimes more than one chunk comes at a time, here we split by system newline,\n // then trim and filter.\n const strings = data\n .toString()\n .split(EOL)\n .map((value) => value.trim());\n\n strings.forEach((str) => {\n // Match the progress percentage:\n // - '34%... 35%...' -> 34\n // - '31%...' -> 31\n // - 'Complete!' -> 100\n\n const match = str.match(/(\\d+)%\\.\\.\\./);\n if (match) {\n updateProgress(parseInt(match[1], 10));\n } else if (hasStarted) {\n updateProgress(100);\n }\n });\n\n debug('[stdout]:', strings);\n });\n\n let stderrBuffer = '';\n childProcess.stderr.on('data', (data: Buffer) => {\n stderrBuffer += data.toString();\n });\n\n childProcess.on('close', (code) => {\n debug('[close]: ' + code);\n if (code === 0) {\n resolve();\n } else {\n const err = new Error(stderrBuffer || `Command failed with exit code ${code}`);\n (err as any).code = code;\n detach(err);\n }\n });\n\n const detach = async (err?: Error) => {\n off?.();\n if (childProcess) {\n return new Promise<void>((resolve) => {\n childProcess?.on('close', () => resolve());\n childProcess?.kill();\n reject(err ?? new CommandError('detached'));\n });\n }\n };\n\n const off = installExitHooks(() => detach());\n });\n}\n\nexport async function launchAppWithDeviceCtl(deviceId: string, bundleId: string) {\n await devicectlAsync([\n 'device',\n 'process',\n 'launch',\n '--terminate-existing',\n '--device',\n deviceId,\n bundleId,\n ]);\n}\n\n/** Find all error codes from the output log */\nfunction getDeviceCtlErrorCodes(log: string): string[] {\n return [...log.matchAll(/BSErrorCodeDescription\\s+=\\s+(.*)$/gim)].map(([_line, code]) => code);\n}\n\nlet hasEverBeenInstalled: boolean | undefined;\n\nexport function hasDevicectlEverBeenInstalled() {\n if (hasEverBeenInstalled) return hasEverBeenInstalled;\n // It doesn't appear possible for devicectl to ever be uninstalled. We can just check once and store this result forever\n // to prevent cold boots of devicectl from slowing down all invocations of `expo run ios`\n if (fs.existsSync(DEVICE_CTL_EXISTS_PATH)) {\n hasEverBeenInstalled = true;\n return true;\n }\n\n const isInstalled = isDevicectlInstalled();\n\n if (isInstalled) {\n fs.writeFileSync(DEVICE_CTL_EXISTS_PATH, '1');\n }\n hasEverBeenInstalled = isInstalled;\n return isInstalled;\n}\n\nfunction isDevicectlInstalled() {\n try {\n execSync('xcrun devicectl --version', { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Wraps the apple device method for installing and running an app,\n * adds indicator and retry loop for when the device is locked.\n */\nexport async function installAndLaunchAppAsync(props: {\n bundle: string;\n bundleIdentifier: string;\n udid: string;\n deviceName: string;\n}): Promise<void> {\n debug('Running on device:', props);\n const { bundle, bundleIdentifier, udid, deviceName } = props;\n let indicator: Ora | undefined;\n\n try {\n if (!indicator) {\n indicator = ora(`Connecting to: ${props.deviceName}`).start();\n }\n\n await installAppWithDeviceCtlAsync(\n udid,\n bundle,\n ({\n status,\n isComplete,\n progress,\n }: {\n status: string;\n isComplete: boolean;\n progress: number;\n }) => {\n if (!indicator) {\n indicator = ora(status).start();\n }\n indicator.text = `${chalk.bold(status)} ${progress}%`;\n if (isComplete) {\n indicator.succeed();\n }\n }\n );\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n throw error;\n }\n\n async function launchAppOptionally() {\n try {\n await launchAppWithDeviceCtl(udid, bundleIdentifier);\n } catch (error: any) {\n if (indicator) {\n indicator.fail();\n }\n if (error.code === 'APPLE_DEVICE_LOCKED') {\n // Get the app name from the binary path.\n const appName = path.basename(bundle).split('.')[0] ?? 'app';\n if (\n isInteractive() &&\n (await confirmAsync({\n message: `Cannot launch ${appName} because the device is locked. Unlock ${deviceName} to continue...`,\n initial: true,\n }))\n ) {\n return launchAppOptionally();\n }\n throw new CommandError(\n `Cannot launch ${appName} on ${deviceName} because the device is locked.`\n );\n }\n throw error;\n }\n }\n\n await launchAppOptionally();\n}\n"],"names":["devicectlAsync","getConnectedAppleDevicesAsync","hasDevicectlEverBeenInstalled","installAndLaunchAppAsync","launchAppWithDeviceCtl","launchBinaryOnMacAsync","DEVICE_CTL_EXISTS_PATH","path","join","getExpoHomeDirectory","debug","require","args","options","xcrunAsync","error","CommandError","errorCodes","getDeviceCtlErrorCodes","stderr","includes","tmpPath","createTempFilePath","devices","stdout","devicesJson","JsonFile","readAsync","info","jsonVersion","Log","warn","assertDevicesJson","result","results","assert","Array","isArray","JSON","stringify","bundleId","appBinaryPath","spawnAsync","code","message","installAppWithDeviceCtlAsync","uuid","bundleIdOrAppPath","onProgress","maxAttempts","attempt","installAppWithDeviceCtlInternalAsync","isTransientDisconnect","backoffDelay","Math","pow","Promise","resolve","setTimeout","reject","childProcess","spawn","currentProgress","hasStarted","updateProgress","progress","statusPrefix","isComplete","status","on","data","strings","toString","split","EOL","map","value","trim","forEach","str","match","parseInt","stderrBuffer","err","Error","detach","off","kill","installExitHooks","deviceId","log","matchAll","_line","hasEverBeenInstalled","fs","existsSync","isInstalled","isDevicectlInstalled","writeFileSync","execSync","stdio","props","bundle","bundleIdentifier","udid","deviceName","indicator","ora","start","text","chalk","bold","succeed","fail","launchAppOptionally","appName","basename","isInteractive","confirmAsync","initial"],"mappings":"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"}
|
|
@@ -32,14 +32,14 @@ function _interop_require_default(obj) {
|
|
|
32
32
|
default: obj
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
function createMetroMiddleware(metroConfig) {
|
|
35
|
+
function createMetroMiddleware(metroConfig, options) {
|
|
36
36
|
const messages = (0, _createMessageSocket.createMessagesSocket)({
|
|
37
37
|
logger: _log.Log
|
|
38
38
|
});
|
|
39
39
|
const events = (0, _createEventSocket.createEventsSocket)(messages);
|
|
40
40
|
const middleware = (0, _connect().default)().use(noCacheMiddleware).use(_compression.compression)// Support opening stack frames from clients directly in the editor
|
|
41
41
|
.use('/open-stack-frame', metroOpenStackFrameMiddleware)// Support status check to detect if the packager needs to be started from the native side
|
|
42
|
-
.use('/status', createMetroStatusMiddleware(metroConfig));
|
|
42
|
+
.use('/status', createMetroStatusMiddleware(metroConfig, options));
|
|
43
43
|
return {
|
|
44
44
|
middleware,
|
|
45
45
|
messagesSocket: messages,
|
|
@@ -70,9 +70,11 @@ const metroOpenStackFrameMiddleware = async (req, res, next)=>{
|
|
|
70
70
|
return res.end('Open stack frame requires the JSON stack frame as request body');
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
-
function createMetroStatusMiddleware(metroConfig) {
|
|
74
|
-
return (_req, res)=>{
|
|
73
|
+
function createMetroStatusMiddleware(metroConfig, options) {
|
|
74
|
+
return async (_req, res)=>{
|
|
75
75
|
res.setHeader('X-React-Native-Project-Root', encodeURI(metroConfig.projectRoot));
|
|
76
|
+
res.flushHeaders();
|
|
77
|
+
await options.getMetroBundler().ready();
|
|
76
78
|
res.end('packager-status:running');
|
|
77
79
|
};
|
|
78
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/start/server/metro/dev-server/createMetroMiddleware.ts"],"sourcesContent":["import type { MetroConfig } from '@expo/metro/metro';\nimport connect from 'connect';\nimport { Body } from 'fetch-nodeshim';\n\nimport { compression } from './compression';\nimport { createEventsSocket } from './createEventSocket';\nimport { createMessagesSocket } from './createMessageSocket';\nimport { Log } from '../../../../log';\nimport { openInEditorAsync } from '../../../../utils/editor';\n\nexport function createMetroMiddleware(metroConfig: Pick<MetroConfig, 'projectRoot'
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/start/server/metro/dev-server/createMetroMiddleware.ts"],"sourcesContent":["import type { MetroConfig } from '@expo/metro/metro';\nimport type MetroBundler from '@expo/metro/metro/Bundler';\nimport connect from 'connect';\nimport { Body } from 'fetch-nodeshim';\n\nimport { compression } from './compression';\nimport { createEventsSocket } from './createEventSocket';\nimport { createMessagesSocket } from './createMessageSocket';\nimport { Log } from '../../../../log';\nimport { openInEditorAsync } from '../../../../utils/editor';\n\ninterface MetroMiddlewareOptions {\n getMetroBundler(): MetroBundler;\n}\n\nexport function createMetroMiddleware(\n metroConfig: Pick<MetroConfig, 'projectRoot'>,\n options: MetroMiddlewareOptions\n) {\n const messages = createMessagesSocket({ logger: Log });\n const events = createEventsSocket(messages);\n\n const middleware = connect()\n .use(noCacheMiddleware)\n .use(compression)\n // Support opening stack frames from clients directly in the editor\n .use('/open-stack-frame', metroOpenStackFrameMiddleware)\n // Support status check to detect if the packager needs to be started from the native side\n .use('/status', createMetroStatusMiddleware(metroConfig, options));\n\n return {\n middleware,\n messagesSocket: messages,\n eventsSocket: events,\n websocketEndpoints: {\n [messages.endpoint]: messages.server,\n [events.endpoint]: events.server,\n },\n };\n}\n\nconst noCacheMiddleware: connect.NextHandleFunction = (req, res, next) => {\n res.setHeader('Surrogate-Control', 'no-store');\n res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');\n res.setHeader('Pragma', 'no-cache');\n res.setHeader('Expires', '0');\n next();\n};\n\nconst metroOpenStackFrameMiddleware: connect.NextHandleFunction = async (req, res, next) => {\n if (req.method !== 'POST') {\n return next();\n }\n try {\n const frame = await new Body(req).json();\n await openInEditorAsync(frame.file, frame.lineNumber);\n return res.end('OK');\n } catch {\n res.statusCode = 400;\n return res.end('Open stack frame requires the JSON stack frame as request body');\n }\n};\n\nfunction createMetroStatusMiddleware(\n metroConfig: Pick<MetroConfig, 'projectRoot'>,\n options: MetroMiddlewareOptions\n): connect.NextHandleFunction {\n return async (_req, res) => {\n res.setHeader('X-React-Native-Project-Root', encodeURI(metroConfig.projectRoot!));\n res.flushHeaders();\n await options.getMetroBundler().ready();\n res.end('packager-status:running');\n };\n}\n"],"names":["createMetroMiddleware","metroConfig","options","messages","createMessagesSocket","logger","Log","events","createEventsSocket","middleware","connect","use","noCacheMiddleware","compression","metroOpenStackFrameMiddleware","createMetroStatusMiddleware","messagesSocket","eventsSocket","websocketEndpoints","endpoint","server","req","res","next","setHeader","method","frame","Body","json","openInEditorAsync","file","lineNumber","end","statusCode","_req","encodeURI","projectRoot","flushHeaders","getMetroBundler","ready"],"mappings":";;;;+BAegBA;;;eAAAA;;;;gEAbI;;;;;;;yBACC;;;;;;6BAEO;mCACO;qCACE;qBACjB;wBACc;;;;;;AAM3B,SAASA,sBACdC,WAA6C,EAC7CC,OAA+B;IAE/B,MAAMC,WAAWC,IAAAA,yCAAoB,EAAC;QAAEC,QAAQC,QAAG;IAAC;IACpD,MAAMC,SAASC,IAAAA,qCAAkB,EAACL;IAElC,MAAMM,aAAaC,IAAAA,kBAAO,IACvBC,GAAG,CAACC,mBACJD,GAAG,CAACE,wBAAW,CAChB,mEAAmE;KAClEF,GAAG,CAAC,qBAAqBG,8BAC1B,0FAA0F;KACzFH,GAAG,CAAC,WAAWI,4BAA4Bd,aAAaC;IAE3D,OAAO;QACLO;QACAO,gBAAgBb;QAChBc,cAAcV;QACdW,oBAAoB;YAClB,CAACf,SAASgB,QAAQ,CAAC,EAAEhB,SAASiB,MAAM;YACpC,CAACb,OAAOY,QAAQ,CAAC,EAAEZ,OAAOa,MAAM;QAClC;IACF;AACF;AAEA,MAAMR,oBAAgD,CAACS,KAAKC,KAAKC;IAC/DD,IAAIE,SAAS,CAAC,qBAAqB;IACnCF,IAAIE,SAAS,CAAC,iBAAiB;IAC/BF,IAAIE,SAAS,CAAC,UAAU;IACxBF,IAAIE,SAAS,CAAC,WAAW;IACzBD;AACF;AAEA,MAAMT,gCAA4D,OAAOO,KAAKC,KAAKC;IACjF,IAAIF,IAAII,MAAM,KAAK,QAAQ;QACzB,OAAOF;IACT;IACA,IAAI;QACF,MAAMG,QAAQ,MAAM,IAAIC,CAAAA,gBAAG,MAAC,CAACN,KAAKO,IAAI;QACtC,MAAMC,IAAAA,yBAAiB,EAACH,MAAMI,IAAI,EAAEJ,MAAMK,UAAU;QACpD,OAAOT,IAAIU,GAAG,CAAC;IACjB,EAAE,OAAM;QACNV,IAAIW,UAAU,GAAG;QACjB,OAAOX,IAAIU,GAAG,CAAC;IACjB;AACF;AAEA,SAASjB,4BACPd,WAA6C,EAC7CC,OAA+B;IAE/B,OAAO,OAAOgC,MAAMZ;QAClBA,IAAIE,SAAS,CAAC,+BAA+BW,UAAUlC,YAAYmC,WAAW;QAC9Ed,IAAIe,YAAY;QAChB,MAAMnC,QAAQoC,eAAe,GAAGC,KAAK;QACrCjB,IAAIU,GAAG,CAAC;IACV;AACF"}
|
|
@@ -263,15 +263,16 @@ async function instantiateMetroAsync(metroBundler, options, { isExporting, exp =
|
|
|
263
263
|
}).exp }) {
|
|
264
264
|
var _metroConfig_server;
|
|
265
265
|
const projectRoot = metroBundler.projectRoot;
|
|
266
|
+
const getMetroBundler = ()=>metro.getBundler().getBundler();
|
|
266
267
|
const { config: metroConfig, setEventReporter, reporter } = await loadMetroConfigAsync(projectRoot, options, {
|
|
267
268
|
exp,
|
|
268
269
|
isExporting,
|
|
269
|
-
getMetroBundler
|
|
270
|
-
return metro.getBundler().getBundler();
|
|
271
|
-
}
|
|
270
|
+
getMetroBundler
|
|
272
271
|
});
|
|
273
272
|
// Create the core middleware stack for Metro, including websocket listeners
|
|
274
|
-
const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = (0, _createMetroMiddleware.createMetroMiddleware)(metroConfig
|
|
273
|
+
const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = (0, _createMetroMiddleware.createMetroMiddleware)(metroConfig, {
|
|
274
|
+
getMetroBundler
|
|
275
|
+
});
|
|
275
276
|
// Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)
|
|
276
277
|
const serverBaseUrl = metroBundler.getUrlCreator().constructUrl({
|
|
277
278
|
scheme: 'http',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { type ExpoConfig, getConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport type { Reporter } from '@expo/metro/metro';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ReadOnlyGraph } from '@expo/metro/metro/DeltaBundler';\nimport type { TransformOptions } from '@expo/metro/metro/DeltaBundler/Worker';\nimport MetroHmrServer, { Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport RevisionNotFoundError from '@expo/metro/metro/IncrementalBundler/RevisionNotFoundError';\nimport type MetroServer from '@expo/metro/metro/Server';\nimport formatBundlingError from '@expo/metro/metro/lib/formatBundlingError';\nimport { mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';\nimport { Terminal } from '@expo/metro/metro-core';\nimport { createStableModuleIdFactory, getDefaultConfig } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport http from 'http';\nimport path from 'path';\n\nimport { createDevToolsPluginWebsocketEndpoint } from './DevToolsPluginWebsocketEndpoint';\nimport { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { MetroTerminalReporter } from './MetroTerminalReporter';\nimport { attachAtlasAsync } from './debugging/attachAtlas';\nimport { createDebugMiddleware } from './debugging/createDebugMiddleware';\nimport { createMetroMiddleware } from './dev-server/createMetroMiddleware';\nimport { runServer, type SecureServerOptions } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\nimport { events, shouldReduceLogs } from '../../../events';\nimport { Log } from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { createCorsMiddleware } from '../middleware/CorsMiddleware';\nimport { createJsInspectorMiddleware } from '../middleware/inspector/createJsInspectorMiddleware';\nimport { prependMiddleware } from '../middleware/mutations';\nimport { getPlatformBundlers } from '../platformBundlers';\n\n// prettier-ignore\nexport const event = events('metro', (t) => [\n t.event<'config', {\n serverRoot: string;\n projectRoot: string;\n exporting: boolean;\n flags: {\n autolinkingModuleResolution: boolean;\n serverActions: boolean;\n serverComponents: boolean;\n reactCompiler: boolean;\n optimizeGraph?: boolean;\n treeshaking?: boolean;\n logbox?: boolean;\n };\n }>(),\n t.event<'instantiate', {\n atlas: boolean;\n workers: number | null;\n host: string | null;\n port: number | null;\n }>(),\n]);\n\n// NOTE(@kitten): We pass a custom createStableModuleIdFactory function into the Metro module ID factory sometimes\ninterface MetroServerWithModuleIdMod extends MetroServer {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\ninterface MetroHmrServerWithModuleIdMod extends MetroHmrServer<MetroHmrClient> {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\n\n// From expo/dev-server but with ability to use custom logger.\ntype MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\n// TODO(@kitten): We assign this here to run server-side code bundled by metro\n// It's not isolated into a worker thread yet\n// Check `metro-require/require.ts` for how this setting is used\ndeclare namespace globalThis {\n let __requireCycleIgnorePatterns: readonly RegExp[] | undefined;\n}\n\nfunction asWritable<T>(input: T): { -readonly [K in keyof T]: T[K] } {\n return input;\n}\n\n// Wrap terminal and polyfill console.log so we can log during bundling without breaking the indicator.\nclass LogRespectingTerminal extends Terminal {\n constructor(stream: import('node:net').Socket | import('node:stream').Writable) {\n super(stream, { ttyPrint: true });\n\n const sendLog = (...msg: any[]) => {\n if (!msg.length) {\n this.log('');\n } else {\n const [format, ...args] = msg;\n this.log(format, ...args);\n }\n // Flush the logs to the terminal immediately so logs at the end of the process are not lost.\n this.flush();\n };\n\n console.log = sendLog;\n console.info = sendLog;\n }\n}\n\n// Share one instance of Terminal for all instances of Metro.\nconst terminal = new LogRespectingTerminal(process.stdout);\n\ninterface LoadMetroConfigOptions {\n maxWorkers?: number;\n port?: number;\n reporter?: Reporter;\n resetCache?: boolean;\n}\n\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadMetroConfigOptions,\n {\n exp,\n isExporting,\n getMetroBundler,\n }: { exp: ExpoConfig; isExporting: boolean; getMetroBundler: () => Bundler }\n) {\n let reportEvent: ((event: any) => void) | undefined;\n\n // We're resolving a monorepo root, higher up than the `projectRoot`. If this\n // folder is different (presumably a parent) we're in a monorepo\n const serverRoot = getMetroServerRoot(projectRoot);\n const isWorkspace = serverRoot !== projectRoot;\n\n // Autolinking Module Resolution will be enabled by default when we're in a monorepo\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? isWorkspace;\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n const serverComponentsEnabled = !!exp.experiments?.reactServerComponentRoutes;\n if (serverActionsEnabled) {\n process.env.EXPO_UNSTABLE_SERVER_FUNCTIONS = '1';\n }\n\n // NOTE: Enable all the experimental Metro flags when RSC is enabled.\n if (serverComponentsEnabled || serverActionsEnabled) {\n process.env.EXPO_USE_METRO_REQUIRE = '1';\n }\n\n if (exp.experiments?.reactCanary) {\n Log.warn(`React 19 is enabled by default. Remove unused experiments.reactCanary flag.`);\n }\n\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n const configPath = env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined;\n const resolvedConfig = await resolveConfig(configPath, projectRoot);\n const defaultConfig = getDefaultConfig(projectRoot);\n\n let config: ConfigT = resolvedConfig.isEmpty\n ? defaultConfig\n : await mergeConfig(defaultConfig, resolvedConfig.config);\n\n // Set the watchfolders to include the projectRoot, as Metro assumes this\n // Force-override the reporter\n config = {\n ...config,\n\n // See: `overrideConfigWithArguments` https://github.com/facebook/metro/blob/5059e26/packages/metro-config/src/loadConfig.js#L274-L339\n // Compare to `LoadOptions` type (disregard `reporter` as we don't expose this)\n resetCache: !!options.resetCache,\n maxWorkers: options.maxWorkers ?? config.maxWorkers,\n server: {\n ...config.server,\n port: options.port ?? config.server.port,\n },\n\n watchFolders: !config.watchFolders.includes(config.projectRoot)\n ? [config.projectRoot, ...config.watchFolders]\n : config.watchFolders,\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // NOTE(@kitten): `useWatchman` is currently enabled by default, but it also disables `forceNodeFilesystemAPI`.\n // If we instead set it to the special value `null`, it gets enables but also bypasses the \"native find\" codepath,\n // which is slower than just using the Node filesystem API\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro-file-map/src/index.js#L326\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro/src/node-haste/DependencyGraph/createFileMap.js#L109\n if (config.resolver.useWatchman === true) {\n asWritable(config.resolver).useWatchman = null as any;\n }\n\n globalThis.__requireCycleIgnorePatterns = config.resolver?.requireCycleIgnorePatterns;\n\n if (isExporting) {\n // This token will be used in the asset plugin to ensure the path is correct for writing locally.\n asWritable(config.transformer).publicPath = `/assets?export_path=${\n (exp.experiments?.baseUrl ?? '') + '/assets'\n }`;\n } else {\n asWritable(config.transformer).publicPath = '/assets/?unstable_path=.';\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n const reduceLogs = shouldReduceLogs();\n\n const reactCompilerEnabled = !!exp.experiments?.reactCompiler;\n if (!reduceLogs && reactCompilerEnabled) {\n Log.log(chalk.gray`React Compiler enabled`);\n }\n\n if (!reduceLogs && autolinkingModuleResolutionEnabled) {\n Log.log(chalk.gray`Expo Autolinking module resolution enabled`);\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING && !env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n throw new CommandError(\n 'EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.'\n );\n }\n\n if (!reduceLogs && env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_LOG_BOX) {\n Log.warn(`Experimental Expo LogBox is enabled.`);\n }\n\n if (!reduceLogs && serverActionsEnabled) {\n Log.warn(\n `React Server Functions (beta) are enabled. Route rendering mode: ${exp.experiments?.reactServerComponentRoutes ? 'server' : 'client'}`\n );\n }\n\n config = await withMetroMultiPlatformAsync(projectRoot, {\n config,\n exp,\n platformBundlers,\n isTsconfigPathsEnabled: exp.experiments?.tsconfigPaths ?? true,\n isAutolinkingResolverEnabled: autolinkingModuleResolutionEnabled,\n isExporting,\n isNamedRequiresEnabled: env.EXPO_USE_METRO_REQUIRE,\n isReactServerComponentsEnabled: serverComponentsEnabled,\n getMetroBundler,\n });\n\n event('config', {\n serverRoot: event.path(serverRoot),\n projectRoot: event.path(projectRoot),\n exporting: isExporting,\n flags: {\n autolinkingModuleResolution: autolinkingModuleResolutionEnabled,\n serverActions: serverActionsEnabled,\n serverComponents: serverComponentsEnabled,\n reactCompiler: reactCompilerEnabled,\n optimizeGraph: env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH,\n treeshaking: env.EXPO_UNSTABLE_TREE_SHAKING,\n logbox: env.EXPO_UNSTABLE_LOG_BOX,\n },\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\ninterface InstantiateMetroConfigOptions extends LoadMetroConfigOptions {\n host?: string;\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: InstantiateMetroConfigOptions,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: MetroServer;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n server: http.Server;\n middleware: any;\n messageSocket: MessageSocket;\n}> {\n const projectRoot = metroBundler.projectRoot;\n\n const {\n config: metroConfig,\n setEventReporter,\n reporter,\n } = await loadMetroConfigAsync(projectRoot, options, {\n exp,\n isExporting,\n getMetroBundler() {\n return metro.getBundler().getBundler();\n },\n });\n\n // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } =\n createMetroMiddleware(metroConfig);\n\n // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)\n const serverBaseUrl = metroBundler\n .getUrlCreator()\n .constructUrl({ scheme: 'http', hostType: 'localhost' });\n\n if (!isExporting) {\n // Enable correct CORS headers for Expo Router features\n prependMiddleware(middleware, createCorsMiddleware(exp));\n\n // Enable debug middleware for CDP-related debugging\n const { debugMiddleware, debugWebsocketEndpoints } = createDebugMiddleware({\n serverBaseUrl,\n reporter,\n });\n Object.assign(websocketEndpoints, debugWebsocketEndpoints);\n middleware.use(debugMiddleware);\n middleware.use('/_expo/debugger', createJsInspectorMiddleware());\n\n // TODO(cedric): `enhanceMiddleware` is deprecated, but is currently used to unify the middleware stacks\n // See: https://github.com/facebook/metro/commit/22e85fde85ec454792a1b70eba4253747a2587a9\n // See: https://github.com/facebook/metro/commit/d0d554381f119bb80ab09dbd6a1d310b54737e52\n const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware;\n asWritable(metroConfig.server).enhanceMiddleware = (\n metroMiddleware: any,\n server: MetroServer\n ) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\n\n const devtoolsWebsocketEndpoints = createDevToolsPluginWebsocketEndpoint();\n Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);\n }\n\n // Attach Expo Atlas if enabled\n await attachAtlasAsync({\n isExporting,\n exp,\n projectRoot,\n middleware,\n metroConfig,\n // NOTE(cedric): reset the Atlas file once, and reuse it for static exports\n resetAtlasFile: isExporting,\n });\n\n // Support HTTPS based on the metro's tls server config\n // TODO(@kitten): Remove cast once `@expo/metro` is updated to a Metro version that supports the tls config\n const tls = (metroConfig.server as typeof metroConfig.server & { tls?: SecureServerOptions })\n ?.tls;\n const secureServerOptions = tls\n ? {\n key: tls.key,\n cert: tls.cert,\n ca: tls.ca,\n requestCert: tls.requestCert,\n }\n : undefined;\n\n const { address, server, hmrServer, metro } = await runServer(\n metroBundler,\n metroConfig,\n {\n host: options.host,\n websocketEndpoints,\n watch: !isExporting && isWatchEnabled(),\n secureServerOptions,\n },\n {\n mockServer: isExporting,\n }\n );\n\n event('instantiate', {\n atlas: env.EXPO_ATLAS,\n workers: metroConfig.maxWorkers ?? null,\n host: address?.address ?? null,\n port: address?.port ?? null,\n });\n\n // Patch transform file to remove inconvenient customTransformOptions which are only used in single well-known files.\n const originalTransformFile = metro\n .getBundler()\n .getBundler()\n .transformFile.bind(metro.getBundler().getBundler());\n\n metro.getBundler().getBundler().transformFile = async function (\n filePath: string,\n transformOptions: TransformOptions,\n fileBuffer?: Buffer\n ) {\n return originalTransformFile(\n filePath,\n pruneCustomTransformOptions(\n projectRoot,\n filePath,\n // Clone the options so we don't mutate the original.\n {\n ...transformOptions,\n customTransformOptions: {\n __proto__: null,\n ...transformOptions.customTransformOptions,\n },\n }\n ),\n fileBuffer\n );\n };\n\n setEventReporter(eventsSocket.reportMetroEvent);\n\n // This function ensures that modules in source maps are sorted in the same\n // order as in a plain JS bundle.\n metro._getSortedModules = function (this: MetroServerWithModuleIdMod, graph: ReadOnlyGraph) {\n const modules = [...graph.dependencies.values()];\n\n const ctx = {\n // TODO(@kitten): Increase type-safety here\n platform: graph.transformOptions.platform!,\n environment: graph.transformOptions.customTransformOptions?.environment,\n };\n // Assign IDs to modules in a consistent order\n for (const module of modules) {\n this._createModuleId(module.path, ctx);\n }\n // Sort by IDs\n return modules.sort(\n (a, b) => this._createModuleId(a.path, ctx) - this._createModuleId(b.path, ctx)\n );\n };\n\n if (hmrServer) {\n let hmrJSBundle:\n | typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default\n | typeof import('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // TODO: Add fallback for monorepo tests up until the fork is merged.\n Log.warn('Failed to load HMR serializer from @expo/metro-config, using fallback version.');\n hmrJSBundle = require('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle');\n }\n\n // Patch HMR Server to send more info to the `_createModuleId` function for deterministic module IDs and add support for serializing HMR updates the same as all other bundles.\n hmrServer._prepareMessage = async function (\n this: MetroHmrServerWithModuleIdMod,\n group,\n options,\n changeEvent\n ) {\n // Fork of https://github.com/facebook/metro/blob/3b3e0aaf725cfa6907bf2c8b5fbc0da352d29efe/packages/metro/src/HmrServer.js#L327-L393\n // with patch for `_createModuleId`.\n const logger = !options.isInitialUpdate ? changeEvent?.logger : null;\n try {\n const revPromise = this._bundler.getRevision(group.revisionId);\n if (!revPromise) {\n return {\n type: 'error',\n body: formatBundlingError(new RevisionNotFoundError(group.revisionId)),\n };\n }\n logger?.point('updateGraph_start');\n const { revision, delta } = await this._bundler.updateGraph(await revPromise, false);\n logger?.point('updateGraph_end');\n this._clientGroups.delete(group.revisionId);\n group.revisionId = revision.id;\n for (const client of group.clients) {\n client.revisionIds = client.revisionIds.filter(\n (revisionId) => revisionId !== group.revisionId\n );\n client.revisionIds.push(revision.id);\n }\n this._clientGroups.set(group.revisionId, group);\n logger?.point('serialize_start');\n // NOTE(EvanBacon): This is the patch\n const moduleIdContext = {\n // TODO(@kitten): Increase type-safety here\n platform: revision.graph.transformOptions.platform!,\n environment: revision.graph.transformOptions.customTransformOptions?.environment,\n };\n const hmrUpdate = hmrJSBundle(delta, revision.graph, {\n clientUrl: group.clientUrl,\n // NOTE(EvanBacon): This is also the patch\n createModuleId: (moduleId: string) => {\n return this._createModuleId(moduleId, moduleIdContext);\n },\n includeAsyncPaths: group.graphOptions.lazy,\n projectRoot: this._config.projectRoot,\n serverRoot: this._config.server.unstable_serverRoot ?? this._config.projectRoot,\n });\n logger?.point('serialize_end');\n return {\n type: 'update',\n body: {\n revisionId: revision.id,\n isInitialUpdate: options.isInitialUpdate,\n ...hmrUpdate,\n },\n };\n } catch (error: any) {\n const formattedError = formatBundlingError(error);\n this._config.reporter.update({\n type: 'bundling_error',\n error,\n });\n return {\n type: 'error',\n body: formattedError,\n };\n }\n };\n }\n\n return {\n metro,\n hmrServer,\n server,\n middleware,\n messageSocket: messagesSocket,\n };\n}\n\n// TODO: Fork the entire transform function so we can simply regex the file contents for keywords instead.\nfunction pruneCustomTransformOptions(\n projectRoot: string,\n filePath: string,\n transformOptions: TransformOptions\n): TransformOptions {\n // Normalize the filepath for cross platform checking.\n filePath = filePath.split(path.sep).join('/');\n\n if (\n transformOptions.customTransformOptions?.dom &&\n // The only generated file that needs the dom root is `expo/dom/entry.js`\n !filePath.match(/expo\\/dom\\/entry\\.js$/)\n ) {\n // Clear the dom root option if we aren't transforming the magic entry file, this ensures\n // that cached artifacts from other DOM component bundles can be reused.\n transformOptions.customTransformOptions.dom = 'true';\n }\n\n const routerRoot = transformOptions.customTransformOptions?.routerRoot;\n if (typeof routerRoot === 'string') {\n const isRouterEntry = /\\/expo-router\\/_ctx/.test(filePath);\n // The router root is used all over expo-router (`process.env.EXPO_ROUTER_ABS_APP_ROOT`, `process.env.EXPO_ROUTER_APP_ROOT`) so we'll just ignore the entire package.\n const isRouterModule = /\\/expo-router\\/build\\//.test(filePath);\n // Any page/router inside the expo-router app folder may access the `routerRoot` option to determine whether it's in the app folder\n const resolvedRouterRoot = path.resolve(projectRoot, routerRoot).split(path.sep).join('/');\n const isRouterRoute = path.isAbsolute(filePath) && filePath.startsWith(resolvedRouterRoot);\n\n // In any other file than the above, we enforce that we mustn't use `routerRoot`, and set it to an arbitrary value here (the default)\n // to ensure that the cache never invalidates when this value is changed\n if (!isRouterEntry && !isRouterModule && !isRouterRoute) {\n transformOptions.customTransformOptions!.routerRoot = 'app';\n }\n }\n\n if (\n transformOptions.customTransformOptions?.asyncRoutes &&\n // The async routes settings are also used in `expo-router/_ctx.ios.js` (and other platform variants) via `process.env.EXPO_ROUTER_IMPORT_MODE`\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n delete transformOptions.customTransformOptions.asyncRoutes;\n }\n\n if (\n transformOptions.customTransformOptions?.clientBoundaries &&\n // The client boundaries are only used in `expo/virtual/rsc.js` for production RSC exports.\n !filePath.match(/\\/expo\\/virtual\\/rsc\\.js$/)\n ) {\n delete transformOptions.customTransformOptions.clientBoundaries;\n }\n\n return transformOptions;\n}\n\n/**\n * Simplify and communicate if Metro is running without watching file updates,.\n * Exposed for testing.\n */\nexport function isWatchEnabled() {\n if (env.CI) {\n Log.log(\n chalk`Metro is running in CI mode, reloads are disabled. Remove {bold CI=true} to enable watch mode.`\n );\n }\n\n return !env.CI;\n}\n"],"names":["event","instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","events","t","asWritable","input","LogRespectingTerminal","Terminal","constructor","stream","ttyPrint","sendLog","msg","length","log","format","args","flush","console","info","terminal","process","stdout","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","serverRoot","getMetroServerRoot","isWorkspace","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","serverActionsEnabled","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","serverComponentsEnabled","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","warn","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","resolver","useWatchman","globalThis","__requireCycleIgnorePatterns","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reduceLogs","shouldReduceLogs","reactCompilerEnabled","reactCompiler","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","EXPO_UNSTABLE_LOG_BOX","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isNamedRequiresEnabled","isReactServerComponentsEnabled","path","exporting","flags","serverActions","serverComponents","optimizeGraph","treeshaking","logbox","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","metroConfig","metro","getBundler","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","serverBaseUrl","getUrlCreator","constructUrl","scheme","hostType","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","enhanceMiddleware","metroMiddleware","devtoolsWebsocketEndpoints","createDevToolsPluginWebsocketEndpoint","attachAtlasAsync","resetAtlasFile","tls","secureServerOptions","key","cert","ca","requestCert","address","hmrServer","runServer","host","watch","mockServer","atlas","EXPO_ATLAS","workers","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","platform","environment","module","_createModuleId","sort","a","b","hmrJSBundle","require","default","_prepareMessage","group","changeEvent","isInitialUpdate","revision","revPromise","_bundler","getRevision","revisionId","type","body","formatBundlingError","RevisionNotFoundError","point","delta","updateGraph","_clientGroups","delete","id","client","clients","revisionIds","filter","push","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","error","formattedError","messageSocket","split","sep","join","dom","match","routerRoot","isRouterEntry","test","isRouterModule","resolvedRouterRoot","resolve","isRouterRoute","isAbsolute","startsWith","asyncRoutes","clientBoundaries","CI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/instantiateMetro.ts"],"sourcesContent":["import { type ExpoConfig, getConfig } from '@expo/config';\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport type { Reporter } from '@expo/metro/metro';\nimport type Bundler from '@expo/metro/metro/Bundler';\nimport type { ReadOnlyGraph } from '@expo/metro/metro/DeltaBundler';\nimport type { TransformOptions } from '@expo/metro/metro/DeltaBundler/Worker';\nimport MetroHmrServer, { Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport RevisionNotFoundError from '@expo/metro/metro/IncrementalBundler/RevisionNotFoundError';\nimport type MetroServer from '@expo/metro/metro/Server';\nimport formatBundlingError from '@expo/metro/metro/lib/formatBundlingError';\nimport { mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';\nimport { Terminal } from '@expo/metro/metro-core';\nimport { createStableModuleIdFactory, getDefaultConfig } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport http from 'http';\nimport path from 'path';\n\nimport { createDevToolsPluginWebsocketEndpoint } from './DevToolsPluginWebsocketEndpoint';\nimport { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { MetroTerminalReporter } from './MetroTerminalReporter';\nimport { attachAtlasAsync } from './debugging/attachAtlas';\nimport { createDebugMiddleware } from './debugging/createDebugMiddleware';\nimport { createMetroMiddleware } from './dev-server/createMetroMiddleware';\nimport { runServer, type SecureServerOptions } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\nimport { events, shouldReduceLogs } from '../../../events';\nimport { Log } from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { createCorsMiddleware } from '../middleware/CorsMiddleware';\nimport { createJsInspectorMiddleware } from '../middleware/inspector/createJsInspectorMiddleware';\nimport { prependMiddleware } from '../middleware/mutations';\nimport { getPlatformBundlers } from '../platformBundlers';\n\n// prettier-ignore\nexport const event = events('metro', (t) => [\n t.event<'config', {\n serverRoot: string;\n projectRoot: string;\n exporting: boolean;\n flags: {\n autolinkingModuleResolution: boolean;\n serverActions: boolean;\n serverComponents: boolean;\n reactCompiler: boolean;\n optimizeGraph?: boolean;\n treeshaking?: boolean;\n logbox?: boolean;\n };\n }>(),\n t.event<'instantiate', {\n atlas: boolean;\n workers: number | null;\n host: string | null;\n port: number | null;\n }>(),\n]);\n\n// NOTE(@kitten): We pass a custom createStableModuleIdFactory function into the Metro module ID factory sometimes\ninterface MetroServerWithModuleIdMod extends MetroServer {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\ninterface MetroHmrServerWithModuleIdMod extends MetroHmrServer<MetroHmrClient> {\n _createModuleId: ReturnType<typeof createStableModuleIdFactory> & ((path: string) => number);\n}\n\n// From expo/dev-server but with ability to use custom logger.\ntype MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\n// TODO(@kitten): We assign this here to run server-side code bundled by metro\n// It's not isolated into a worker thread yet\n// Check `metro-require/require.ts` for how this setting is used\ndeclare namespace globalThis {\n let __requireCycleIgnorePatterns: readonly RegExp[] | undefined;\n}\n\nfunction asWritable<T>(input: T): { -readonly [K in keyof T]: T[K] } {\n return input;\n}\n\n// Wrap terminal and polyfill console.log so we can log during bundling without breaking the indicator.\nclass LogRespectingTerminal extends Terminal {\n constructor(stream: import('node:net').Socket | import('node:stream').Writable) {\n super(stream, { ttyPrint: true });\n\n const sendLog = (...msg: any[]) => {\n if (!msg.length) {\n this.log('');\n } else {\n const [format, ...args] = msg;\n this.log(format, ...args);\n }\n // Flush the logs to the terminal immediately so logs at the end of the process are not lost.\n this.flush();\n };\n\n console.log = sendLog;\n console.info = sendLog;\n }\n}\n\n// Share one instance of Terminal for all instances of Metro.\nconst terminal = new LogRespectingTerminal(process.stdout);\n\ninterface LoadMetroConfigOptions {\n maxWorkers?: number;\n port?: number;\n reporter?: Reporter;\n resetCache?: boolean;\n}\n\nexport async function loadMetroConfigAsync(\n projectRoot: string,\n options: LoadMetroConfigOptions,\n {\n exp,\n isExporting,\n getMetroBundler,\n }: { exp: ExpoConfig; isExporting: boolean; getMetroBundler: () => Bundler }\n) {\n let reportEvent: ((event: any) => void) | undefined;\n\n // We're resolving a monorepo root, higher up than the `projectRoot`. If this\n // folder is different (presumably a parent) we're in a monorepo\n const serverRoot = getMetroServerRoot(projectRoot);\n const isWorkspace = serverRoot !== projectRoot;\n\n // Autolinking Module Resolution will be enabled by default when we're in a monorepo\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? isWorkspace;\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n const serverComponentsEnabled = !!exp.experiments?.reactServerComponentRoutes;\n if (serverActionsEnabled) {\n process.env.EXPO_UNSTABLE_SERVER_FUNCTIONS = '1';\n }\n\n // NOTE: Enable all the experimental Metro flags when RSC is enabled.\n if (serverComponentsEnabled || serverActionsEnabled) {\n process.env.EXPO_USE_METRO_REQUIRE = '1';\n }\n\n if (exp.experiments?.reactCanary) {\n Log.warn(`React 19 is enabled by default. Remove unused experiments.reactCanary flag.`);\n }\n\n const terminalReporter = new MetroTerminalReporter(serverRoot, terminal);\n\n // NOTE: Allow external tools to override the metro config. This is considered internal and unstable\n const configPath = env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined;\n const resolvedConfig = await resolveConfig(configPath, projectRoot);\n const defaultConfig = getDefaultConfig(projectRoot);\n\n let config: ConfigT = resolvedConfig.isEmpty\n ? defaultConfig\n : await mergeConfig(defaultConfig, resolvedConfig.config);\n\n // Set the watchfolders to include the projectRoot, as Metro assumes this\n // Force-override the reporter\n config = {\n ...config,\n\n // See: `overrideConfigWithArguments` https://github.com/facebook/metro/blob/5059e26/packages/metro-config/src/loadConfig.js#L274-L339\n // Compare to `LoadOptions` type (disregard `reporter` as we don't expose this)\n resetCache: !!options.resetCache,\n maxWorkers: options.maxWorkers ?? config.maxWorkers,\n server: {\n ...config.server,\n port: options.port ?? config.server.port,\n },\n\n watchFolders: !config.watchFolders.includes(config.projectRoot)\n ? [config.projectRoot, ...config.watchFolders]\n : config.watchFolders,\n reporter: {\n update(event) {\n terminalReporter.update(event);\n if (reportEvent) {\n reportEvent(event);\n }\n },\n },\n };\n\n // NOTE(@kitten): `useWatchman` is currently enabled by default, but it also disables `forceNodeFilesystemAPI`.\n // If we instead set it to the special value `null`, it gets enables but also bypasses the \"native find\" codepath,\n // which is slower than just using the Node filesystem API\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro-file-map/src/index.js#L326\n // See: https://github.com/facebook/metro/blob/b9c243f/packages/metro/src/node-haste/DependencyGraph/createFileMap.js#L109\n if (config.resolver.useWatchman === true) {\n asWritable(config.resolver).useWatchman = null as any;\n }\n\n globalThis.__requireCycleIgnorePatterns = config.resolver?.requireCycleIgnorePatterns;\n\n if (isExporting) {\n // This token will be used in the asset plugin to ensure the path is correct for writing locally.\n asWritable(config.transformer).publicPath = `/assets?export_path=${\n (exp.experiments?.baseUrl ?? '') + '/assets'\n }`;\n } else {\n asWritable(config.transformer).publicPath = '/assets/?unstable_path=.';\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n const reduceLogs = shouldReduceLogs();\n\n const reactCompilerEnabled = !!exp.experiments?.reactCompiler;\n if (!reduceLogs && reactCompilerEnabled) {\n Log.log(chalk.gray`React Compiler enabled`);\n }\n\n if (!reduceLogs && autolinkingModuleResolutionEnabled) {\n Log.log(chalk.gray`Expo Autolinking module resolution enabled`);\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING && !env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n throw new CommandError(\n 'EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.'\n );\n }\n\n if (!reduceLogs && env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (!reduceLogs && env.EXPO_UNSTABLE_LOG_BOX) {\n Log.warn(`Experimental Expo LogBox is enabled.`);\n }\n\n if (!reduceLogs && serverActionsEnabled) {\n Log.warn(\n `React Server Functions (beta) are enabled. Route rendering mode: ${exp.experiments?.reactServerComponentRoutes ? 'server' : 'client'}`\n );\n }\n\n config = await withMetroMultiPlatformAsync(projectRoot, {\n config,\n exp,\n platformBundlers,\n isTsconfigPathsEnabled: exp.experiments?.tsconfigPaths ?? true,\n isAutolinkingResolverEnabled: autolinkingModuleResolutionEnabled,\n isExporting,\n isNamedRequiresEnabled: env.EXPO_USE_METRO_REQUIRE,\n isReactServerComponentsEnabled: serverComponentsEnabled,\n getMetroBundler,\n });\n\n event('config', {\n serverRoot: event.path(serverRoot),\n projectRoot: event.path(projectRoot),\n exporting: isExporting,\n flags: {\n autolinkingModuleResolution: autolinkingModuleResolutionEnabled,\n serverActions: serverActionsEnabled,\n serverComponents: serverComponentsEnabled,\n reactCompiler: reactCompilerEnabled,\n optimizeGraph: env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH,\n treeshaking: env.EXPO_UNSTABLE_TREE_SHAKING,\n logbox: env.EXPO_UNSTABLE_LOG_BOX,\n },\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\ninterface InstantiateMetroConfigOptions extends LoadMetroConfigOptions {\n host?: string;\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: InstantiateMetroConfigOptions,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: MetroServer;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n server: http.Server;\n middleware: any;\n messageSocket: MessageSocket;\n}> {\n const projectRoot = metroBundler.projectRoot;\n const getMetroBundler = () => metro.getBundler().getBundler();\n\n const {\n config: metroConfig,\n setEventReporter,\n reporter,\n } = await loadMetroConfigAsync(projectRoot, options, {\n exp,\n isExporting,\n getMetroBundler,\n });\n\n // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = createMetroMiddleware(\n metroConfig,\n { getMetroBundler }\n );\n\n // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)\n const serverBaseUrl = metroBundler\n .getUrlCreator()\n .constructUrl({ scheme: 'http', hostType: 'localhost' });\n\n if (!isExporting) {\n // Enable correct CORS headers for Expo Router features\n prependMiddleware(middleware, createCorsMiddleware(exp));\n\n // Enable debug middleware for CDP-related debugging\n const { debugMiddleware, debugWebsocketEndpoints } = createDebugMiddleware({\n serverBaseUrl,\n reporter,\n });\n Object.assign(websocketEndpoints, debugWebsocketEndpoints);\n middleware.use(debugMiddleware);\n middleware.use('/_expo/debugger', createJsInspectorMiddleware());\n\n // TODO(cedric): `enhanceMiddleware` is deprecated, but is currently used to unify the middleware stacks\n // See: https://github.com/facebook/metro/commit/22e85fde85ec454792a1b70eba4253747a2587a9\n // See: https://github.com/facebook/metro/commit/d0d554381f119bb80ab09dbd6a1d310b54737e52\n const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware;\n asWritable(metroConfig.server).enhanceMiddleware = (\n metroMiddleware: any,\n server: MetroServer\n ) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\n\n const devtoolsWebsocketEndpoints = createDevToolsPluginWebsocketEndpoint();\n Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);\n }\n\n // Attach Expo Atlas if enabled\n await attachAtlasAsync({\n isExporting,\n exp,\n projectRoot,\n middleware,\n metroConfig,\n // NOTE(cedric): reset the Atlas file once, and reuse it for static exports\n resetAtlasFile: isExporting,\n });\n\n // Support HTTPS based on the metro's tls server config\n // TODO(@kitten): Remove cast once `@expo/metro` is updated to a Metro version that supports the tls config\n const tls = (metroConfig.server as typeof metroConfig.server & { tls?: SecureServerOptions })\n ?.tls;\n const secureServerOptions = tls\n ? {\n key: tls.key,\n cert: tls.cert,\n ca: tls.ca,\n requestCert: tls.requestCert,\n }\n : undefined;\n\n const { address, server, hmrServer, metro } = await runServer(\n metroBundler,\n metroConfig,\n {\n host: options.host,\n websocketEndpoints,\n watch: !isExporting && isWatchEnabled(),\n secureServerOptions,\n },\n {\n mockServer: isExporting,\n }\n );\n\n event('instantiate', {\n atlas: env.EXPO_ATLAS,\n workers: metroConfig.maxWorkers ?? null,\n host: address?.address ?? null,\n port: address?.port ?? null,\n });\n\n // Patch transform file to remove inconvenient customTransformOptions which are only used in single well-known files.\n const originalTransformFile = metro\n .getBundler()\n .getBundler()\n .transformFile.bind(metro.getBundler().getBundler());\n\n metro.getBundler().getBundler().transformFile = async function (\n filePath: string,\n transformOptions: TransformOptions,\n fileBuffer?: Buffer\n ) {\n return originalTransformFile(\n filePath,\n pruneCustomTransformOptions(\n projectRoot,\n filePath,\n // Clone the options so we don't mutate the original.\n {\n ...transformOptions,\n customTransformOptions: {\n __proto__: null,\n ...transformOptions.customTransformOptions,\n },\n }\n ),\n fileBuffer\n );\n };\n\n setEventReporter(eventsSocket.reportMetroEvent);\n\n // This function ensures that modules in source maps are sorted in the same\n // order as in a plain JS bundle.\n metro._getSortedModules = function (this: MetroServerWithModuleIdMod, graph: ReadOnlyGraph) {\n const modules = [...graph.dependencies.values()];\n\n const ctx = {\n // TODO(@kitten): Increase type-safety here\n platform: graph.transformOptions.platform!,\n environment: graph.transformOptions.customTransformOptions?.environment,\n };\n // Assign IDs to modules in a consistent order\n for (const module of modules) {\n this._createModuleId(module.path, ctx);\n }\n // Sort by IDs\n return modules.sort(\n (a, b) => this._createModuleId(a.path, ctx) - this._createModuleId(b.path, ctx)\n );\n };\n\n if (hmrServer) {\n let hmrJSBundle:\n | typeof import('@expo/metro-config/build/serializer/fork/hmrJSBundle').default\n | typeof import('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle').default;\n\n try {\n hmrJSBundle = require('@expo/metro-config/build/serializer/fork/hmrJSBundle').default;\n } catch {\n // TODO: Add fallback for monorepo tests up until the fork is merged.\n Log.warn('Failed to load HMR serializer from @expo/metro-config, using fallback version.');\n hmrJSBundle = require('@expo/metro/metro/DeltaBundler/Serializers/hmrJSBundle');\n }\n\n // Patch HMR Server to send more info to the `_createModuleId` function for deterministic module IDs and add support for serializing HMR updates the same as all other bundles.\n hmrServer._prepareMessage = async function (\n this: MetroHmrServerWithModuleIdMod,\n group,\n options,\n changeEvent\n ) {\n // Fork of https://github.com/facebook/metro/blob/3b3e0aaf725cfa6907bf2c8b5fbc0da352d29efe/packages/metro/src/HmrServer.js#L327-L393\n // with patch for `_createModuleId`.\n const logger = !options.isInitialUpdate ? changeEvent?.logger : null;\n try {\n const revPromise = this._bundler.getRevision(group.revisionId);\n if (!revPromise) {\n return {\n type: 'error',\n body: formatBundlingError(new RevisionNotFoundError(group.revisionId)),\n };\n }\n logger?.point('updateGraph_start');\n const { revision, delta } = await this._bundler.updateGraph(await revPromise, false);\n logger?.point('updateGraph_end');\n this._clientGroups.delete(group.revisionId);\n group.revisionId = revision.id;\n for (const client of group.clients) {\n client.revisionIds = client.revisionIds.filter(\n (revisionId) => revisionId !== group.revisionId\n );\n client.revisionIds.push(revision.id);\n }\n this._clientGroups.set(group.revisionId, group);\n logger?.point('serialize_start');\n // NOTE(EvanBacon): This is the patch\n const moduleIdContext = {\n // TODO(@kitten): Increase type-safety here\n platform: revision.graph.transformOptions.platform!,\n environment: revision.graph.transformOptions.customTransformOptions?.environment,\n };\n const hmrUpdate = hmrJSBundle(delta, revision.graph, {\n clientUrl: group.clientUrl,\n // NOTE(EvanBacon): This is also the patch\n createModuleId: (moduleId: string) => {\n return this._createModuleId(moduleId, moduleIdContext);\n },\n includeAsyncPaths: group.graphOptions.lazy,\n projectRoot: this._config.projectRoot,\n serverRoot: this._config.server.unstable_serverRoot ?? this._config.projectRoot,\n });\n logger?.point('serialize_end');\n return {\n type: 'update',\n body: {\n revisionId: revision.id,\n isInitialUpdate: options.isInitialUpdate,\n ...hmrUpdate,\n },\n };\n } catch (error: any) {\n const formattedError = formatBundlingError(error);\n this._config.reporter.update({\n type: 'bundling_error',\n error,\n });\n return {\n type: 'error',\n body: formattedError,\n };\n }\n };\n }\n\n return {\n metro,\n hmrServer,\n server,\n middleware,\n messageSocket: messagesSocket,\n };\n}\n\n// TODO: Fork the entire transform function so we can simply regex the file contents for keywords instead.\nfunction pruneCustomTransformOptions(\n projectRoot: string,\n filePath: string,\n transformOptions: TransformOptions\n): TransformOptions {\n // Normalize the filepath for cross platform checking.\n filePath = filePath.split(path.sep).join('/');\n\n if (\n transformOptions.customTransformOptions?.dom &&\n // The only generated file that needs the dom root is `expo/dom/entry.js`\n !filePath.match(/expo\\/dom\\/entry\\.js$/)\n ) {\n // Clear the dom root option if we aren't transforming the magic entry file, this ensures\n // that cached artifacts from other DOM component bundles can be reused.\n transformOptions.customTransformOptions.dom = 'true';\n }\n\n const routerRoot = transformOptions.customTransformOptions?.routerRoot;\n if (typeof routerRoot === 'string') {\n const isRouterEntry = /\\/expo-router\\/_ctx/.test(filePath);\n // The router root is used all over expo-router (`process.env.EXPO_ROUTER_ABS_APP_ROOT`, `process.env.EXPO_ROUTER_APP_ROOT`) so we'll just ignore the entire package.\n const isRouterModule = /\\/expo-router\\/build\\//.test(filePath);\n // Any page/router inside the expo-router app folder may access the `routerRoot` option to determine whether it's in the app folder\n const resolvedRouterRoot = path.resolve(projectRoot, routerRoot).split(path.sep).join('/');\n const isRouterRoute = path.isAbsolute(filePath) && filePath.startsWith(resolvedRouterRoot);\n\n // In any other file than the above, we enforce that we mustn't use `routerRoot`, and set it to an arbitrary value here (the default)\n // to ensure that the cache never invalidates when this value is changed\n if (!isRouterEntry && !isRouterModule && !isRouterRoute) {\n transformOptions.customTransformOptions!.routerRoot = 'app';\n }\n }\n\n if (\n transformOptions.customTransformOptions?.asyncRoutes &&\n // The async routes settings are also used in `expo-router/_ctx.ios.js` (and other platform variants) via `process.env.EXPO_ROUTER_IMPORT_MODE`\n !(filePath.match(/\\/expo-router\\/_ctx/) || filePath.match(/\\/expo-router\\/build\\//))\n ) {\n delete transformOptions.customTransformOptions.asyncRoutes;\n }\n\n if (\n transformOptions.customTransformOptions?.clientBoundaries &&\n // The client boundaries are only used in `expo/virtual/rsc.js` for production RSC exports.\n !filePath.match(/\\/expo\\/virtual\\/rsc\\.js$/)\n ) {\n delete transformOptions.customTransformOptions.clientBoundaries;\n }\n\n return transformOptions;\n}\n\n/**\n * Simplify and communicate if Metro is running without watching file updates,.\n * Exposed for testing.\n */\nexport function isWatchEnabled() {\n if (env.CI) {\n Log.log(\n chalk`Metro is running in CI mode, reloads are disabled. Remove {bold CI=true} to enable watch mode.`\n );\n }\n\n return !env.CI;\n}\n"],"names":["event","instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","events","t","asWritable","input","LogRespectingTerminal","Terminal","constructor","stream","ttyPrint","sendLog","msg","length","log","format","args","flush","console","info","terminal","process","stdout","projectRoot","options","exp","isExporting","getMetroBundler","config","reportEvent","serverRoot","getMetroServerRoot","isWorkspace","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","serverActionsEnabled","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","serverComponentsEnabled","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","warn","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","resolver","useWatchman","globalThis","__requireCycleIgnorePatterns","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reduceLogs","shouldReduceLogs","reactCompilerEnabled","reactCompiler","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","EXPO_UNSTABLE_LOG_BOX","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isNamedRequiresEnabled","isReactServerComponentsEnabled","path","exporting","flags","serverActions","serverComponents","optimizeGraph","treeshaking","logbox","setEventReporter","logger","metroBundler","getConfig","skipSDKVersionRequirement","metroConfig","metro","getBundler","middleware","messagesSocket","eventsSocket","websocketEndpoints","createMetroMiddleware","serverBaseUrl","getUrlCreator","constructUrl","scheme","hostType","prependMiddleware","createCorsMiddleware","debugMiddleware","debugWebsocketEndpoints","createDebugMiddleware","Object","assign","use","createJsInspectorMiddleware","customEnhanceMiddleware","enhanceMiddleware","metroMiddleware","devtoolsWebsocketEndpoints","createDevToolsPluginWebsocketEndpoint","attachAtlasAsync","resetAtlasFile","tls","secureServerOptions","key","cert","ca","requestCert","address","hmrServer","runServer","host","watch","mockServer","atlas","EXPO_ATLAS","workers","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","platform","environment","module","_createModuleId","sort","a","b","hmrJSBundle","require","default","_prepareMessage","group","changeEvent","isInitialUpdate","revision","revPromise","_bundler","getRevision","revisionId","type","body","formatBundlingError","RevisionNotFoundError","point","delta","updateGraph","_clientGroups","delete","id","client","clients","revisionIds","filter","push","set","moduleIdContext","hmrUpdate","clientUrl","createModuleId","moduleId","includeAsyncPaths","graphOptions","lazy","_config","unstable_serverRoot","error","formattedError","messageSocket","split","sep","join","dom","match","routerRoot","isRouterEntry","test","isRouterModule","resolvedRouterRoot","resolve","isRouterRoute","isAbsolute","startsWith","asyncRoutes","clientBoundaries","CI"],"mappings":"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"}
|
|
@@ -68,7 +68,7 @@ function _interop_require_default(obj) {
|
|
|
68
68
|
default: obj
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
const runServer = async (_metroBundler, config, { hasReducedPerformance = false, host, onError, onReady, secureServerOptions,
|
|
71
|
+
const runServer = async (_metroBundler, config, { hasReducedPerformance = false, host, onError, onReady, secureServerOptions, websocketEndpoints = {}, watch, waitForBundler = !!watch }, { mockServer })=>{
|
|
72
72
|
// await earlyPortCheck(host, config.server.port);
|
|
73
73
|
// if (secure != null || secureCert != null || secureKey != null) {
|
|
74
74
|
// // eslint-disable-next-line no-console
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/runServer-fork.ts"],"sourcesContent":["// Copyright © 2023 650 Industries.\n// Copyright (c) Meta Platforms, Inc. and affiliates.\n//\n// Forks https://github.com/facebook/metro/blob/b80d9a0f638ee9fb82ff69cd3c8d9f4309ca1da2/packages/metro/src/index.flow.js#L57\n// and adds the ability to access the bundler instance.\nimport { createConnectMiddleware } from '@expo/metro/metro';\nimport type { RunServerOptions } from '@expo/metro/metro';\nimport MetroHmrServer, { type Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport Server from '@expo/metro/metro/Server';\nimport createWebsocketServer from '@expo/metro/metro/lib/createWebsocketServer';\nimport type { ConfigT } from '@expo/metro/metro-config';\nimport assert from 'assert';\nimport http from 'http';\nimport https from 'https';\nimport type { AddressInfo } from 'net';\nimport { parse } from 'url';\nimport type { WebSocketServer } from 'ws';\n\nimport { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { Log } from '../../../log';\nimport type { ConnectAppType } from '../middleware/server.types';\n\nexport interface SecureServerOptions {\n readonly key: string | Buffer;\n readonly cert: string | Buffer;\n readonly ca: string | Buffer;\n readonly requestCert: boolean;\n}\n\ninterface RunServerOptionsFork {\n hasReducedPerformance?: boolean;\n host?: string;\n onError?($$PARAM_0$$: Error & { code?: string }): void;\n onReady?(server: http.Server | https.Server): void;\n onClose?(): void;\n websocketEndpoints?: RunServerOptions['websocketEndpoints'];\n secureServerOptions?: SecureServerOptions;\n waitForBundler?: boolean;\n watch?: boolean;\n}\n\nexport const runServer = async (\n _metroBundler: MetroBundlerDevServer,\n config: ConfigT,\n {\n hasReducedPerformance = false,\n host,\n onError,\n onReady,\n secureServerOptions,\n waitForBundler = false,\n websocketEndpoints = {},\n watch,\n }: RunServerOptionsFork,\n {\n mockServer,\n }: {\n // Use a mock server object instead of creating a real server, this is used in export cases where we want to reuse codepaths but not actually start a server.\n mockServer: boolean;\n }\n): Promise<{\n address: AddressInfo | null;\n server: http.Server | https.Server;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n metro: Server;\n}> => {\n // await earlyPortCheck(host, config.server.port);\n\n // if (secure != null || secureCert != null || secureKey != null) {\n // // eslint-disable-next-line no-console\n // console.warn(\n // chalk.inverse.yellow.bold(' DEPRECATED '),\n // 'The `secure`, `secureCert`, and `secureKey` options are now deprecated. ' +\n // 'Use the `secureServerOptions` object instead to pass options to ' +\n // \"Metro's https development server.\",\n // );\n // }\n\n const { middleware, end, metroServer } = await createConnectMiddleware(config, {\n hasReducedPerformance,\n waitForBundler,\n watch,\n });\n\n if (!mockServer) {\n assert(typeof (middleware as any).use === 'function');\n }\n const serverApp = middleware as ConnectAppType;\n\n let httpServer: http.Server | https.Server;\n\n if (secureServerOptions != null) {\n httpServer = https.createServer(secureServerOptions, serverApp);\n } else {\n httpServer = http.createServer(serverApp);\n }\n\n httpServer.on('error', (error) => {\n if ('code' in error && error.code === 'EADDRINUSE') {\n // If `Error: listen EADDRINUSE: address already in use :::8081` then print additional info\n // about the process before throwing.\n const { getRunningProcess } =\n require('../../../utils/getRunningProcess') as typeof import('../../../utils/getRunningProcess');\n getRunningProcess(config.server.port).then((info) => {\n if (info) {\n Log.error(\n `Port ${config.server.port} is busy running ${info.command} in: ${info.directory}`\n );\n }\n });\n }\n\n if (onError) {\n onError(error);\n }\n end();\n });\n\n // Disable any kind of automatic timeout behavior for incoming\n // requests in case it takes the packager more than the default\n // timeout of 120 seconds to respond to a request.\n httpServer.timeout = 0;\n\n // Extend the close method to ensure all websocket servers are closed, and connections are terminated\n const originalClose = httpServer.close.bind(httpServer);\n\n httpServer.close = function closeHttpServer(callback) {\n originalClose((err?: Error) => {\n // Always call end() to clean up Metro workers, even if the server wasn't started.\n // The 'close' event doesn't fire for servers that were never started (mockServer case),\n // so we need to call end() explicitly here.\n end();\n callback?.(err);\n });\n\n // Close all websocket servers, including possible client connections (see: https://github.com/websockets/ws/issues/2137#issuecomment-1507469375)\n for (const endpoint of Object.values(websocketEndpoints) as WebSocketServer[]) {\n endpoint.close();\n endpoint.clients.forEach((client) => client.terminate());\n }\n\n // Forcibly close active connections\n this.closeAllConnections();\n return this;\n };\n\n if (mockServer) {\n return { address: null, server: httpServer, hmrServer: null, metro: metroServer };\n }\n\n return new Promise((resolve, reject) => {\n httpServer.on('error', (error) => {\n reject(error);\n });\n\n httpServer.listen(config.server.port, host, () => {\n if (onReady) {\n onReady(httpServer);\n }\n\n const hmrServer = new MetroHmrServer(\n metroServer.getBundler(),\n metroServer.getCreateModuleId(),\n config\n );\n\n Object.assign(websocketEndpoints, {\n '/hot': createWebsocketServer({\n websocketServer: hmrServer,\n }),\n });\n\n httpServer.on('upgrade', (request, socket, head) => {\n const { pathname } = parse(request.url!);\n if (pathname != null && websocketEndpoints[pathname]) {\n websocketEndpoints[pathname].handleUpgrade(request, socket, head, (ws) => {\n websocketEndpoints[pathname].emit('connection', ws, request);\n });\n } else {\n socket.destroy();\n }\n });\n\n const address = httpServer.address();\n\n resolve({\n address: address && typeof address === 'object' ? address : null,\n server: httpServer,\n hmrServer,\n metro: metroServer,\n });\n });\n });\n};\n"],"names":["runServer","_metroBundler","config","hasReducedPerformance","host","onError","onReady","secureServerOptions","waitForBundler","websocketEndpoints","watch","mockServer","middleware","end","metroServer","createConnectMiddleware","assert","use","serverApp","httpServer","https","createServer","http","on","error","code","getRunningProcess","require","server","port","then","info","Log","command","directory","timeout","originalClose","close","bind","closeHttpServer","callback","err","endpoint","Object","values","clients","forEach","client","terminate","closeAllConnections","address","hmrServer","metro","Promise","resolve","reject","listen","MetroHmrServer","getBundler","getCreateModuleId","assign","createWebsocketServer","websocketServer","request","socket","head","pathname","parse","url","handleUpgrade","ws","emit","destroy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/runServer-fork.ts"],"sourcesContent":["// Copyright © 2023 650 Industries.\n// Copyright (c) Meta Platforms, Inc. and affiliates.\n//\n// Forks https://github.com/facebook/metro/blob/b80d9a0f638ee9fb82ff69cd3c8d9f4309ca1da2/packages/metro/src/index.flow.js#L57\n// and adds the ability to access the bundler instance.\nimport { createConnectMiddleware } from '@expo/metro/metro';\nimport type { RunServerOptions } from '@expo/metro/metro';\nimport MetroHmrServer, { type Client as MetroHmrClient } from '@expo/metro/metro/HmrServer';\nimport Server from '@expo/metro/metro/Server';\nimport createWebsocketServer from '@expo/metro/metro/lib/createWebsocketServer';\nimport type { ConfigT } from '@expo/metro/metro-config';\nimport assert from 'assert';\nimport http from 'http';\nimport https from 'https';\nimport type { AddressInfo } from 'net';\nimport { parse } from 'url';\nimport type { WebSocketServer } from 'ws';\n\nimport { MetroBundlerDevServer } from './MetroBundlerDevServer';\nimport { Log } from '../../../log';\nimport type { ConnectAppType } from '../middleware/server.types';\n\nexport interface SecureServerOptions {\n readonly key: string | Buffer;\n readonly cert: string | Buffer;\n readonly ca: string | Buffer;\n readonly requestCert: boolean;\n}\n\ninterface RunServerOptionsFork {\n hasReducedPerformance?: boolean;\n host?: string;\n onError?($$PARAM_0$$: Error & { code?: string }): void;\n onReady?(server: http.Server | https.Server): void;\n onClose?(): void;\n websocketEndpoints?: RunServerOptions['websocketEndpoints'];\n secureServerOptions?: SecureServerOptions;\n waitForBundler?: boolean;\n watch?: boolean;\n}\n\nexport const runServer = async (\n _metroBundler: MetroBundlerDevServer,\n config: ConfigT,\n {\n hasReducedPerformance = false,\n host,\n onError,\n onReady,\n secureServerOptions,\n websocketEndpoints = {},\n watch,\n waitForBundler = !!watch,\n }: RunServerOptionsFork,\n {\n mockServer,\n }: {\n // Use a mock server object instead of creating a real server, this is used in export cases where we want to reuse codepaths but not actually start a server.\n mockServer: boolean;\n }\n): Promise<{\n address: AddressInfo | null;\n server: http.Server | https.Server;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n metro: Server;\n}> => {\n // await earlyPortCheck(host, config.server.port);\n\n // if (secure != null || secureCert != null || secureKey != null) {\n // // eslint-disable-next-line no-console\n // console.warn(\n // chalk.inverse.yellow.bold(' DEPRECATED '),\n // 'The `secure`, `secureCert`, and `secureKey` options are now deprecated. ' +\n // 'Use the `secureServerOptions` object instead to pass options to ' +\n // \"Metro's https development server.\",\n // );\n // }\n\n const { middleware, end, metroServer } = await createConnectMiddleware(config, {\n hasReducedPerformance,\n waitForBundler,\n watch,\n });\n\n if (!mockServer) {\n assert(typeof (middleware as any).use === 'function');\n }\n const serverApp = middleware as ConnectAppType;\n\n let httpServer: http.Server | https.Server;\n\n if (secureServerOptions != null) {\n httpServer = https.createServer(secureServerOptions, serverApp);\n } else {\n httpServer = http.createServer(serverApp);\n }\n\n httpServer.on('error', (error) => {\n if ('code' in error && error.code === 'EADDRINUSE') {\n // If `Error: listen EADDRINUSE: address already in use :::8081` then print additional info\n // about the process before throwing.\n const { getRunningProcess } =\n require('../../../utils/getRunningProcess') as typeof import('../../../utils/getRunningProcess');\n getRunningProcess(config.server.port).then((info) => {\n if (info) {\n Log.error(\n `Port ${config.server.port} is busy running ${info.command} in: ${info.directory}`\n );\n }\n });\n }\n\n if (onError) {\n onError(error);\n }\n end();\n });\n\n // Disable any kind of automatic timeout behavior for incoming\n // requests in case it takes the packager more than the default\n // timeout of 120 seconds to respond to a request.\n httpServer.timeout = 0;\n\n // Extend the close method to ensure all websocket servers are closed, and connections are terminated\n const originalClose = httpServer.close.bind(httpServer);\n\n httpServer.close = function closeHttpServer(callback) {\n originalClose((err?: Error) => {\n // Always call end() to clean up Metro workers, even if the server wasn't started.\n // The 'close' event doesn't fire for servers that were never started (mockServer case),\n // so we need to call end() explicitly here.\n end();\n callback?.(err);\n });\n\n // Close all websocket servers, including possible client connections (see: https://github.com/websockets/ws/issues/2137#issuecomment-1507469375)\n for (const endpoint of Object.values(websocketEndpoints) as WebSocketServer[]) {\n endpoint.close();\n endpoint.clients.forEach((client) => client.terminate());\n }\n\n // Forcibly close active connections\n this.closeAllConnections();\n return this;\n };\n\n if (mockServer) {\n return { address: null, server: httpServer, hmrServer: null, metro: metroServer };\n }\n\n return new Promise((resolve, reject) => {\n httpServer.on('error', (error) => {\n reject(error);\n });\n\n httpServer.listen(config.server.port, host, () => {\n if (onReady) {\n onReady(httpServer);\n }\n\n const hmrServer = new MetroHmrServer(\n metroServer.getBundler(),\n metroServer.getCreateModuleId(),\n config\n );\n\n Object.assign(websocketEndpoints, {\n '/hot': createWebsocketServer({\n websocketServer: hmrServer,\n }),\n });\n\n httpServer.on('upgrade', (request, socket, head) => {\n const { pathname } = parse(request.url!);\n if (pathname != null && websocketEndpoints[pathname]) {\n websocketEndpoints[pathname].handleUpgrade(request, socket, head, (ws) => {\n websocketEndpoints[pathname].emit('connection', ws, request);\n });\n } else {\n socket.destroy();\n }\n });\n\n const address = httpServer.address();\n\n resolve({\n address: address && typeof address === 'object' ? address : null,\n server: httpServer,\n hmrServer,\n metro: metroServer,\n });\n });\n });\n};\n"],"names":["runServer","_metroBundler","config","hasReducedPerformance","host","onError","onReady","secureServerOptions","websocketEndpoints","watch","waitForBundler","mockServer","middleware","end","metroServer","createConnectMiddleware","assert","use","serverApp","httpServer","https","createServer","http","on","error","code","getRunningProcess","require","server","port","then","info","Log","command","directory","timeout","originalClose","close","bind","closeHttpServer","callback","err","endpoint","Object","values","clients","forEach","client","terminate","closeAllConnections","address","hmrServer","metro","Promise","resolve","reject","listen","MetroHmrServer","getBundler","getCreateModuleId","assign","createWebsocketServer","websocketServer","request","socket","head","pathname","parse","url","handleUpgrade","ws","emit","destroy"],"mappings":"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"}
|
|
@@ -14,6 +14,9 @@ _export(exports, {
|
|
|
14
14
|
},
|
|
15
15
|
serializeHtmlWithAssets: function() {
|
|
16
16
|
return serializeHtmlWithAssets;
|
|
17
|
+
},
|
|
18
|
+
sortMatchedAssetsByEntryPoints: function() {
|
|
19
|
+
return sortMatchedAssetsByEntryPoints;
|
|
17
20
|
}
|
|
18
21
|
});
|
|
19
22
|
const debug = require('debug')('expo:metro:html');
|
|
@@ -60,7 +63,15 @@ function htmlFromSerialAssets(assets, { isExporting, template, baseUrl, bundleUr
|
|
|
60
63
|
// External link tags will be passed through as-is.
|
|
61
64
|
return source;
|
|
62
65
|
}).join('');
|
|
63
|
-
|
|
66
|
+
let orderedJsAssets = assetsRequiresSort(assets.filter((asset)=>asset.type === 'js'));
|
|
67
|
+
if ((route == null ? void 0 : route.entryPoints) && Array.isArray(route.entryPoints)) {
|
|
68
|
+
const syncAssets = orderedJsAssets.filter((a)=>!a.metadata.isAsync);
|
|
69
|
+
const sortedAsync = sortMatchedAssetsByEntryPoints(orderedJsAssets.filter((a)=>a.metadata.isAsync), route.entryPoints);
|
|
70
|
+
orderedJsAssets = [
|
|
71
|
+
...syncAssets,
|
|
72
|
+
...sortedAsync
|
|
73
|
+
];
|
|
74
|
+
}
|
|
64
75
|
const scripts = bundleUrl ? `<script src="${bundleUrl}" defer></script>` : orderedJsAssets.map(({ filename, metadata })=>{
|
|
65
76
|
// TODO: Mark dependencies of the HTML and include them to prevent waterfalls.
|
|
66
77
|
if (metadata.isAsync) {
|
|
@@ -87,6 +98,10 @@ function htmlFromSerialAssets(assets, { isExporting, template, baseUrl, bundleUr
|
|
|
87
98
|
}
|
|
88
99
|
return template.replace('</head>', `${styleString}</head>`).replace('</body>', `${scripts}\n</body>`);
|
|
89
100
|
}
|
|
101
|
+
function sortMatchedAssetsByEntryPoints(matchedAssets, entryPoints) {
|
|
102
|
+
const getEntryPointIndex = (modulePaths)=>modulePaths ? entryPoints.findIndex((ep)=>modulePaths.includes(ep)) : -1;
|
|
103
|
+
return matchedAssets.sort((a, b)=>getEntryPointIndex(a.metadata.modulePaths) - getEntryPointIndex(b.metadata.modulePaths));
|
|
104
|
+
}
|
|
90
105
|
function assetsRequiresSort(assets) {
|
|
91
106
|
const lookup = new Map();
|
|
92
107
|
const visited = new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/serializeHtml.ts"],"sourcesContent":["import type { SerialAsset } from '@expo/metro-config/build/serializer/serializerAssets';\nimport type { RouteNode } from 'expo-router/build/Route';\n\nconst debug = require('debug')('expo:metro:html') as typeof console.log;\n\nexport function serializeHtmlWithAssets({\n resources,\n template,\n devBundleUrl,\n baseUrl,\n route,\n isExporting,\n hydrate,\n}: {\n resources: SerialAsset[];\n template: string;\n /** asset prefix used for deploying to non-standard origins like GitHub pages. */\n baseUrl: string;\n devBundleUrl?: string;\n route?: RouteNode;\n isExporting: boolean;\n hydrate?: boolean;\n}): string {\n if (!resources) {\n return '';\n }\n return htmlFromSerialAssets(resources, {\n isExporting,\n template,\n baseUrl,\n bundleUrl: isExporting ? undefined : devBundleUrl,\n route,\n hydrate,\n });\n}\n\n/**\n * Combine the path segments of a URL.\n * This filters out empty segments and avoids duplicate slashes when joining.\n * If base url is empty, it will be treated as a root path, adding `/` to the beginning.\n */\nfunction combineUrlPath(baseUrl: string, ...segments: string[]) {\n return [baseUrl || '/', ...segments]\n .filter(Boolean)\n .map((segment, index) => {\n const segmentIsBaseUrl = index === 0;\n // Do not remove leading slashes from baseUrl\n return segment.replace(segmentIsBaseUrl ? /\\/+$/g : /^\\/+|\\/+$/g, '');\n })\n .join('/');\n}\n\nfunction htmlFromSerialAssets(\n assets: SerialAsset[],\n {\n isExporting,\n template,\n baseUrl,\n bundleUrl,\n route,\n hydrate,\n }: {\n isExporting: boolean;\n template: string;\n baseUrl: string;\n /** This is dev-only. */\n bundleUrl?: string;\n route?: RouteNode;\n hydrate?: boolean;\n }\n) {\n // Combine the CSS modules into tags that have hot refresh data attributes.\n const styleString = assets\n .filter((asset) => asset.type.startsWith('css'))\n .map(({ type, metadata, filename, source }) => {\n if (type === 'css') {\n if (isExporting) {\n return [\n `<link rel=\"preload\" href=\"${combineUrlPath(baseUrl, filename)}\" as=\"style\">`,\n `<link rel=\"stylesheet\" href=\"${combineUrlPath(baseUrl, filename)}\">`,\n ].join('');\n } else {\n return `<style data-expo-css-hmr=\"${metadata.hmrId}\">` + source + '\\n</style>';\n }\n }\n // External link tags will be passed through as-is.\n return source;\n })\n .join('');\n\n const orderedJsAssets = assetsRequiresSort(assets.filter((asset) => asset.type === 'js'));\n\n const scripts = bundleUrl\n ? `<script src=\"${bundleUrl}\" defer></script>`\n : orderedJsAssets\n .map(({ filename, metadata }) => {\n // TODO: Mark dependencies of the HTML and include them to prevent waterfalls.\n if (metadata.isAsync) {\n // We have the data required to match async chunks to the route's HTML file.\n if (\n route?.entryPoints &&\n metadata.modulePaths &&\n Array.isArray(route.entryPoints) &&\n Array.isArray(metadata.modulePaths)\n ) {\n // TODO: Handle module IDs like `expo-router/build/views/Unmatched.js`\n const doesAsyncChunkContainRouteEntryPoint = route.entryPoints.some((entryPoint) =>\n (metadata.modulePaths as string[]).includes(entryPoint)\n );\n if (!doesAsyncChunkContainRouteEntryPoint) {\n return '';\n }\n debug('Linking async chunk %s to HTML for route %s', filename, route.contextKey);\n // Pass through to the next condition.\n } else {\n return '';\n }\n // Mark async chunks as defer so they don't block the page load.\n // return `<script src=\"${combineUrlPath(baseUrl, filename)\" defer></script>`;\n }\n\n return `<script src=\"${combineUrlPath(baseUrl, filename)}\" defer></script>`;\n })\n .join('');\n\n if (hydrate) {\n const hydrateScript = `<script type=\"module\">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script>`;\n template = template.replace('</head>', `${hydrateScript}</head>`);\n }\n\n return template\n .replace('</head>', `${styleString}</head>`)\n .replace('</body>', `${scripts}\\n</body>`);\n}\n\n/**\n * Sorts assets based on the requires tree. DFS order.\n */\nexport function assetsRequiresSort(assets: SerialAsset[]): SerialAsset[] {\n const lookup = new Map<string, SerialAsset>();\n const visited = new Set();\n const visiting = new Set();\n const result: SerialAsset[] = [];\n\n assets.forEach((a) => {\n lookup.set(a.filename, a);\n });\n\n function visit(name: string) {\n if (visited.has(name)) return;\n if (visiting.has(name))\n throw new Error(\n `Circular dependencies in assets are not allowed. Found cycle: ${[...visiting, name].join(' -> ')}`\n );\n\n visiting.add(name);\n\n const module = lookup.get(name);\n if (!module) throw new Error(`Asset not found: ${name}`);\n\n module.metadata.requires?.forEach((dependency) => {\n visit(dependency);\n });\n\n visiting.delete(name);\n visited.add(name);\n result.push(module);\n }\n\n assets.forEach((a) => {\n if (!visited.has(a.filename)) {\n visit(a.filename);\n }\n });\n\n return result;\n}\n"],"names":["assetsRequiresSort","serializeHtmlWithAssets","debug","require","resources","template","devBundleUrl","baseUrl","route","isExporting","hydrate","htmlFromSerialAssets","bundleUrl","undefined","combineUrlPath","segments","filter","Boolean","map","segment","index","segmentIsBaseUrl","replace","join","assets","styleString","asset","type","startsWith","metadata","filename","source","hmrId","orderedJsAssets","scripts","isAsync","entryPoints","modulePaths","Array","isArray","doesAsyncChunkContainRouteEntryPoint","some","entryPoint","includes","contextKey","hydrateScript","lookup","Map","visited","Set","visiting","result","forEach","a","set","visit","name","module","has","Error","add","get","requires","dependency","delete","push"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/serializeHtml.ts"],"sourcesContent":["import type { SerialAsset } from '@expo/metro-config/build/serializer/serializerAssets';\nimport type { RouteNode } from 'expo-router/build/Route';\n\nconst debug = require('debug')('expo:metro:html') as typeof console.log;\n\nexport function serializeHtmlWithAssets({\n resources,\n template,\n devBundleUrl,\n baseUrl,\n route,\n isExporting,\n hydrate,\n}: {\n resources: SerialAsset[];\n template: string;\n /** asset prefix used for deploying to non-standard origins like GitHub pages. */\n baseUrl: string;\n devBundleUrl?: string;\n route?: RouteNode;\n isExporting: boolean;\n hydrate?: boolean;\n}): string {\n if (!resources) {\n return '';\n }\n return htmlFromSerialAssets(resources, {\n isExporting,\n template,\n baseUrl,\n bundleUrl: isExporting ? undefined : devBundleUrl,\n route,\n hydrate,\n });\n}\n\n/**\n * Combine the path segments of a URL.\n * This filters out empty segments and avoids duplicate slashes when joining.\n * If base url is empty, it will be treated as a root path, adding `/` to the beginning.\n */\nfunction combineUrlPath(baseUrl: string, ...segments: string[]) {\n return [baseUrl || '/', ...segments]\n .filter(Boolean)\n .map((segment, index) => {\n const segmentIsBaseUrl = index === 0;\n // Do not remove leading slashes from baseUrl\n return segment.replace(segmentIsBaseUrl ? /\\/+$/g : /^\\/+|\\/+$/g, '');\n })\n .join('/');\n}\n\nfunction htmlFromSerialAssets(\n assets: SerialAsset[],\n {\n isExporting,\n template,\n baseUrl,\n bundleUrl,\n route,\n hydrate,\n }: {\n isExporting: boolean;\n template: string;\n baseUrl: string;\n /** This is dev-only. */\n bundleUrl?: string;\n route?: RouteNode;\n hydrate?: boolean;\n }\n) {\n // Combine the CSS modules into tags that have hot refresh data attributes.\n const styleString = assets\n .filter((asset) => asset.type.startsWith('css'))\n .map(({ type, metadata, filename, source }) => {\n if (type === 'css') {\n if (isExporting) {\n return [\n `<link rel=\"preload\" href=\"${combineUrlPath(baseUrl, filename)}\" as=\"style\">`,\n `<link rel=\"stylesheet\" href=\"${combineUrlPath(baseUrl, filename)}\">`,\n ].join('');\n } else {\n return `<style data-expo-css-hmr=\"${metadata.hmrId}\">` + source + '\\n</style>';\n }\n }\n // External link tags will be passed through as-is.\n return source;\n })\n .join('');\n\n let orderedJsAssets = assetsRequiresSort(assets.filter((asset) => asset.type === 'js'));\n\n if (route?.entryPoints && Array.isArray(route.entryPoints)) {\n const syncAssets = orderedJsAssets.filter((a) => !a.metadata.isAsync);\n const sortedAsync = sortMatchedAssetsByEntryPoints(\n orderedJsAssets.filter((a) => a.metadata.isAsync),\n route.entryPoints\n );\n orderedJsAssets = [...syncAssets, ...sortedAsync];\n }\n\n const scripts = bundleUrl\n ? `<script src=\"${bundleUrl}\" defer></script>`\n : orderedJsAssets\n .map(({ filename, metadata }) => {\n // TODO: Mark dependencies of the HTML and include them to prevent waterfalls.\n if (metadata.isAsync) {\n // We have the data required to match async chunks to the route's HTML file.\n if (\n route?.entryPoints &&\n metadata.modulePaths &&\n Array.isArray(route.entryPoints) &&\n Array.isArray(metadata.modulePaths)\n ) {\n // TODO: Handle module IDs like `expo-router/build/views/Unmatched.js`\n const doesAsyncChunkContainRouteEntryPoint = route.entryPoints.some((entryPoint) =>\n (metadata.modulePaths as string[]).includes(entryPoint)\n );\n if (!doesAsyncChunkContainRouteEntryPoint) {\n return '';\n }\n debug('Linking async chunk %s to HTML for route %s', filename, route.contextKey);\n // Pass through to the next condition.\n } else {\n return '';\n }\n // Mark async chunks as defer so they don't block the page load.\n // return `<script src=\"${combineUrlPath(baseUrl, filename)\" defer></script>`;\n }\n\n return `<script src=\"${combineUrlPath(baseUrl, filename)}\" defer></script>`;\n })\n .join('');\n\n if (hydrate) {\n const hydrateScript = `<script type=\"module\">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script>`;\n template = template.replace('</head>', `${hydrateScript}</head>`);\n }\n\n return template\n .replace('</head>', `${styleString}</head>`)\n .replace('</body>', `${scripts}\\n</body>`);\n}\n\n/**\n * Sorts matched async assets by their matching `entryPoint` in the route's `entryPoints` array.\n * This ensures layout chunks come before page chunks.\n */\nexport function sortMatchedAssetsByEntryPoints(\n matchedAssets: SerialAsset[],\n entryPoints: string[]\n): SerialAsset[] {\n const getEntryPointIndex = (modulePaths?: string[]) =>\n modulePaths ? entryPoints.findIndex((ep) => modulePaths.includes(ep)) : -1;\n\n return matchedAssets.sort(\n (a, b) =>\n getEntryPointIndex(a.metadata.modulePaths) - getEntryPointIndex(b.metadata.modulePaths)\n );\n}\n\n/**\n * Sorts assets based on the requires tree. DFS order.\n */\nexport function assetsRequiresSort(assets: SerialAsset[]): SerialAsset[] {\n const lookup = new Map<string, SerialAsset>();\n const visited = new Set();\n const visiting = new Set();\n const result: SerialAsset[] = [];\n\n assets.forEach((a) => {\n lookup.set(a.filename, a);\n });\n\n function visit(name: string) {\n if (visited.has(name)) return;\n if (visiting.has(name))\n throw new Error(\n `Circular dependencies in assets are not allowed. Found cycle: ${[...visiting, name].join(' -> ')}`\n );\n\n visiting.add(name);\n\n const module = lookup.get(name);\n if (!module) throw new Error(`Asset not found: ${name}`);\n\n module.metadata.requires?.forEach((dependency) => {\n visit(dependency);\n });\n\n visiting.delete(name);\n visited.add(name);\n result.push(module);\n }\n\n assets.forEach((a) => {\n if (!visited.has(a.filename)) {\n visit(a.filename);\n }\n });\n\n return result;\n}\n"],"names":["assetsRequiresSort","serializeHtmlWithAssets","sortMatchedAssetsByEntryPoints","debug","require","resources","template","devBundleUrl","baseUrl","route","isExporting","hydrate","htmlFromSerialAssets","bundleUrl","undefined","combineUrlPath","segments","filter","Boolean","map","segment","index","segmentIsBaseUrl","replace","join","assets","styleString","asset","type","startsWith","metadata","filename","source","hmrId","orderedJsAssets","entryPoints","Array","isArray","syncAssets","a","isAsync","sortedAsync","scripts","modulePaths","doesAsyncChunkContainRouteEntryPoint","some","entryPoint","includes","contextKey","hydrateScript","matchedAssets","getEntryPointIndex","findIndex","ep","sort","b","lookup","Map","visited","Set","visiting","result","forEach","set","visit","name","module","has","Error","add","get","requires","dependency","delete","push"],"mappings":"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"}
|
|
@@ -156,7 +156,12 @@ async function startAsync(projectRoot, options, settings) {
|
|
|
156
156
|
await devServerManager.bootstrapTypeScriptAsync();
|
|
157
157
|
}
|
|
158
158
|
if (!_env.env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly && !options.devClient) {
|
|
159
|
-
|
|
159
|
+
try {
|
|
160
|
+
await (0, _profile.profile)(_validateDependenciesVersions.validateDependenciesVersionsAsync)(projectRoot, exp, pkg);
|
|
161
|
+
} catch {
|
|
162
|
+
// We don't show the dependency validation error, since it's non-essential
|
|
163
|
+
// for the user to know it ran or failed
|
|
164
|
+
}
|
|
160
165
|
}
|
|
161
166
|
// Open project on devices.
|
|
162
167
|
await (0, _profile.profile)(_openPlatforms.openPlatformsAsync)(devServerManager, options);
|