@expo/cli 55.0.4 → 56.0.0-canary-20260128-67ce8d5
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 +3 -1
- package/build/bin/cli.map +1 -1
- package/build/src/start/interface/interactiveActions.js +2 -1
- package/build/src/start/interface/interactiveActions.js.map +1 -1
- package/build/src/start/server/UrlCreator.js +1 -1
- package/build/src/start/server/UrlCreator.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +144 -33
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +53 -0
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js +3 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ManifestMiddleware.js +14 -9
- package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
- package/build/src/start/server/type-generation/routes.js +2 -59
- package/build/src/start/server/type-generation/routes.js.map +1 -1
- package/build/src/utils/env.js +28 -0
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/interactive.js +1 -1
- package/build/src/utils/interactive.js.map +1 -1
- package/build/src/utils/jsonl.js +243 -0
- package/build/src/utils/jsonl.js.map +1 -0
- package/build/src/utils/progress.js +5 -0
- package/build/src/utils/progress.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/build/src/utils/url.js +4 -8
- package/build/src/utils/url.js.map +1 -1
- package/package.json +19 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import type { Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n if (level === 'warn' || (level as string) === 'error') {\n let hasStack = false;\n const parsed = event.data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') return p;\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(this.projectRoot, level, p);\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...filtered);\n })();\n return;\n }\n }\n\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n const converted = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (converted <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(converted.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n _logBundlingError(error: SnippetError): void {\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n if (moduleResolutionError) {\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n message += '\\n\\n' + nearestImportStack(error);\n return this.terminal.log(message);\n }\n\n attachImportStackToRootMessage(error);\n\n // NOTE(@kitten): Metro drops the stack forcefully when it finds a `SyntaxError`. However,\n // this is really unhelpful, since it prevents debugging Babel plugins or reporting bugs\n // in Babel plugins or a transformer entirely\n if (error.snippet == null && error.stack != null && error instanceof SyntaxError) {\n error.message = error.stack;\n delete error.stack;\n }\n\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","extractCodeFrame","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","_log","event","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","hasStack","parsed","map","msg","includes","stack","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","status","reason","value","isFallback","push","filtered","filter","_","logLikeMetro","log","bind","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","path","sep","replace","inputFile","entryFile","isAbsolute","relative","color","chalk","green","red","_bundleTimers","get","buildID","time","elapsed","micro","Number","converted","tenthFractionOfMicro","toFixed","cyan","bold","dim","plural","totalFileCount","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundlingError","error","moduleResolutionError","maybeAppendCodeFrame","nearestImportStack","attachImportStackToRootMessage","snippet","SyntaxError","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","formatted","ios","android","web","environment","trim"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import { AmbiguousModuleResolutionError, type Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { stripAnsi } from '../../../utils/ansi';\nimport { env } from '../../../utils/env';\nimport { getJsonlReporter } from '../../../utils/jsonl';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n private lastFailedBuildID: string | undefined = undefined;\n\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n const jsonlReporter = getJsonlReporter();\n\n switch (event.type) {\n case 'bundle_build_started': {\n const details = event.bundleDetails;\n if (details) {\n const platform = details.platform || 'unknown';\n const environment = details.customTransformOptions?.environment;\n jsonlReporter.emitBundlingStarted({\n id: event.buildID!,\n platform,\n path: details.entryFile,\n environment,\n });\n }\n break;\n }\n case 'unstable_server_log': {\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n\n // In JSONL mode, emit server log events and skip normal terminal logging\n if (\n jsonlReporter.emitServerLog({\n level: event.level,\n value: event.data ?? [],\n })\n )\n return;\n break;\n }\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n if (level === 'warn' || (level as string) === 'error') {\n let hasStack = false;\n const parsed = event.data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') return p;\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(this.projectRoot, level, p);\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n if (\n jsonlReporter.emitConsole({\n level,\n source: 'client',\n value: filtered,\n })\n )\n return;\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...filtered);\n })();\n return;\n }\n }\n\n if (\n jsonlReporter.emitConsole({\n level,\n source: 'client',\n value: event.data,\n })\n )\n return;\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const jsonlReporter = getJsonlReporter();\n\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: number | undefined = undefined;\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const converted = Number(elapsed) / 1e6;\n time = converted;\n }\n\n // Emit bundling.done in JSONL mode and return empty string\n if (phase === 'done') {\n if (\n jsonlReporter.emitBundlingDone({\n id: progress.bundleDetails.buildID!,\n duration: time,\n totalModules: progress.totalFileCount,\n })\n ) {\n return '';\n }\n }\n\n // Return empty string for failed phase in JSONL mode (error is emitted by _logBundlingError)\n if (phase === 'failed' && jsonlReporter.isEnabled) {\n return '';\n }\n\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n let timeLabel: string = '';\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (time !== undefined) {\n if (time <= 0.5) {\n // Format as microseconds to nearest tenth\n timeLabel = chalk.cyan.bold(`${time.toFixed(1)}ms`);\n } else {\n timeLabel = chalk.dim(time.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n timeLabel +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n if (\n getJsonlReporter().emitBundlingProgress({\n id: progress.bundleDetails.buildID ?? 'unknown',\n progress: progress.ratio,\n total: progress.totalFileCount,\n current: progress.transformedFileCount,\n })\n ) {\n return '';\n } else {\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n /**\n * Workaround to link build ids to bundling errors.\n * This works because `_logBundleBuildFailed` is called before `_logBundlingError` in synchronous manner.\n * https://github.com/facebook/metro/blob/main/packages/metro/src/Server.js#L939-L945\n */\n _logBundleBuildFailed(buildID: string): void {\n this.lastFailedBuildID = buildID;\n super._logBundleBuildFailed(buildID);\n }\n\n _logBundlingError(error: SnippetError): void {\n // Reset the last failed build id after it's used\n // Bundling errors can also be emitted during hot reload,\n // where bundling id is not available.\n // https://github.com/facebook/metro/blob/main/packages/metro/src/HmrServer.js#L384\n const lastFailedBuildID = this.lastFailedBuildID;\n this.lastFailedBuildID = undefined;\n\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n if (moduleResolutionError) {\n if (\n getJsonlReporter().emitBundlingError({\n id: lastFailedBuildID,\n value: stripAnsi(moduleResolutionError) ?? '',\n filename: error.filename,\n })\n )\n return;\n\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n message += '\\n\\n' + nearestImportStack(error);\n return this.terminal.log(message);\n }\n\n attachImportStackToRootMessage(error);\n\n // NOTE(@kitten): Metro drops the stack forcefully when it finds a `SyntaxError`. However,\n // this is really unhelpful, since it prevents debugging Babel plugins or reporting bugs\n // in Babel plugins or a transformer entirely\n if (error.snippet == null && error.stack != null && error instanceof SyntaxError) {\n error.message = error.stack;\n delete error.stack;\n }\n\n if (\n getJsonlReporter().emitBundlingError({\n id: lastFailedBuildID,\n value: stripAnsi(formatSnippetErrorForJSONL(error)) ?? '',\n filename: error.filename,\n })\n )\n return;\n\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Based on Metro's default `_logBundlingError` implementation.\n * https://github.com/facebook/metro/blob/main/packages/metro/src/lib/TerminalReporter.js#L308\n */\nexport function formatSnippetErrorForJSONL(error: SnippetError): string {\n if (error instanceof AmbiguousModuleResolutionError) {\n const he = error.hasteError;\n const message =\n 'ambiguous resolution: module `' +\n `${error.fromModulePath}\\` tries to require \\`${he.hasteName}\\`, ` +\n 'but there are several files providing this module. You can delete ' +\n 'or fix them: \\n\\n' +\n Object.keys(he.duplicatesSet)\n .sort()\n .map((dupFilePath) => ` * \\`${dupFilePath}\\`\\n`)\n .join('');\n return message;\n }\n\n let { message } = error;\n\n if (error.filename && !message.includes(error.filename)) {\n message += ` [${error.filename}]`;\n }\n\n if (error.snippet != null) {\n message += '\\n' + error.snippet;\n }\n\n return message;\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","extractCodeFrame","formatSnippetErrorForJSONL","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","lastFailedBuildID","undefined","_log","event","jsonlReporter","getJsonlReporter","type","details","bundleDetails","platform","environment","customTransformOptions","emitBundlingStarted","id","buildID","path","entryFile","data","message","match","env","EXPO_DEBUG","emitServerLog","level","value","shouldFilterClientLog","hasStack","parsed","map","msg","includes","stack","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","status","reason","isFallback","push","filtered","filter","_","emitConsole","source","logLikeMetro","log","bind","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","getPlatformTagForBuildDetails","inProgress","localPath","dom","sep","replace","inputFile","isAbsolute","relative","_bundleTimers","get","time","elapsed","converted","Number","emitBundlingDone","duration","totalModules","totalFileCount","isEnabled","color","chalk","green","red","timeLabel","cyan","bold","toFixed","dim","plural","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","emitBundlingProgress","total","current","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundleBuildFailed","_logBundlingError","error","moduleResolutionError","emitBundlingError","stripAnsi","filename","maybeAppendCodeFrame","nearestImportStack","attachImportStackToRootMessage","snippet","SyntaxError","AmbiguousModuleResolutionError","he","hasteError","fromModulePath","hasteName","Object","keys","duplicatesSet","sort","dupFilePath","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","formatted","ios","android","web","trim"],"mappings":"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"}
|
|
@@ -17,6 +17,9 @@ _export(exports, {
|
|
|
17
17
|
},
|
|
18
18
|
loadMetroConfigAsync: function() {
|
|
19
19
|
return loadMetroConfigAsync;
|
|
20
|
+
},
|
|
21
|
+
overrideExpoMetroCacheStores: function() {
|
|
22
|
+
return overrideExpoMetroCacheStores;
|
|
20
23
|
}
|
|
21
24
|
});
|
|
22
25
|
function _config() {
|
|
@@ -68,6 +71,13 @@ function _metroconfig1() {
|
|
|
68
71
|
};
|
|
69
72
|
return data;
|
|
70
73
|
}
|
|
74
|
+
function _filestore() {
|
|
75
|
+
const data = require("@expo/metro-config/file-store");
|
|
76
|
+
_filestore = function() {
|
|
77
|
+
return data;
|
|
78
|
+
};
|
|
79
|
+
return data;
|
|
80
|
+
}
|
|
71
81
|
function _chalk() {
|
|
72
82
|
const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
73
83
|
_chalk = function() {
|
|
@@ -75,6 +85,13 @@ function _chalk() {
|
|
|
75
85
|
};
|
|
76
86
|
return data;
|
|
77
87
|
}
|
|
88
|
+
function _fs() {
|
|
89
|
+
const data = /*#__PURE__*/ _interop_require_default(require("fs"));
|
|
90
|
+
_fs = function() {
|
|
91
|
+
return data;
|
|
92
|
+
};
|
|
93
|
+
return data;
|
|
94
|
+
}
|
|
78
95
|
function _path() {
|
|
79
96
|
const data = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
80
97
|
_path = function() {
|
|
@@ -173,6 +190,10 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
|
|
|
173
190
|
}
|
|
174
191
|
}
|
|
175
192
|
};
|
|
193
|
+
overrideExpoMetroCacheStores(config, {
|
|
194
|
+
projectRoot
|
|
195
|
+
});
|
|
196
|
+
// @ts-expect-error: Set the global require cycle ignore patterns for SSR bundles. This won't work with custom global prefixes, but we don't use those.
|
|
176
197
|
globalThis.__requireCycleIgnorePatterns = (_config_resolver = config.resolver) == null ? void 0 : _config_resolver.requireCycleIgnorePatterns;
|
|
177
198
|
if (isExporting) {
|
|
178
199
|
var _exp_experiments7;
|
|
@@ -434,5 +455,37 @@ function isWatchEnabled() {
|
|
|
434
455
|
}
|
|
435
456
|
return !_env.env.CI;
|
|
436
457
|
}
|
|
458
|
+
async function overrideExpoMetroCacheStores(config, { projectRoot }) {
|
|
459
|
+
var _config_cacheStores;
|
|
460
|
+
if (!_env.env.EXPO_METRO_CACHE_STORES_DIR) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
// Resolve relative paths to absolute paths based on project root
|
|
464
|
+
const cacheStoresDir = _path().default.isAbsolute(_env.env.EXPO_METRO_CACHE_STORES_DIR) ? _env.env.EXPO_METRO_CACHE_STORES_DIR : _path().default.resolve(projectRoot, _env.env.EXPO_METRO_CACHE_STORES_DIR);
|
|
465
|
+
// Create the directory if it doesn't exist
|
|
466
|
+
try {
|
|
467
|
+
await _fs().default.promises.mkdir(cacheStoresDir, {
|
|
468
|
+
recursive: true
|
|
469
|
+
});
|
|
470
|
+
} catch (error) {
|
|
471
|
+
if (error.code !== 'EEXIST') {
|
|
472
|
+
_log.Log.error(`Provided EXPO_METRO_CACHE_STORES_DIR="${cacheStoresDir}" is not a directory. Use new or existing directory path.`);
|
|
473
|
+
throw error;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
// Check if user has custom cacheStores in their metro.config.js
|
|
477
|
+
if ((_config_cacheStores = config.cacheStores) == null ? void 0 : _config_cacheStores.length) {
|
|
478
|
+
_log.Log.warn(`Using EXPO_METRO_CACHE_STORES_DIR="${cacheStoresDir}" which overrides cacheStores from metro.config.js`);
|
|
479
|
+
} else {
|
|
480
|
+
_log.Log.log(_chalk().default.gray(`Using Metro cache directory: ${cacheStoresDir}`));
|
|
481
|
+
}
|
|
482
|
+
// Override cacheStores with the env-specified directory
|
|
483
|
+
// @ts-expect-error - cacheStores is a read-only property
|
|
484
|
+
config.cacheStores = [
|
|
485
|
+
new (_filestore()).FileStore({
|
|
486
|
+
root: cacheStoresDir
|
|
487
|
+
})
|
|
488
|
+
];
|
|
489
|
+
}
|
|
437
490
|
|
|
438
491
|
//# sourceMappingURL=instantiateMetro.js.map
|
|
@@ -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 } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\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// 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 const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? env.EXPO_USE_STICKY_RESOLVER;\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n\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 (exp.experiments?.reactServerComponentRoutes || 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 serverRoot = getMetroServerRoot(projectRoot);\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 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\n if (exp.experiments?.reactCompiler) {\n Log.log(chalk.gray`React Compiler 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 (env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (env.EXPO_UNSTABLE_LOG_BOX) {\n Log.warn(`Experimental Expo LogBox is enabled.`);\n }\n if (autolinkingModuleResolutionEnabled) {\n Log.warn(`Experimental Expo Autolinking module resolver is enabled.`);\n }\n\n if (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: !!exp.experiments?.reactServerComponentRoutes,\n getMetroBundler,\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: LoadMetroConfigOptions,\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({ serverBaseUrl });\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 const { server, hmrServer, metro } = await runServer(\n metroBundler,\n metroConfig,\n {\n websocketEndpoints,\n watch: !isExporting && isWatchEnabled(),\n },\n {\n mockServer: isExporting,\n }\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":["instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","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","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","env","EXPO_USE_STICKY_RESOLVER","serverActionsEnabled","reactServerFunctions","EXPO_UNSTABLE_SERVER_FUNCTIONS","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","warn","serverRoot","getMetroServerRoot","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","event","globalThis","__requireCycleIgnorePatterns","resolver","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reactCompiler","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","EXPO_UNSTABLE_LOG_BOX","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isNamedRequiresEnabled","isReactServerComponentsEnabled","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","hmrServer","runServer","watch","mockServer","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","platform","environment","module","_createModuleId","path","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 { FileStore } from '@expo/metro-config/file-store';\nimport chalk from 'chalk';\nimport fs from 'fs';\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 } from './runServer-fork';\nimport { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';\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// 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 const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? env.EXPO_USE_STICKY_RESOLVER;\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n\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 (exp.experiments?.reactServerComponentRoutes || 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 serverRoot = getMetroServerRoot(projectRoot);\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\noverrideExpoMetroCacheStores(config, { projectRoot });\n\n // @ts-expect-error: Set the global require cycle ignore patterns for SSR bundles. This won't work with custom global prefixes, but we don't use those.\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\n if (exp.experiments?.reactCompiler) {\n Log.log(chalk.gray`React Compiler 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 (env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n Log.warn(`Experimental bundle optimization is enabled.`);\n }\n if (env.EXPO_UNSTABLE_TREE_SHAKING) {\n Log.warn(`Experimental tree shaking is enabled.`);\n }\n if (env.EXPO_UNSTABLE_LOG_BOX) {\n Log.warn(`Experimental Expo LogBox is enabled.`);\n }\n if (autolinkingModuleResolutionEnabled) {\n Log.warn(`Experimental Expo Autolinking module resolver is enabled.`);\n }\n\n if (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: !!exp.experiments?.reactServerComponentRoutes,\n getMetroBundler,\n });\n\n return {\n config,\n setEventReporter: (logger: (event: any) => void) => (reportEvent = logger),\n reporter: terminalReporter,\n };\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: LoadMetroConfigOptions,\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({ serverBaseUrl });\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 const { server, hmrServer, metro } = await runServer(\n metroBundler,\n metroConfig,\n {\n websocketEndpoints,\n watch: !isExporting && isWatchEnabled(),\n },\n {\n mockServer: isExporting,\n }\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\n/**\n * Override the Metro cache stores directory using the EXPO_METRO_CACHE_STORES_DIR environment variable.\n * Exposed for testing.\n */\nexport async function overrideExpoMetroCacheStores(\n config: ConfigT,\n { projectRoot }: { projectRoot: string }\n) {\n if (!env.EXPO_METRO_CACHE_STORES_DIR) {\n return;\n }\n\n // Resolve relative paths to absolute paths based on project root\n const cacheStoresDir = path.isAbsolute(env.EXPO_METRO_CACHE_STORES_DIR)\n ? env.EXPO_METRO_CACHE_STORES_DIR\n : path.resolve(projectRoot, env.EXPO_METRO_CACHE_STORES_DIR);\n\n // Create the directory if it doesn't exist\n try {\n await fs.promises.mkdir(cacheStoresDir, { recursive: true });\n } catch (error: any) {\n if (error.code !== 'EEXIST') {\n Log.error(\n `Provided EXPO_METRO_CACHE_STORES_DIR=\"${cacheStoresDir}\" is not a directory. Use new or existing directory path.`\n );\n throw error;\n }\n }\n\n // Check if user has custom cacheStores in their metro.config.js\n if (config.cacheStores?.length) {\n Log.warn(\n `Using EXPO_METRO_CACHE_STORES_DIR=\"${cacheStoresDir}\" which overrides cacheStores from metro.config.js`\n );\n } else {\n Log.log(chalk.gray(`Using Metro cache directory: ${cacheStoresDir}`));\n }\n\n // Override cacheStores with the env-specified directory\n // @ts-expect-error - cacheStores is a read-only property\n config.cacheStores = [\n new FileStore({\n root: cacheStoresDir,\n }),\n ];\n}\n"],"names":["instantiateMetroAsync","isWatchEnabled","loadMetroConfigAsync","overrideExpoMetroCacheStores","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","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","env","EXPO_USE_STICKY_RESOLVER","serverActionsEnabled","reactServerFunctions","EXPO_UNSTABLE_SERVER_FUNCTIONS","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","warn","serverRoot","getMetroServerRoot","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","event","globalThis","__requireCycleIgnorePatterns","resolver","requireCycleIgnorePatterns","transformer","publicPath","baseUrl","platformBundlers","getPlatformBundlers","reactCompiler","chalk","gray","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","CommandError","EXPO_UNSTABLE_LOG_BOX","withMetroMultiPlatformAsync","isTsconfigPathsEnabled","tsconfigPaths","isAutolinkingResolverEnabled","isNamedRequiresEnabled","isReactServerComponentsEnabled","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","hmrServer","runServer","watch","mockServer","originalTransformFile","transformFile","bind","filePath","transformOptions","fileBuffer","pruneCustomTransformOptions","customTransformOptions","__proto__","reportMetroEvent","_getSortedModules","graph","modules","dependencies","values","ctx","platform","environment","module","_createModuleId","path","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","EXPO_METRO_CACHE_STORES_DIR","cacheStoresDir","fs","promises","mkdir","recursive","code","cacheStores","FileStore","root"],"mappings":"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"}
|
|
@@ -102,11 +102,13 @@ class ExpoGoManifestHandlerMiddleware extends _ManifestMiddleware.ManifestMiddle
|
|
|
102
102
|
break;
|
|
103
103
|
}
|
|
104
104
|
const expectSignature = req.headers['expo-expect-signature'];
|
|
105
|
+
const requestedUrl = (0, _url.parseUrl)(req.headers['host']);
|
|
105
106
|
return {
|
|
106
107
|
responseContentType,
|
|
107
108
|
platform,
|
|
108
109
|
expectSignature: expectSignature ? String(expectSignature) : null,
|
|
109
|
-
hostname:
|
|
110
|
+
hostname: requestedUrl == null ? void 0 : requestedUrl.hostname,
|
|
111
|
+
port: requestedUrl == null ? void 0 : requestedUrl.port,
|
|
110
112
|
protocol: req.headers['x-forwarded-proto']
|
|
111
113
|
};
|
|
112
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/middleware/ExpoGoManifestHandlerMiddleware.ts"],"sourcesContent":["import { ExpoUpdatesManifest } from '@expo/config';\nimport { Updates } from '@expo/config-plugins';\nimport accepts from 'accepts';\nimport crypto from 'crypto';\nimport { serializeDictionary, Dictionary } from 'structured-headers';\n\nimport { ManifestMiddleware, ManifestRequestInfo } from './ManifestMiddleware';\nimport { assertRuntimePlatform, parsePlatformHeader } from './resolvePlatform';\nimport { resolveRuntimeVersionWithExpoUpdatesAsync } from './resolveRuntimeVersionWithExpoUpdatesAsync';\nimport { ServerHeaders, ServerRequest } from './server.types';\nimport { getAnonymousIdAsync } from '../../../api/user/UserSettings';\nimport { ANONYMOUS_USERNAME } from '../../../api/user/user';\nimport {\n CodeSigningInfo,\n getCodeSigningInfoAsync,\n signManifestString,\n} from '../../../utils/codesigning';\nimport { CommandError } from '../../../utils/errors';\nimport {\n encodeMultipartMixed,\n FormDataField,\n EncodedFormData,\n} from '../../../utils/multipartMixed';\nimport { stripPort } from '../../../utils/url';\n\nconst debug = require('debug')('expo:start:server:middleware:ExpoGoManifestHandlerMiddleware');\n\nexport enum ResponseContentType {\n TEXT_PLAIN,\n APPLICATION_JSON,\n APPLICATION_EXPO_JSON,\n MULTIPART_MIXED,\n}\n\ninterface ExpoGoManifestRequestInfo extends ManifestRequestInfo {\n responseContentType: ResponseContentType;\n expectSignature: string | null;\n}\n\nexport class ExpoGoManifestHandlerMiddleware extends ManifestMiddleware<ExpoGoManifestRequestInfo> {\n public getParsedHeaders(req: ServerRequest): ExpoGoManifestRequestInfo {\n let platform = parsePlatformHeader(req);\n\n if (!platform) {\n debug(\n `No \"expo-platform\" header or \"platform\" query parameter specified. Falling back to \"ios\".`\n );\n platform = 'ios';\n }\n\n assertRuntimePlatform(platform);\n\n // Expo Updates clients explicitly accept \"multipart/mixed\" responses while browsers implicitly\n // accept them with \"accept: */*\". To make it easier to debug manifest responses by visiting their\n // URLs in a browser, we denote the response as \"text/plain\" if the user agent appears not to be\n // an Expo Updates client.\n const accept = accepts(req);\n const acceptedType = accept.types([\n 'unknown/unknown',\n 'multipart/mixed',\n 'application/json',\n 'application/expo+json',\n 'text/plain',\n ]);\n\n let responseContentType;\n switch (acceptedType) {\n case 'multipart/mixed':\n responseContentType = ResponseContentType.MULTIPART_MIXED;\n break;\n case 'application/json':\n responseContentType = ResponseContentType.APPLICATION_JSON;\n break;\n case 'application/expo+json':\n responseContentType = ResponseContentType.APPLICATION_EXPO_JSON;\n break;\n default:\n responseContentType = ResponseContentType.TEXT_PLAIN;\n break;\n }\n\n const expectSignature = req.headers['expo-expect-signature'];\n\n return {\n responseContentType,\n platform,\n expectSignature: expectSignature ? String(expectSignature) : null,\n hostname: stripPort(req.headers['host']),\n protocol: req.headers['x-forwarded-proto'] as 'http' | 'https' | undefined,\n };\n }\n\n private getDefaultResponseHeaders(): ServerHeaders {\n const headers = new Map<string, number | string | readonly string[]>();\n // set required headers for Expo Updates manifest specification\n headers.set('expo-protocol-version', 0);\n headers.set('expo-sfv-version', 0);\n headers.set('cache-control', 'private, max-age=0');\n return headers;\n }\n\n public async _getManifestResponseAsync(requestOptions: ExpoGoManifestRequestInfo): Promise<{\n body: string;\n version: string;\n headers: ServerHeaders;\n }> {\n const { exp, hostUri, expoGoConfig, bundleUrl } =\n await this._resolveProjectSettingsAsync(requestOptions);\n\n const runtimeVersion =\n (await resolveRuntimeVersionWithExpoUpdatesAsync({\n projectRoot: this.projectRoot,\n platform: requestOptions.platform,\n })) ??\n // if expo-updates can't determine runtime version, fall back to calculation from config-plugin.\n // this happens when expo-updates is installed but runtimeVersion hasn't yet been configured or when\n // expo-updates is not installed.\n (await Updates.getRuntimeVersionAsync(\n this.projectRoot,\n { ...exp, runtimeVersion: exp.runtimeVersion ?? { policy: 'sdkVersion' } },\n requestOptions.platform\n ));\n if (!runtimeVersion) {\n throw new CommandError(\n 'MANIFEST_MIDDLEWARE',\n `Unable to determine runtime version for platform '${requestOptions.platform}'`\n );\n }\n\n const codeSigningInfo = await getCodeSigningInfoAsync(\n exp,\n requestOptions.expectSignature,\n this.options.privateKeyPath\n );\n\n const easProjectId = exp.extra?.eas?.projectId as string | undefined | null;\n const scopeKey = await ExpoGoManifestHandlerMiddleware.getScopeKeyAsync({\n slug: exp.slug,\n codeSigningInfo,\n });\n\n const expoUpdatesManifest: ExpoUpdatesManifest = {\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n runtimeVersion,\n launchAsset: {\n key: 'bundle',\n contentType: 'application/javascript',\n url: bundleUrl,\n },\n assets: [], // assets are not used in development\n metadata: {}, // required for the client to detect that this is an expo-updates manifest\n extra: {\n eas: {\n projectId: easProjectId ?? undefined,\n },\n expoClient: {\n ...exp,\n hostUri,\n },\n expoGo: expoGoConfig,\n scopeKey,\n },\n };\n\n const stringifiedManifest = JSON.stringify(expoUpdatesManifest);\n\n let manifestPartHeaders: { 'expo-signature': string } | null = null;\n let certificateChainBody: string | null = null;\n if (codeSigningInfo) {\n const signature = signManifestString(stringifiedManifest, codeSigningInfo);\n manifestPartHeaders = {\n 'expo-signature': serializeDictionary(\n convertToDictionaryItemsRepresentation({\n keyid: codeSigningInfo.keyId,\n sig: signature,\n alg: 'rsa-v1_5-sha256',\n })\n ),\n };\n certificateChainBody = codeSigningInfo.certificateChainForResponse.join('\\n');\n }\n\n const headers = this.getDefaultResponseHeaders();\n\n switch (requestOptions.responseContentType) {\n case ResponseContentType.MULTIPART_MIXED: {\n const encoded = await this.encodeFormDataAsync({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n });\n headers.set('content-type', `multipart/mixed; boundary=${encoded.boundary}`);\n return {\n body: encoded.body,\n version: runtimeVersion,\n headers,\n };\n }\n case ResponseContentType.APPLICATION_EXPO_JSON:\n case ResponseContentType.APPLICATION_JSON:\n case ResponseContentType.TEXT_PLAIN: {\n headers.set(\n 'content-type',\n ExpoGoManifestHandlerMiddleware.getContentTypeForResponseContentType(\n requestOptions.responseContentType\n )\n );\n if (manifestPartHeaders) {\n Object.entries(manifestPartHeaders).forEach(([key, value]) => {\n headers.set(key, value);\n });\n }\n\n return {\n body: stringifiedManifest,\n version: runtimeVersion,\n headers,\n };\n }\n }\n }\n\n private static getContentTypeForResponseContentType(\n responseContentType: ResponseContentType\n ): string {\n switch (responseContentType) {\n case ResponseContentType.MULTIPART_MIXED:\n return 'multipart/mixed';\n case ResponseContentType.APPLICATION_EXPO_JSON:\n return 'application/expo+json';\n case ResponseContentType.APPLICATION_JSON:\n return 'application/json';\n case ResponseContentType.TEXT_PLAIN:\n return 'text/plain';\n }\n }\n\n private encodeFormDataAsync({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n }: {\n stringifiedManifest: string;\n manifestPartHeaders: { 'expo-signature': string } | null;\n certificateChainBody: string | null;\n }): Promise<EncodedFormData> {\n const fields: FormDataField[] = [\n {\n name: 'manifest',\n value: stringifiedManifest,\n contentType: 'application/json',\n partHeaders: manifestPartHeaders,\n },\n ];\n if (certificateChainBody && certificateChainBody.length > 0) {\n fields.push({\n name: 'certificate_chain',\n value: certificateChainBody,\n contentType: 'application/x-pem-file',\n });\n }\n return encodeMultipartMixed(fields);\n }\n\n private static async getScopeKeyAsync({\n slug,\n codeSigningInfo,\n }: {\n slug: string;\n codeSigningInfo: CodeSigningInfo | null;\n }): Promise<string> {\n const scopeKeyFromCodeSigningInfo = codeSigningInfo?.scopeKey;\n if (scopeKeyFromCodeSigningInfo) {\n return scopeKeyFromCodeSigningInfo;\n }\n\n // Log.warn(\n // env.EXPO_OFFLINE\n // ? 'Using anonymous scope key in manifest for offline mode.'\n // : 'Using anonymous scope key in manifest.'\n // );\n return await getAnonymousScopeKeyAsync(slug);\n }\n}\n\nasync function getAnonymousScopeKeyAsync(slug: string): Promise<string> {\n const userAnonymousIdentifier = await getAnonymousIdAsync();\n return `@${ANONYMOUS_USERNAME}/${slug}-${userAnonymousIdentifier}`;\n}\n\nfunction convertToDictionaryItemsRepresentation(obj: { [key: string]: string }): Dictionary {\n return new Map(\n Object.entries(obj).map(([k, v]) => {\n return [k, [v, new Map()]];\n })\n );\n}\n"],"names":["ExpoGoManifestHandlerMiddleware","ResponseContentType","debug","require","ManifestMiddleware","getParsedHeaders","req","platform","parsePlatformHeader","assertRuntimePlatform","accept","accepts","acceptedType","types","responseContentType","expectSignature","headers","String","hostname","stripPort","protocol","getDefaultResponseHeaders","Map","set","_getManifestResponseAsync","requestOptions","exp","hostUri","expoGoConfig","bundleUrl","_resolveProjectSettingsAsync","runtimeVersion","resolveRuntimeVersionWithExpoUpdatesAsync","projectRoot","Updates","getRuntimeVersionAsync","policy","CommandError","codeSigningInfo","getCodeSigningInfoAsync","options","privateKeyPath","easProjectId","extra","eas","projectId","scopeKey","getScopeKeyAsync","slug","expoUpdatesManifest","id","crypto","randomUUID","createdAt","Date","toISOString","launchAsset","key","contentType","url","assets","metadata","undefined","expoClient","expoGo","stringifiedManifest","JSON","stringify","manifestPartHeaders","certificateChainBody","signature","signManifestString","serializeDictionary","convertToDictionaryItemsRepresentation","keyid","keyId","sig","alg","certificateChainForResponse","join","encoded","encodeFormDataAsync","boundary","body","version","getContentTypeForResponseContentType","Object","entries","forEach","value","fields","name","partHeaders","length","push","encodeMultipartMixed","scopeKeyFromCodeSigningInfo","getAnonymousScopeKeyAsync","userAnonymousIdentifier","getAnonymousIdAsync","ANONYMOUS_USERNAME","obj","map","k","v"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/middleware/ExpoGoManifestHandlerMiddleware.ts"],"sourcesContent":["import { ExpoUpdatesManifest } from '@expo/config';\nimport { Updates } from '@expo/config-plugins';\nimport accepts from 'accepts';\nimport crypto from 'crypto';\nimport { serializeDictionary, Dictionary } from 'structured-headers';\n\nimport { ManifestMiddleware, ManifestRequestInfo } from './ManifestMiddleware';\nimport { assertRuntimePlatform, parsePlatformHeader } from './resolvePlatform';\nimport { resolveRuntimeVersionWithExpoUpdatesAsync } from './resolveRuntimeVersionWithExpoUpdatesAsync';\nimport { ServerHeaders, ServerRequest } from './server.types';\nimport { getAnonymousIdAsync } from '../../../api/user/UserSettings';\nimport { ANONYMOUS_USERNAME } from '../../../api/user/user';\nimport {\n CodeSigningInfo,\n getCodeSigningInfoAsync,\n signManifestString,\n} from '../../../utils/codesigning';\nimport { CommandError } from '../../../utils/errors';\nimport {\n encodeMultipartMixed,\n FormDataField,\n EncodedFormData,\n} from '../../../utils/multipartMixed';\nimport { parseUrl } from '../../../utils/url';\n\nconst debug = require('debug')('expo:start:server:middleware:ExpoGoManifestHandlerMiddleware');\n\nexport enum ResponseContentType {\n TEXT_PLAIN,\n APPLICATION_JSON,\n APPLICATION_EXPO_JSON,\n MULTIPART_MIXED,\n}\n\ninterface ExpoGoManifestRequestInfo extends ManifestRequestInfo {\n responseContentType: ResponseContentType;\n expectSignature: string | null;\n}\n\nexport class ExpoGoManifestHandlerMiddleware extends ManifestMiddleware<ExpoGoManifestRequestInfo> {\n public getParsedHeaders(req: ServerRequest): ExpoGoManifestRequestInfo {\n let platform = parsePlatformHeader(req);\n\n if (!platform) {\n debug(\n `No \"expo-platform\" header or \"platform\" query parameter specified. Falling back to \"ios\".`\n );\n platform = 'ios';\n }\n\n assertRuntimePlatform(platform);\n\n // Expo Updates clients explicitly accept \"multipart/mixed\" responses while browsers implicitly\n // accept them with \"accept: */*\". To make it easier to debug manifest responses by visiting their\n // URLs in a browser, we denote the response as \"text/plain\" if the user agent appears not to be\n // an Expo Updates client.\n const accept = accepts(req);\n const acceptedType = accept.types([\n 'unknown/unknown',\n 'multipart/mixed',\n 'application/json',\n 'application/expo+json',\n 'text/plain',\n ]);\n\n let responseContentType;\n switch (acceptedType) {\n case 'multipart/mixed':\n responseContentType = ResponseContentType.MULTIPART_MIXED;\n break;\n case 'application/json':\n responseContentType = ResponseContentType.APPLICATION_JSON;\n break;\n case 'application/expo+json':\n responseContentType = ResponseContentType.APPLICATION_EXPO_JSON;\n break;\n default:\n responseContentType = ResponseContentType.TEXT_PLAIN;\n break;\n }\n\n const expectSignature = req.headers['expo-expect-signature'];\n\n const requestedUrl = parseUrl(req.headers['host']);\n\n return {\n responseContentType,\n platform,\n expectSignature: expectSignature ? String(expectSignature) : null,\n hostname: requestedUrl?.hostname,\n port: requestedUrl?.port,\n protocol: req.headers['x-forwarded-proto'] as 'http' | 'https' | undefined,\n };\n }\n\n private getDefaultResponseHeaders(): ServerHeaders {\n const headers = new Map<string, number | string | readonly string[]>();\n // set required headers for Expo Updates manifest specification\n headers.set('expo-protocol-version', 0);\n headers.set('expo-sfv-version', 0);\n headers.set('cache-control', 'private, max-age=0');\n return headers;\n }\n\n public async _getManifestResponseAsync(requestOptions: ExpoGoManifestRequestInfo): Promise<{\n body: string;\n version: string;\n headers: ServerHeaders;\n }> {\n const { exp, hostUri, expoGoConfig, bundleUrl } =\n await this._resolveProjectSettingsAsync(requestOptions);\n\n const runtimeVersion =\n (await resolveRuntimeVersionWithExpoUpdatesAsync({\n projectRoot: this.projectRoot,\n platform: requestOptions.platform,\n })) ??\n // if expo-updates can't determine runtime version, fall back to calculation from config-plugin.\n // this happens when expo-updates is installed but runtimeVersion hasn't yet been configured or when\n // expo-updates is not installed.\n (await Updates.getRuntimeVersionAsync(\n this.projectRoot,\n { ...exp, runtimeVersion: exp.runtimeVersion ?? { policy: 'sdkVersion' } },\n requestOptions.platform\n ));\n if (!runtimeVersion) {\n throw new CommandError(\n 'MANIFEST_MIDDLEWARE',\n `Unable to determine runtime version for platform '${requestOptions.platform}'`\n );\n }\n\n const codeSigningInfo = await getCodeSigningInfoAsync(\n exp,\n requestOptions.expectSignature,\n this.options.privateKeyPath\n );\n\n const easProjectId = exp.extra?.eas?.projectId as string | undefined | null;\n const scopeKey = await ExpoGoManifestHandlerMiddleware.getScopeKeyAsync({\n slug: exp.slug,\n codeSigningInfo,\n });\n\n const expoUpdatesManifest: ExpoUpdatesManifest = {\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n runtimeVersion,\n launchAsset: {\n key: 'bundle',\n contentType: 'application/javascript',\n url: bundleUrl,\n },\n assets: [], // assets are not used in development\n metadata: {}, // required for the client to detect that this is an expo-updates manifest\n extra: {\n eas: {\n projectId: easProjectId ?? undefined,\n },\n expoClient: {\n ...exp,\n hostUri,\n },\n expoGo: expoGoConfig,\n scopeKey,\n },\n };\n\n const stringifiedManifest = JSON.stringify(expoUpdatesManifest);\n\n let manifestPartHeaders: { 'expo-signature': string } | null = null;\n let certificateChainBody: string | null = null;\n if (codeSigningInfo) {\n const signature = signManifestString(stringifiedManifest, codeSigningInfo);\n manifestPartHeaders = {\n 'expo-signature': serializeDictionary(\n convertToDictionaryItemsRepresentation({\n keyid: codeSigningInfo.keyId,\n sig: signature,\n alg: 'rsa-v1_5-sha256',\n })\n ),\n };\n certificateChainBody = codeSigningInfo.certificateChainForResponse.join('\\n');\n }\n\n const headers = this.getDefaultResponseHeaders();\n\n switch (requestOptions.responseContentType) {\n case ResponseContentType.MULTIPART_MIXED: {\n const encoded = await this.encodeFormDataAsync({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n });\n headers.set('content-type', `multipart/mixed; boundary=${encoded.boundary}`);\n return {\n body: encoded.body,\n version: runtimeVersion,\n headers,\n };\n }\n case ResponseContentType.APPLICATION_EXPO_JSON:\n case ResponseContentType.APPLICATION_JSON:\n case ResponseContentType.TEXT_PLAIN: {\n headers.set(\n 'content-type',\n ExpoGoManifestHandlerMiddleware.getContentTypeForResponseContentType(\n requestOptions.responseContentType\n )\n );\n if (manifestPartHeaders) {\n Object.entries(manifestPartHeaders).forEach(([key, value]) => {\n headers.set(key, value);\n });\n }\n\n return {\n body: stringifiedManifest,\n version: runtimeVersion,\n headers,\n };\n }\n }\n }\n\n private static getContentTypeForResponseContentType(\n responseContentType: ResponseContentType\n ): string {\n switch (responseContentType) {\n case ResponseContentType.MULTIPART_MIXED:\n return 'multipart/mixed';\n case ResponseContentType.APPLICATION_EXPO_JSON:\n return 'application/expo+json';\n case ResponseContentType.APPLICATION_JSON:\n return 'application/json';\n case ResponseContentType.TEXT_PLAIN:\n return 'text/plain';\n }\n }\n\n private encodeFormDataAsync({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n }: {\n stringifiedManifest: string;\n manifestPartHeaders: { 'expo-signature': string } | null;\n certificateChainBody: string | null;\n }): Promise<EncodedFormData> {\n const fields: FormDataField[] = [\n {\n name: 'manifest',\n value: stringifiedManifest,\n contentType: 'application/json',\n partHeaders: manifestPartHeaders,\n },\n ];\n if (certificateChainBody && certificateChainBody.length > 0) {\n fields.push({\n name: 'certificate_chain',\n value: certificateChainBody,\n contentType: 'application/x-pem-file',\n });\n }\n return encodeMultipartMixed(fields);\n }\n\n private static async getScopeKeyAsync({\n slug,\n codeSigningInfo,\n }: {\n slug: string;\n codeSigningInfo: CodeSigningInfo | null;\n }): Promise<string> {\n const scopeKeyFromCodeSigningInfo = codeSigningInfo?.scopeKey;\n if (scopeKeyFromCodeSigningInfo) {\n return scopeKeyFromCodeSigningInfo;\n }\n\n // Log.warn(\n // env.EXPO_OFFLINE\n // ? 'Using anonymous scope key in manifest for offline mode.'\n // : 'Using anonymous scope key in manifest.'\n // );\n return await getAnonymousScopeKeyAsync(slug);\n }\n}\n\nasync function getAnonymousScopeKeyAsync(slug: string): Promise<string> {\n const userAnonymousIdentifier = await getAnonymousIdAsync();\n return `@${ANONYMOUS_USERNAME}/${slug}-${userAnonymousIdentifier}`;\n}\n\nfunction convertToDictionaryItemsRepresentation(obj: { [key: string]: string }): Dictionary {\n return new Map(\n Object.entries(obj).map(([k, v]) => {\n return [k, [v, new Map()]];\n })\n );\n}\n"],"names":["ExpoGoManifestHandlerMiddleware","ResponseContentType","debug","require","ManifestMiddleware","getParsedHeaders","req","platform","parsePlatformHeader","assertRuntimePlatform","accept","accepts","acceptedType","types","responseContentType","expectSignature","headers","requestedUrl","parseUrl","String","hostname","port","protocol","getDefaultResponseHeaders","Map","set","_getManifestResponseAsync","requestOptions","exp","hostUri","expoGoConfig","bundleUrl","_resolveProjectSettingsAsync","runtimeVersion","resolveRuntimeVersionWithExpoUpdatesAsync","projectRoot","Updates","getRuntimeVersionAsync","policy","CommandError","codeSigningInfo","getCodeSigningInfoAsync","options","privateKeyPath","easProjectId","extra","eas","projectId","scopeKey","getScopeKeyAsync","slug","expoUpdatesManifest","id","crypto","randomUUID","createdAt","Date","toISOString","launchAsset","key","contentType","url","assets","metadata","undefined","expoClient","expoGo","stringifiedManifest","JSON","stringify","manifestPartHeaders","certificateChainBody","signature","signManifestString","serializeDictionary","convertToDictionaryItemsRepresentation","keyid","keyId","sig","alg","certificateChainForResponse","join","encoded","encodeFormDataAsync","boundary","body","version","getContentTypeForResponseContentType","Object","entries","forEach","value","fields","name","partHeaders","length","push","encodeMultipartMixed","scopeKeyFromCodeSigningInfo","getAnonymousScopeKeyAsync","userAnonymousIdentifier","getAnonymousIdAsync","ANONYMOUS_USERNAME","obj","map","k","v"],"mappings":"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"}
|
|
@@ -140,7 +140,7 @@ class ManifestMiddleware extends _ExpoMiddleware.ExpoMiddleware {
|
|
|
140
140
|
this.initialProjectConfig = (0, _config().getConfig)(projectRoot);
|
|
141
141
|
this.platformBundlers = (0, _platformBundlers.getPlatformBundlers)(projectRoot, this.initialProjectConfig.exp);
|
|
142
142
|
}
|
|
143
|
-
/** Exposed for testing. */ async _resolveProjectSettingsAsync({ platform, hostname, protocol }) {
|
|
143
|
+
/** Exposed for testing. */ async _resolveProjectSettingsAsync({ platform, hostname, protocol, port }) {
|
|
144
144
|
var _projectConfig_exp_experiments;
|
|
145
145
|
// Read the config
|
|
146
146
|
const projectConfig = (0, _config().getConfig)(this.projectRoot);
|
|
@@ -153,11 +153,13 @@ class ManifestMiddleware extends _ExpoMiddleware.ExpoMiddleware {
|
|
|
153
153
|
// Create the manifest and set fields within it
|
|
154
154
|
const expoGoConfig = this.getExpoGoConfig({
|
|
155
155
|
mainModuleName,
|
|
156
|
-
hostname
|
|
156
|
+
hostname,
|
|
157
|
+
port
|
|
157
158
|
});
|
|
158
159
|
const hostUri = this.options.constructUrl({
|
|
159
|
-
scheme:
|
|
160
|
-
hostname
|
|
160
|
+
scheme: protocol,
|
|
161
|
+
hostname,
|
|
162
|
+
port
|
|
161
163
|
});
|
|
162
164
|
const bundleUrl = this._getBundleUrl({
|
|
163
165
|
platform,
|
|
@@ -168,7 +170,8 @@ class ManifestMiddleware extends _ExpoMiddleware.ExpoMiddleware {
|
|
|
168
170
|
asyncRoutes: (0, _metroOptions.getAsyncRoutesFromExpoConfig)(projectConfig.exp, this.options.mode ?? 'development', platform),
|
|
169
171
|
routerRoot: (0, _router.getRouterDirectoryModuleIdWithManifest)(this.projectRoot, projectConfig.exp),
|
|
170
172
|
protocol,
|
|
171
|
-
reactCompiler: !!((_projectConfig_exp_experiments = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments.reactCompiler)
|
|
173
|
+
reactCompiler: !!((_projectConfig_exp_experiments = projectConfig.exp.experiments) == null ? void 0 : _projectConfig_exp_experiments.reactCompiler),
|
|
174
|
+
port
|
|
172
175
|
});
|
|
173
176
|
// Resolve all assets and set them on the manifest as URLs
|
|
174
177
|
await this.mutateManifestWithAssetsAsync(projectConfig.exp, bundleUrl);
|
|
@@ -200,7 +203,7 @@ class ManifestMiddleware extends _ExpoMiddleware.ExpoMiddleware {
|
|
|
200
203
|
await _devices.saveDevicesAsync(this.projectRoot, deviceIds).catch((e)=>_log.exception(e));
|
|
201
204
|
}
|
|
202
205
|
}
|
|
203
|
-
/** Create the bundle URL (points to the single JS entry file). Exposed for testing. */ _getBundleUrl({ platform, mainModuleName, hostname, engine, baseUrl, isExporting, asyncRoutes, routerRoot, protocol, reactCompiler }) {
|
|
206
|
+
/** Create the bundle URL (points to the single JS entry file). Exposed for testing. */ _getBundleUrl({ platform, mainModuleName, hostname, engine, baseUrl, isExporting, asyncRoutes, routerRoot, protocol, reactCompiler, port }) {
|
|
204
207
|
const path = (0, _metroOptions.createBundleUrlPath)({
|
|
205
208
|
mode: this.options.mode ?? 'development',
|
|
206
209
|
minify: this.options.minify,
|
|
@@ -218,15 +221,17 @@ class ManifestMiddleware extends _ExpoMiddleware.ExpoMiddleware {
|
|
|
218
221
|
return this.options.constructUrl({
|
|
219
222
|
scheme: protocol ?? 'http',
|
|
220
223
|
// hostType: this.options.location.hostType,
|
|
221
|
-
hostname
|
|
224
|
+
hostname,
|
|
225
|
+
port
|
|
222
226
|
}) + path;
|
|
223
227
|
}
|
|
224
|
-
getExpoGoConfig({ mainModuleName, hostname }) {
|
|
228
|
+
getExpoGoConfig({ mainModuleName, hostname, port }) {
|
|
225
229
|
return {
|
|
226
230
|
// localhost:8081
|
|
227
231
|
debuggerHost: this.options.constructUrl({
|
|
228
232
|
scheme: '',
|
|
229
|
-
hostname
|
|
233
|
+
hostname,
|
|
234
|
+
port
|
|
230
235
|
}),
|
|
231
236
|
// Required for Expo Go to function.
|
|
232
237
|
developer: {
|