@expo/cli 55.0.5 → 55.0.7

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.
Files changed (28) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/api/user/actions.js +5 -2
  3. package/build/src/api/user/actions.js.map +1 -1
  4. package/build/src/api/user/expoSsoLauncher.js +22 -49
  5. package/build/src/api/user/expoSsoLauncher.js.map +1 -1
  6. package/build/src/api/user/user.js +6 -5
  7. package/build/src/api/user/user.js.map +1 -1
  8. package/build/src/login/index.js +6 -2
  9. package/build/src/login/index.js.map +1 -1
  10. package/build/src/start/platforms/android/AndroidSdk.js +15 -6
  11. package/build/src/start/platforms/android/AndroidSdk.js.map +1 -1
  12. package/build/src/start/platforms/ios/devicectl.js +4 -1
  13. package/build/src/start/platforms/ios/devicectl.js.map +1 -1
  14. package/build/src/start/server/metro/MetroBundlerDevServer.js +1 -0
  15. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  16. package/build/src/start/server/metro/debugging/createDebugMiddleware.js +5 -1
  17. package/build/src/start/server/metro/debugging/createDebugMiddleware.js.map +1 -1
  18. package/build/src/start/server/metro/instantiateMetro.js +10 -5
  19. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  20. package/build/src/start/server/webpack/WebpackBundlerDevServer.js +2 -1
  21. package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
  22. package/build/src/utils/downloadExpoGoAsync.js +36 -0
  23. package/build/src/utils/downloadExpoGoAsync.js.map +1 -1
  24. package/build/src/utils/env.js +13 -11
  25. package/build/src/utils/env.js.map +1 -1
  26. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  27. package/build/src/utils/telemetry/utils/context.js +1 -1
  28. package/package.json +9 -9
@@ -42,7 +42,11 @@ function createDebugMiddleware({ serverBaseUrl, reporter }) {
42
42
  enableNetworkInspector: true,
43
43
  // Only enable opening the browser version of React Native DevTools when debugging.
44
44
  // This is useful when debugging the React Native DevTools by going to `/open-debugger` in the browser.
45
- enableOpenDebuggerRedirect: _env.env.EXPO_DEBUG
45
+ enableOpenDebuggerRedirect: _env.env.EXPO_DEBUG,
46
+ // The standalone fusebox shell (@react-native/debugger-shell) starts installing almost
47
+ // immediately in the background when the dev middleware is created, which we don't
48
+ // always want to happen
49
+ enableStandaloneFuseboxShell: !(0, _env.envIsHeadless)()
46
50
  }
47
51
  });
48
52
  const debuggerWebsocketEndpoint = websocketEndpoints['/inspector/debug'];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/start/server/metro/debugging/createDebugMiddleware.ts"],"sourcesContent":["import type { NextHandleFunction } from 'connect';\nimport { WebSocketServer } from 'ws';\n\nimport { createHandlersFactory } from './createHandlersFactory';\nimport { env } from '../../../../utils/env';\nimport { isLocalSocket, isMatchingOrigin } from '../../../../utils/net';\nimport { TerminalReporter } from '../TerminalReporter';\nimport { NETWORK_RESPONSE_STORAGE } from './messageHandlers/NetworkResponse';\n\nconst debug = require('debug')('expo:metro:debugging:middleware') as typeof console.log;\n\ninterface DebugMiddleware {\n debugMiddleware: NextHandleFunction;\n debugWebsocketEndpoints: Record<string, WebSocketServer>;\n}\n\ninterface DebugMiddlewareParams {\n serverBaseUrl: string;\n reporter: TerminalReporter;\n}\n\nexport function createDebugMiddleware({\n serverBaseUrl,\n reporter,\n}: DebugMiddlewareParams): DebugMiddleware {\n // Load the React Native debugging tools from project\n // TODO: check if this works with isolated modules\n const { createDevMiddleware } =\n require('@react-native/dev-middleware') as typeof import('@react-native/dev-middleware');\n\n const { middleware, websocketEndpoints } = createDevMiddleware({\n // TODO: Check with cedric why this can be removed\n // https://github.com/facebook/react-native/pull/53921\n // projectRoot: metroBundler.projectRoot,\n serverBaseUrl,\n logger: createLogger(reporter),\n unstable_customInspectorMessageHandler: createHandlersFactory(),\n // TODO: Forward all events to the shared Metro log reporter. Do this when we have opinions on how all logs should be presented.\n // unstable_eventReporter: {\n // logEvent(event) {\n // reporter.update(event);\n // },\n // },\n unstable_experiments: {\n // Enable the Network tab in React Native DevTools\n enableNetworkInspector: true,\n // Only enable opening the browser version of React Native DevTools when debugging.\n // This is useful when debugging the React Native DevTools by going to `/open-debugger` in the browser.\n enableOpenDebuggerRedirect: env.EXPO_DEBUG,\n },\n });\n\n const debuggerWebsocketEndpoint = websocketEndpoints['/inspector/debug'] as WebSocketServer;\n\n // NOTE(cedric): add a temporary websocket to handle Network-related CDP events\n websocketEndpoints['/inspector/network'] = createNetworkWebsocket(debuggerWebsocketEndpoint);\n\n // Explicitly limit debugger websocket to loopback requests\n debuggerWebsocketEndpoint.on('connection', (socket, request) => {\n if (!isLocalSocket(request.socket) || !isMatchingOrigin(request, serverBaseUrl)) {\n // NOTE: `socket.close` nicely closes the websocket, which will still allow incoming messages\n // `socket.terminate` instead forcefully closes down the socket\n socket.terminate();\n }\n });\n\n return {\n debugMiddleware(req, res, next) {\n // The debugger middleware is skipped entirely if the connection isn't a loopback request\n if (isLocalSocket(req.socket)) {\n return middleware(req, res, next);\n } else {\n return next();\n }\n },\n debugWebsocketEndpoints: websocketEndpoints,\n };\n}\n\nfunction createLogger(\n reporter: TerminalReporter\n): Parameters<typeof import('@react-native/dev-middleware').createDevMiddleware>[0]['logger'] {\n return {\n info: makeLogger(reporter, 'info'),\n warn: makeLogger(reporter, 'warn'),\n error: makeLogger(reporter, 'error'),\n };\n}\n\nfunction makeLogger(reporter: TerminalReporter, level: 'info' | 'warn' | 'error') {\n return (...data: any[]) =>\n reporter.update({\n type: 'unstable_server_log',\n level,\n data,\n });\n}\n\n/**\n * This adds a dedicated websocket connection that handles Network-related CDP events.\n * It's a temporary solution until Fusebox either implements the Network CDP domain,\n * or allows external domain agents that can send messages over the CDP socket to the debugger.\n * The Network websocket rebroadcasts events on the debugger CDP connections.\n */\nfunction createNetworkWebsocket(debuggerWebsocket: WebSocketServer) {\n const wss = new WebSocketServer({\n noServer: true,\n perMessageDeflate: true,\n // Don't crash on exceptionally large messages - assume the device is\n // well-behaved and the debugger is prepared to handle large messages.\n maxPayload: 0,\n });\n\n wss.on('connection', (networkSocket) => {\n networkSocket.on('message', (data) => {\n try {\n // Parse the network message, to determine how the message should be handled\n const message = JSON.parse(data.toString());\n\n if (message.method === 'Expo(Network.receivedResponseBody)' && message.params) {\n // If its a response body, write it to the global storage\n const { requestId, ...requestInfo } = message.params;\n NETWORK_RESPONSE_STORAGE.set(requestId, requestInfo);\n } else if (message.method.startsWith('Network.')) {\n // Otherwise, directly re-broadcast the Network events to all connected debuggers\n debuggerWebsocket.clients.forEach((debuggerSocket) => {\n if (debuggerSocket.readyState === debuggerSocket.OPEN) {\n debuggerSocket.send(data.toString());\n }\n });\n }\n } catch (error) {\n debug('Failed to handle Network CDP event', error);\n }\n });\n });\n\n return wss;\n}\n"],"names":["createDebugMiddleware","debug","require","serverBaseUrl","reporter","createDevMiddleware","middleware","websocketEndpoints","logger","createLogger","unstable_customInspectorMessageHandler","createHandlersFactory","unstable_experiments","enableNetworkInspector","enableOpenDebuggerRedirect","env","EXPO_DEBUG","debuggerWebsocketEndpoint","createNetworkWebsocket","on","socket","request","isLocalSocket","isMatchingOrigin","terminate","debugMiddleware","req","res","next","debugWebsocketEndpoints","info","makeLogger","warn","error","level","data","update","type","debuggerWebsocket","wss","WebSocketServer","noServer","perMessageDeflate","maxPayload","networkSocket","message","JSON","parse","toString","method","params","requestId","requestInfo","NETWORK_RESPONSE_STORAGE","set","startsWith","clients","forEach","debuggerSocket","readyState","OPEN","send"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../src/start/server/metro/debugging/createDebugMiddleware.ts"],"sourcesContent":["import type { NextHandleFunction } from 'connect';\nimport { WebSocketServer } from 'ws';\n\nimport { createHandlersFactory } from './createHandlersFactory';\nimport { env, envIsHeadless } from '../../../../utils/env';\nimport { isLocalSocket, isMatchingOrigin } from '../../../../utils/net';\nimport { TerminalReporter } from '../TerminalReporter';\nimport { NETWORK_RESPONSE_STORAGE } from './messageHandlers/NetworkResponse';\n\nconst debug = require('debug')('expo:metro:debugging:middleware') as typeof console.log;\n\ninterface DebugMiddleware {\n debugMiddleware: NextHandleFunction;\n debugWebsocketEndpoints: Record<string, WebSocketServer>;\n}\n\ninterface DebugMiddlewareParams {\n serverBaseUrl: string;\n reporter: TerminalReporter;\n}\n\nexport function createDebugMiddleware({\n serverBaseUrl,\n reporter,\n}: DebugMiddlewareParams): DebugMiddleware {\n // Load the React Native debugging tools from project\n // TODO: check if this works with isolated modules\n const { createDevMiddleware } =\n require('@react-native/dev-middleware') as typeof import('@react-native/dev-middleware');\n\n const { middleware, websocketEndpoints } = createDevMiddleware({\n // TODO: Check with cedric why this can be removed\n // https://github.com/facebook/react-native/pull/53921\n // projectRoot: metroBundler.projectRoot,\n serverBaseUrl,\n logger: createLogger(reporter),\n unstable_customInspectorMessageHandler: createHandlersFactory(),\n // TODO: Forward all events to the shared Metro log reporter. Do this when we have opinions on how all logs should be presented.\n // unstable_eventReporter: {\n // logEvent(event) {\n // reporter.update(event);\n // },\n // },\n unstable_experiments: {\n // Enable the Network tab in React Native DevTools\n enableNetworkInspector: true,\n // Only enable opening the browser version of React Native DevTools when debugging.\n // This is useful when debugging the React Native DevTools by going to `/open-debugger` in the browser.\n enableOpenDebuggerRedirect: env.EXPO_DEBUG,\n // The standalone fusebox shell (@react-native/debugger-shell) starts installing almost\n // immediately in the background when the dev middleware is created, which we don't\n // always want to happen\n enableStandaloneFuseboxShell: !envIsHeadless(),\n },\n });\n\n const debuggerWebsocketEndpoint = websocketEndpoints['/inspector/debug'] as WebSocketServer;\n\n // NOTE(cedric): add a temporary websocket to handle Network-related CDP events\n websocketEndpoints['/inspector/network'] = createNetworkWebsocket(debuggerWebsocketEndpoint);\n\n // Explicitly limit debugger websocket to loopback requests\n debuggerWebsocketEndpoint.on('connection', (socket, request) => {\n if (!isLocalSocket(request.socket) || !isMatchingOrigin(request, serverBaseUrl)) {\n // NOTE: `socket.close` nicely closes the websocket, which will still allow incoming messages\n // `socket.terminate` instead forcefully closes down the socket\n socket.terminate();\n }\n });\n\n return {\n debugMiddleware(req, res, next) {\n // The debugger middleware is skipped entirely if the connection isn't a loopback request\n if (isLocalSocket(req.socket)) {\n return middleware(req, res, next);\n } else {\n return next();\n }\n },\n debugWebsocketEndpoints: websocketEndpoints,\n };\n}\n\nfunction createLogger(\n reporter: TerminalReporter\n): Parameters<typeof import('@react-native/dev-middleware').createDevMiddleware>[0]['logger'] {\n return {\n info: makeLogger(reporter, 'info'),\n warn: makeLogger(reporter, 'warn'),\n error: makeLogger(reporter, 'error'),\n };\n}\n\nfunction makeLogger(reporter: TerminalReporter, level: 'info' | 'warn' | 'error') {\n return (...data: any[]) =>\n reporter.update({\n type: 'unstable_server_log',\n level,\n data,\n });\n}\n\n/**\n * This adds a dedicated websocket connection that handles Network-related CDP events.\n * It's a temporary solution until Fusebox either implements the Network CDP domain,\n * or allows external domain agents that can send messages over the CDP socket to the debugger.\n * The Network websocket rebroadcasts events on the debugger CDP connections.\n */\nfunction createNetworkWebsocket(debuggerWebsocket: WebSocketServer) {\n const wss = new WebSocketServer({\n noServer: true,\n perMessageDeflate: true,\n // Don't crash on exceptionally large messages - assume the device is\n // well-behaved and the debugger is prepared to handle large messages.\n maxPayload: 0,\n });\n\n wss.on('connection', (networkSocket) => {\n networkSocket.on('message', (data) => {\n try {\n // Parse the network message, to determine how the message should be handled\n const message = JSON.parse(data.toString());\n\n if (message.method === 'Expo(Network.receivedResponseBody)' && message.params) {\n // If its a response body, write it to the global storage\n const { requestId, ...requestInfo } = message.params;\n NETWORK_RESPONSE_STORAGE.set(requestId, requestInfo);\n } else if (message.method.startsWith('Network.')) {\n // Otherwise, directly re-broadcast the Network events to all connected debuggers\n debuggerWebsocket.clients.forEach((debuggerSocket) => {\n if (debuggerSocket.readyState === debuggerSocket.OPEN) {\n debuggerSocket.send(data.toString());\n }\n });\n }\n } catch (error) {\n debug('Failed to handle Network CDP event', error);\n }\n });\n });\n\n return wss;\n}\n"],"names":["createDebugMiddleware","debug","require","serverBaseUrl","reporter","createDevMiddleware","middleware","websocketEndpoints","logger","createLogger","unstable_customInspectorMessageHandler","createHandlersFactory","unstable_experiments","enableNetworkInspector","enableOpenDebuggerRedirect","env","EXPO_DEBUG","enableStandaloneFuseboxShell","envIsHeadless","debuggerWebsocketEndpoint","createNetworkWebsocket","on","socket","request","isLocalSocket","isMatchingOrigin","terminate","debugMiddleware","req","res","next","debugWebsocketEndpoints","info","makeLogger","warn","error","level","data","update","type","debuggerWebsocket","wss","WebSocketServer","noServer","perMessageDeflate","maxPayload","networkSocket","message","JSON","parse","toString","method","params","requestId","requestInfo","NETWORK_RESPONSE_STORAGE","set","startsWith","clients","forEach","debuggerSocket","readyState","OPEN","send"],"mappings":"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"}
@@ -129,7 +129,12 @@ const terminal = new LogRespectingTerminal(process.stdout);
129
129
  async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, getMetroBundler }) {
130
130
  var _exp_experiments, _exp_experiments1, _exp_experiments2, _exp_experiments3, _config_resolver, _exp_experiments4, _exp_experiments5, _exp_experiments6;
131
131
  let reportEvent;
132
- const autolinkingModuleResolutionEnabled = ((_exp_experiments = exp.experiments) == null ? void 0 : _exp_experiments.autolinkingModuleResolution) ?? _env.env.EXPO_USE_STICKY_RESOLVER;
132
+ // We're resolving a monorepo root, higher up than the `projectRoot`. If this
133
+ // folder is different (presumably a parent) we're in a monorepo
134
+ const serverRoot = (0, _paths().getMetroServerRoot)(projectRoot);
135
+ const isWorkspace = serverRoot !== projectRoot;
136
+ // Autolinking Module Resolution will be enabled by default when we're in a monorepo
137
+ const autolinkingModuleResolutionEnabled = ((_exp_experiments = exp.experiments) == null ? void 0 : _exp_experiments.autolinkingModuleResolution) ?? isWorkspace;
133
138
  const serverActionsEnabled = ((_exp_experiments1 = exp.experiments) == null ? void 0 : _exp_experiments1.reactServerFunctions) ?? _env.env.EXPO_UNSTABLE_SERVER_FUNCTIONS;
134
139
  if (serverActionsEnabled) {
135
140
  process.env.EXPO_UNSTABLE_SERVER_FUNCTIONS = '1';
@@ -141,7 +146,6 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
141
146
  if ((_exp_experiments3 = exp.experiments) == null ? void 0 : _exp_experiments3.reactCanary) {
142
147
  _log.Log.warn(`React 19 is enabled by default. Remove unused experiments.reactCanary flag.`);
143
148
  }
144
- const serverRoot = (0, _paths().getMetroServerRoot)(projectRoot);
145
149
  const terminalReporter = new _MetroTerminalReporter.MetroTerminalReporter(serverRoot, terminal);
146
150
  // NOTE: Allow external tools to override the metro config. This is considered internal and unstable
147
151
  const configPath = _env.env.EXPO_OVERRIDE_METRO_CONFIG ?? undefined;
@@ -185,6 +189,9 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
185
189
  if ((_exp_experiments4 = exp.experiments) == null ? void 0 : _exp_experiments4.reactCompiler) {
186
190
  _log.Log.log(_chalk().default.gray`React Compiler enabled`);
187
191
  }
192
+ if (autolinkingModuleResolutionEnabled) {
193
+ _log.Log.log(_chalk().default.gray`Expo Autolinking module resolution enabled`);
194
+ }
188
195
  if (_env.env.EXPO_UNSTABLE_TREE_SHAKING && !_env.env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {
189
196
  throw new _errors.CommandError('EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.');
190
197
  }
@@ -197,9 +204,6 @@ async function loadMetroConfigAsync(projectRoot, options, { exp, isExporting, ge
197
204
  if (_env.env.EXPO_UNSTABLE_LOG_BOX) {
198
205
  _log.Log.warn(`Experimental Expo LogBox is enabled.`);
199
206
  }
200
- if (autolinkingModuleResolutionEnabled) {
201
- _log.Log.warn(`Experimental Expo Autolinking module resolver is enabled.`);
202
- }
203
207
  if (serverActionsEnabled) {
204
208
  var _exp_experiments8;
205
209
  _log.Log.warn(`React Server Functions (beta) are enabled. Route rendering mode: ${((_exp_experiments8 = exp.experiments) == null ? void 0 : _exp_experiments8.reactServerComponentRoutes) ? 'server' : 'client'}`);
@@ -274,6 +278,7 @@ async function instantiateMetroAsync(metroBundler, options, { isExporting, exp =
274
278
  resetAtlasFile: isExporting
275
279
  });
276
280
  const { server, hmrServer, metro } = await (0, _runServerfork.runServer)(metroBundler, metroConfig, {
281
+ host: options.host,
277
282
  websocketEndpoints,
278
283
  watch: !isExporting && isWatchEnabled()
279
284
  }, {
@@ -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();\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 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 // We're resolving a monorepo root, higher up than the `projectRoot`. If this\n // folder is different (presumably a parent) we're in a monorepo\n const serverRoot = getMetroServerRoot(projectRoot);\n const isWorkspace = serverRoot !== projectRoot;\n\n // Autolinking Module Resolution will be enabled by default when we're in a monorepo\n const autolinkingModuleResolutionEnabled =\n exp.experiments?.autolinkingModuleResolution ?? isWorkspace;\n\n const serverActionsEnabled =\n exp.experiments?.reactServerFunctions ?? env.EXPO_UNSTABLE_SERVER_FUNCTIONS;\n\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 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 (autolinkingModuleResolutionEnabled) {\n Log.log(chalk.gray`Expo Autolinking module resolution enabled`);\n }\n\n if (env.EXPO_UNSTABLE_TREE_SHAKING && !env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH) {\n throw new CommandError(\n 'EXPO_UNSTABLE_TREE_SHAKING requires EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH to be enabled.'\n );\n }\n\n if (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\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\ninterface InstantiateMetroConfigOptions extends LoadMetroConfigOptions {\n host?: string;\n}\n\n/** The most generic possible setup for Metro bundler. */\nexport async function instantiateMetroAsync(\n metroBundler: MetroBundlerDevServer,\n options: InstantiateMetroConfigOptions,\n {\n isExporting,\n exp = getConfig(metroBundler.projectRoot, {\n skipSDKVersionRequirement: true,\n }).exp,\n }: { isExporting: boolean; exp?: ExpoConfig }\n): Promise<{\n metro: MetroServer;\n hmrServer: MetroHmrServer<MetroHmrClient> | null;\n server: http.Server;\n middleware: any;\n messageSocket: MessageSocket;\n}> {\n const projectRoot = metroBundler.projectRoot;\n\n const {\n config: metroConfig,\n setEventReporter,\n reporter,\n } = await loadMetroConfigAsync(projectRoot, options, {\n exp,\n isExporting,\n getMetroBundler() {\n return metro.getBundler().getBundler();\n },\n });\n\n // Create the core middleware stack for Metro, including websocket listeners\n const { middleware, messagesSocket, eventsSocket, websocketEndpoints } =\n createMetroMiddleware(metroConfig);\n\n // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)\n const serverBaseUrl = metroBundler\n .getUrlCreator()\n .constructUrl({ scheme: 'http', hostType: 'localhost' });\n\n if (!isExporting) {\n // Enable correct CORS headers for Expo Router features\n prependMiddleware(middleware, createCorsMiddleware(exp));\n\n // Enable debug middleware for CDP-related debugging\n const { debugMiddleware, debugWebsocketEndpoints } = createDebugMiddleware({\n serverBaseUrl,\n reporter,\n });\n Object.assign(websocketEndpoints, debugWebsocketEndpoints);\n middleware.use(debugMiddleware);\n middleware.use('/_expo/debugger', createJsInspectorMiddleware());\n\n // TODO(cedric): `enhanceMiddleware` is deprecated, but is currently used to unify the middleware stacks\n // See: https://github.com/facebook/metro/commit/22e85fde85ec454792a1b70eba4253747a2587a9\n // See: https://github.com/facebook/metro/commit/d0d554381f119bb80ab09dbd6a1d310b54737e52\n const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware;\n asWritable(metroConfig.server).enhanceMiddleware = (\n metroMiddleware: any,\n server: MetroServer\n ) => {\n if (customEnhanceMiddleware) {\n metroMiddleware = customEnhanceMiddleware(metroMiddleware, server);\n }\n return middleware.use(metroMiddleware);\n };\n\n const devtoolsWebsocketEndpoints = createDevToolsPluginWebsocketEndpoint();\n Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);\n }\n\n // Attach Expo Atlas if enabled\n await attachAtlasAsync({\n isExporting,\n exp,\n projectRoot,\n middleware,\n metroConfig,\n // NOTE(cedric): reset the Atlas file once, and reuse it for static exports\n resetAtlasFile: isExporting,\n });\n\n const { server, hmrServer, metro } = await runServer(\n metroBundler,\n metroConfig,\n {\n host: options.host,\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","serverRoot","getMetroServerRoot","isWorkspace","autolinkingModuleResolutionEnabled","experiments","autolinkingModuleResolution","serverActionsEnabled","reactServerFunctions","env","EXPO_UNSTABLE_SERVER_FUNCTIONS","reactServerComponentRoutes","EXPO_USE_METRO_REQUIRE","reactCanary","Log","warn","terminalReporter","MetroTerminalReporter","configPath","EXPO_OVERRIDE_METRO_CONFIG","undefined","resolvedConfig","resolveConfig","defaultConfig","getDefaultConfig","isEmpty","mergeConfig","resetCache","maxWorkers","server","port","watchFolders","includes","reporter","update","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","host","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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"}
@@ -221,8 +221,9 @@ class WebpackBundlerDevServer extends _BundlerDevServer.BundlerDevServer {
221
221
  // Create a webpack compiler that is configured with custom messages.
222
222
  const compiler = webpack(config);
223
223
  const server = new WebpackDevServer(compiler, config.devServer);
224
+ const host = _env.env.WEB_HOST ?? (options.location.hostType === 'localhost' ? 'localhost' : undefined);
224
225
  // Launch WebpackDevServer.
225
- server.listen(port, _env.env.WEB_HOST, function(error) {
226
+ server.listen(port, host, function(error) {
226
227
  if (error) {
227
228
  _log.error(error.message);
228
229
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/webpack/WebpackBundlerDevServer.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { Application } from 'express';\nimport fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\nimport type webpack from 'webpack';\nimport type WebpackDevServer from 'webpack-dev-server';\n\nimport { compileAsync } from './compile';\nimport {\n importExpoWebpackConfigFromProject,\n importWebpackDevServerFromProject,\n importWebpackFromProject,\n} from './resolveFromProject';\nimport { ensureEnvironmentSupportsTLSAsync } from './tls';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { getIpAddress } from '../../../utils/ip';\nimport { setNodeEnv } from '../../../utils/nodeEnv';\nimport { choosePortAsync } from '../../../utils/port';\nimport { createProgressBar } from '../../../utils/progress';\nimport { ensureDotExpoProjectDirectoryInitialized } from '../../project/dotExpo';\nimport { BundlerDevServer, BundlerStartOptions, DevServerInstance } from '../BundlerDevServer';\n\nconst debug = require('debug')('expo:start:server:webpack:devServer') as typeof console.log;\n\nexport type WebpackConfiguration = webpack.Configuration & {\n devServer?: {\n before?: (app: Application, server: WebpackDevServer, compiler: webpack.Compiler) => void;\n };\n};\n\nfunction assertIsWebpackDevServer(value: any): asserts value is WebpackDevServer {\n if (!value?.sockWrite && !value?.sendMessage) {\n throw new CommandError(\n 'WEBPACK',\n value\n ? 'Expected Webpack dev server, found: ' + (value.constructor?.name ?? value)\n : 'Webpack dev server not started yet.'\n );\n }\n}\n\nexport class WebpackBundlerDevServer extends BundlerDevServer {\n get name(): string {\n return 'webpack';\n }\n\n public async startTypeScriptServices(): Promise<void> {\n // noop -- this feature is Metro-only.\n }\n\n public broadcastMessage(\n method: string | 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ): void {\n if (!this.instance) {\n return;\n }\n\n assertIsWebpackDevServer(this.instance?.server);\n\n // TODO(EvanBacon): Custom Webpack overlay.\n // Default webpack-dev-server sockets use \"content-changed\" instead of \"reload\" (what we use on native).\n // For now, just manually convert the value so our CLI interface can be unified.\n const hackyConvertedMessage = method === 'reload' ? 'content-changed' : method;\n\n if (\n 'sendMessage' in this.instance.server &&\n typeof this.instance.server.sendMessage === 'function'\n ) {\n // NOTE: https://github.com/expo/expo/issues/21994#issuecomment-1517122501\n this.instance.server.sendMessage(this.instance.server.sockets, hackyConvertedMessage, params);\n } else {\n this.instance.server.sockWrite(this.instance.server.sockets, hackyConvertedMessage, params);\n }\n }\n\n isTargetingNative(): boolean {\n return false;\n }\n\n private async getAvailablePortAsync(options: { defaultPort?: number }): Promise<number> {\n try {\n const defaultPort = options?.defaultPort ?? 19006;\n const port = await choosePortAsync(this.projectRoot, {\n defaultPort,\n host: env.WEB_HOST,\n });\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', `Port ${defaultPort} not available.`);\n }\n return port;\n } catch (error: any) {\n throw new CommandError('NO_PORT_FOUND', error.message);\n }\n }\n\n async bundleAsync({ mode, clear }: { mode: 'development' | 'production'; clear: boolean }) {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n\n if (clear) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n const config = await this.loadConfigAsync({\n isImageEditingEnabled: true,\n mode,\n });\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n const bar = createProgressBar(chalk`{bold Web} Bundling Javascript [:bar] :percent`, {\n width: 64,\n total: 100,\n clear: true,\n complete: '=',\n incomplete: ' ',\n });\n\n // NOTE(EvanBacon): Add a progress bar to the webpack logger if defined (e.g. not in CI).\n if (bar != null) {\n config.plugins.push(\n new webpack.ProgressPlugin((percent: number) => {\n bar?.update(percent);\n if (percent === 1) {\n bar?.terminate();\n }\n })\n );\n }\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n try {\n await compileAsync(compiler);\n } catch (error: any) {\n Log.error(chalk.red('Failed to compile'));\n throw error;\n } finally {\n bar?.terminate();\n }\n }\n\n protected async startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance> {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n const WebpackDevServer = importWebpackDevServerFromProject(this.projectRoot);\n\n await this.stopAsync();\n\n options.port = await this.getAvailablePortAsync({\n defaultPort: options.port,\n });\n const { resetDevServer, https, port, mode } = options;\n\n this.urlCreator = this.getUrlCreator({\n port,\n location: {\n scheme: https ? 'https' : 'http',\n },\n });\n\n debug('Starting webpack on port: ' + port);\n\n if (resetDevServer) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n if (https) {\n debug('Configuring TLS to enable HTTPS support');\n await ensureEnvironmentSupportsTLSAsync(this.projectRoot).catch((error) => {\n Log.error(`Error creating TLS certificates: ${error}`);\n });\n }\n\n const config = await this.loadConfigAsync(options);\n\n Log.log(chalk`Starting Webpack on port ${port} in {underline ${mode}} mode.`);\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n const server = new WebpackDevServer(compiler, config.devServer);\n // Launch WebpackDevServer.\n server.listen(port, env.WEB_HOST, function (this: http.Server, error) {\n if (error) {\n Log.error(error.message);\n }\n });\n\n // Extend the close method to ensure that we clean up the local info.\n const originalClose = server.close.bind(server);\n\n server.close = (callback?: (err?: Error) => void) => {\n return originalClose((err?: Error) => {\n this.instance = null;\n callback?.(err);\n });\n };\n\n const _host = getIpAddress();\n const protocol = https ? 'https' : 'http';\n\n return {\n // Server instance\n server,\n // URL Info\n location: {\n url: `${protocol}://${_host}:${port}`,\n port,\n protocol,\n host: _host,\n },\n middleware: null,\n // Match the native protocol.\n messageSocket: {\n broadcast: this.broadcastMessage,\n },\n };\n }\n\n /** Load the Webpack config. Exposed for testing. */\n getProjectConfigFilePath(): string | null {\n // Check if the project has a webpack.config.js in the root.\n return (\n this.getConfigModuleIds().reduce<string | null | undefined>(\n (prev, moduleId) => prev || resolveFrom.silent(this.projectRoot, moduleId),\n null\n ) ?? null\n );\n }\n\n async loadConfigAsync(\n options: Pick<BundlerStartOptions, 'mode' | 'isImageEditingEnabled' | 'https'>,\n argv?: string[]\n ): Promise<WebpackConfiguration> {\n // let bar: ProgressBar | null = null;\n\n const env = {\n projectRoot: this.projectRoot,\n pwa: !!options.isImageEditingEnabled,\n // TODO: Use a new loader in Webpack config...\n logger: {\n info() {},\n },\n mode: options.mode,\n https: options.https,\n };\n setNodeEnv(env.mode ?? 'development');\n require('@expo/env').load(env.projectRoot);\n // Check if the project has a webpack.config.js in the root.\n const projectWebpackConfig = this.getProjectConfigFilePath();\n let config: WebpackConfiguration;\n if (projectWebpackConfig) {\n const webpackConfig = require(projectWebpackConfig);\n if (typeof webpackConfig === 'function') {\n config = await webpackConfig(env, argv);\n } else {\n config = webpackConfig;\n }\n } else {\n // Fallback to the default expo webpack config.\n const loadDefaultConfigAsync = importExpoWebpackConfigFromProject(this.projectRoot);\n config = await loadDefaultConfigAsync(env, argv);\n }\n return config;\n }\n\n protected getConfigModuleIds(): string[] {\n return ['./webpack.config.js'];\n }\n\n protected async clearWebProjectCacheAsync(\n projectRoot: string,\n mode: string = 'development'\n ): Promise<void> {\n Log.log(chalk.dim(`Clearing Webpack ${mode} cache directory...`));\n\n const dir = await ensureDotExpoProjectDirectoryInitialized(projectRoot);\n const cacheFolder = path.join(dir, 'web/cache', mode);\n try {\n await fs.promises.rm(cacheFolder, { recursive: true, force: true });\n } catch (error: any) {\n Log.error(`Could not clear ${mode} web cache directory: ${error.message}`);\n }\n }\n}\n\nexport function getProjectWebpackConfigFilePath(projectRoot: string) {\n return resolveFrom.silent(projectRoot, './webpack.config.js');\n}\n"],"names":["WebpackBundlerDevServer","getProjectWebpackConfigFilePath","debug","require","assertIsWebpackDevServer","value","sockWrite","sendMessage","CommandError","constructor","name","BundlerDevServer","startTypeScriptServices","broadcastMessage","method","params","instance","server","hackyConvertedMessage","sockets","isTargetingNative","getAvailablePortAsync","options","defaultPort","port","choosePortAsync","projectRoot","host","env","WEB_HOST","error","message","bundleAsync","mode","clear","webpack","importWebpackFromProject","clearWebProjectCacheAsync","config","loadConfigAsync","isImageEditingEnabled","plugins","bar","createProgressBar","chalk","width","total","complete","incomplete","push","ProgressPlugin","percent","update","terminate","compiler","compileAsync","Log","red","startImplementationAsync","WebpackDevServer","importWebpackDevServerFromProject","stopAsync","resetDevServer","https","urlCreator","getUrlCreator","location","scheme","ensureEnvironmentSupportsTLSAsync","catch","log","devServer","listen","originalClose","close","bind","callback","err","_host","getIpAddress","protocol","url","middleware","messageSocket","broadcast","getProjectConfigFilePath","getConfigModuleIds","reduce","prev","moduleId","resolveFrom","silent","argv","pwa","logger","info","setNodeEnv","load","projectWebpackConfig","webpackConfig","loadDefaultConfigAsync","importExpoWebpackConfigFromProject","dim","dir","ensureDotExpoProjectDirectoryInitialized","cacheFolder","path","join","fs","promises","rm","recursive","force"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/webpack/WebpackBundlerDevServer.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { Application } from 'express';\nimport fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\nimport type webpack from 'webpack';\nimport type WebpackDevServer from 'webpack-dev-server';\n\nimport { compileAsync } from './compile';\nimport {\n importExpoWebpackConfigFromProject,\n importWebpackDevServerFromProject,\n importWebpackFromProject,\n} from './resolveFromProject';\nimport { ensureEnvironmentSupportsTLSAsync } from './tls';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { getIpAddress } from '../../../utils/ip';\nimport { setNodeEnv } from '../../../utils/nodeEnv';\nimport { choosePortAsync } from '../../../utils/port';\nimport { createProgressBar } from '../../../utils/progress';\nimport { ensureDotExpoProjectDirectoryInitialized } from '../../project/dotExpo';\nimport { BundlerDevServer, BundlerStartOptions, DevServerInstance } from '../BundlerDevServer';\n\nconst debug = require('debug')('expo:start:server:webpack:devServer') as typeof console.log;\n\nexport type WebpackConfiguration = webpack.Configuration & {\n devServer?: {\n before?: (app: Application, server: WebpackDevServer, compiler: webpack.Compiler) => void;\n };\n};\n\nfunction assertIsWebpackDevServer(value: any): asserts value is WebpackDevServer {\n if (!value?.sockWrite && !value?.sendMessage) {\n throw new CommandError(\n 'WEBPACK',\n value\n ? 'Expected Webpack dev server, found: ' + (value.constructor?.name ?? value)\n : 'Webpack dev server not started yet.'\n );\n }\n}\n\nexport class WebpackBundlerDevServer extends BundlerDevServer {\n get name(): string {\n return 'webpack';\n }\n\n public async startTypeScriptServices(): Promise<void> {\n // noop -- this feature is Metro-only.\n }\n\n public broadcastMessage(\n method: string | 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ): void {\n if (!this.instance) {\n return;\n }\n\n assertIsWebpackDevServer(this.instance?.server);\n\n // TODO(EvanBacon): Custom Webpack overlay.\n // Default webpack-dev-server sockets use \"content-changed\" instead of \"reload\" (what we use on native).\n // For now, just manually convert the value so our CLI interface can be unified.\n const hackyConvertedMessage = method === 'reload' ? 'content-changed' : method;\n\n if (\n 'sendMessage' in this.instance.server &&\n typeof this.instance.server.sendMessage === 'function'\n ) {\n // NOTE: https://github.com/expo/expo/issues/21994#issuecomment-1517122501\n this.instance.server.sendMessage(this.instance.server.sockets, hackyConvertedMessage, params);\n } else {\n this.instance.server.sockWrite(this.instance.server.sockets, hackyConvertedMessage, params);\n }\n }\n\n isTargetingNative(): boolean {\n return false;\n }\n\n private async getAvailablePortAsync(options: { defaultPort?: number }): Promise<number> {\n try {\n const defaultPort = options?.defaultPort ?? 19006;\n const port = await choosePortAsync(this.projectRoot, {\n defaultPort,\n host: env.WEB_HOST,\n });\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', `Port ${defaultPort} not available.`);\n }\n return port;\n } catch (error: any) {\n throw new CommandError('NO_PORT_FOUND', error.message);\n }\n }\n\n async bundleAsync({ mode, clear }: { mode: 'development' | 'production'; clear: boolean }) {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n\n if (clear) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n const config = await this.loadConfigAsync({\n isImageEditingEnabled: true,\n mode,\n });\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n const bar = createProgressBar(chalk`{bold Web} Bundling Javascript [:bar] :percent`, {\n width: 64,\n total: 100,\n clear: true,\n complete: '=',\n incomplete: ' ',\n });\n\n // NOTE(EvanBacon): Add a progress bar to the webpack logger if defined (e.g. not in CI).\n if (bar != null) {\n config.plugins.push(\n new webpack.ProgressPlugin((percent: number) => {\n bar?.update(percent);\n if (percent === 1) {\n bar?.terminate();\n }\n })\n );\n }\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n try {\n await compileAsync(compiler);\n } catch (error: any) {\n Log.error(chalk.red('Failed to compile'));\n throw error;\n } finally {\n bar?.terminate();\n }\n }\n\n protected async startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance> {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n const WebpackDevServer = importWebpackDevServerFromProject(this.projectRoot);\n\n await this.stopAsync();\n\n options.port = await this.getAvailablePortAsync({\n defaultPort: options.port,\n });\n const { resetDevServer, https, port, mode } = options;\n\n this.urlCreator = this.getUrlCreator({\n port,\n location: {\n scheme: https ? 'https' : 'http',\n },\n });\n\n debug('Starting webpack on port: ' + port);\n\n if (resetDevServer) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n if (https) {\n debug('Configuring TLS to enable HTTPS support');\n await ensureEnvironmentSupportsTLSAsync(this.projectRoot).catch((error) => {\n Log.error(`Error creating TLS certificates: ${error}`);\n });\n }\n\n const config = await this.loadConfigAsync(options);\n\n Log.log(chalk`Starting Webpack on port ${port} in {underline ${mode}} mode.`);\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n const server = new WebpackDevServer(compiler, config.devServer);\n const host =\n env.WEB_HOST ?? (options.location.hostType === 'localhost' ? 'localhost' : undefined);\n\n // Launch WebpackDevServer.\n server.listen(port, host, function (this: http.Server, error) {\n if (error) {\n Log.error(error.message);\n }\n });\n\n // Extend the close method to ensure that we clean up the local info.\n const originalClose = server.close.bind(server);\n\n server.close = (callback?: (err?: Error) => void) => {\n return originalClose((err?: Error) => {\n this.instance = null;\n callback?.(err);\n });\n };\n\n const _host = getIpAddress();\n const protocol = https ? 'https' : 'http';\n\n return {\n // Server instance\n server,\n // URL Info\n location: {\n url: `${protocol}://${_host}:${port}`,\n port,\n protocol,\n host: _host,\n },\n middleware: null,\n // Match the native protocol.\n messageSocket: {\n broadcast: this.broadcastMessage,\n },\n };\n }\n\n /** Load the Webpack config. Exposed for testing. */\n getProjectConfigFilePath(): string | null {\n // Check if the project has a webpack.config.js in the root.\n return (\n this.getConfigModuleIds().reduce<string | null | undefined>(\n (prev, moduleId) => prev || resolveFrom.silent(this.projectRoot, moduleId),\n null\n ) ?? null\n );\n }\n\n async loadConfigAsync(\n options: Pick<BundlerStartOptions, 'mode' | 'isImageEditingEnabled' | 'https'>,\n argv?: string[]\n ): Promise<WebpackConfiguration> {\n // let bar: ProgressBar | null = null;\n\n const env = {\n projectRoot: this.projectRoot,\n pwa: !!options.isImageEditingEnabled,\n // TODO: Use a new loader in Webpack config...\n logger: {\n info() {},\n },\n mode: options.mode,\n https: options.https,\n };\n setNodeEnv(env.mode ?? 'development');\n require('@expo/env').load(env.projectRoot);\n // Check if the project has a webpack.config.js in the root.\n const projectWebpackConfig = this.getProjectConfigFilePath();\n let config: WebpackConfiguration;\n if (projectWebpackConfig) {\n const webpackConfig = require(projectWebpackConfig);\n if (typeof webpackConfig === 'function') {\n config = await webpackConfig(env, argv);\n } else {\n config = webpackConfig;\n }\n } else {\n // Fallback to the default expo webpack config.\n const loadDefaultConfigAsync = importExpoWebpackConfigFromProject(this.projectRoot);\n config = await loadDefaultConfigAsync(env, argv);\n }\n return config;\n }\n\n protected getConfigModuleIds(): string[] {\n return ['./webpack.config.js'];\n }\n\n protected async clearWebProjectCacheAsync(\n projectRoot: string,\n mode: string = 'development'\n ): Promise<void> {\n Log.log(chalk.dim(`Clearing Webpack ${mode} cache directory...`));\n\n const dir = await ensureDotExpoProjectDirectoryInitialized(projectRoot);\n const cacheFolder = path.join(dir, 'web/cache', mode);\n try {\n await fs.promises.rm(cacheFolder, { recursive: true, force: true });\n } catch (error: any) {\n Log.error(`Could not clear ${mode} web cache directory: ${error.message}`);\n }\n }\n}\n\nexport function getProjectWebpackConfigFilePath(projectRoot: string) {\n return resolveFrom.silent(projectRoot, './webpack.config.js');\n}\n"],"names":["WebpackBundlerDevServer","getProjectWebpackConfigFilePath","debug","require","assertIsWebpackDevServer","value","sockWrite","sendMessage","CommandError","constructor","name","BundlerDevServer","startTypeScriptServices","broadcastMessage","method","params","instance","server","hackyConvertedMessage","sockets","isTargetingNative","getAvailablePortAsync","options","defaultPort","port","choosePortAsync","projectRoot","host","env","WEB_HOST","error","message","bundleAsync","mode","clear","webpack","importWebpackFromProject","clearWebProjectCacheAsync","config","loadConfigAsync","isImageEditingEnabled","plugins","bar","createProgressBar","chalk","width","total","complete","incomplete","push","ProgressPlugin","percent","update","terminate","compiler","compileAsync","Log","red","startImplementationAsync","WebpackDevServer","importWebpackDevServerFromProject","stopAsync","resetDevServer","https","urlCreator","getUrlCreator","location","scheme","ensureEnvironmentSupportsTLSAsync","catch","log","devServer","hostType","undefined","listen","originalClose","close","bind","callback","err","_host","getIpAddress","protocol","url","middleware","messageSocket","broadcast","getProjectConfigFilePath","getConfigModuleIds","reduce","prev","moduleId","resolveFrom","silent","argv","pwa","logger","info","setNodeEnv","load","projectWebpackConfig","webpackConfig","loadDefaultConfigAsync","importExpoWebpackConfigFromProject","dim","dir","ensureDotExpoProjectDirectoryInitialized","cacheFolder","path","join","fs","promises","rm","recursive","force"],"mappings":"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"}
@@ -9,6 +9,9 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ cleanupOldExpoGoCacheEntriesAsync: function() {
13
+ return cleanupOldExpoGoCacheEntriesAsync;
14
+ },
12
15
  downloadExpoGoAsync: function() {
13
16
  return downloadExpoGoAsync;
14
17
  },
@@ -16,6 +19,13 @@ _export(exports, {
16
19
  return getExpoGoVersionEntryAsync;
17
20
  }
18
21
  });
22
+ function _promises() {
23
+ const data = /*#__PURE__*/ _interop_require_default(require("fs/promises"));
24
+ _promises = function() {
25
+ return data;
26
+ };
27
+ return data;
28
+ }
19
29
  function _path() {
20
30
  const data = /*#__PURE__*/ _interop_require_default(require("path"));
21
31
  _path = function() {
@@ -77,6 +87,31 @@ async function getExpoGoVersionEntryAsync(sdkVersion) {
77
87
  }
78
88
  return version;
79
89
  }
90
+ const SIX_MONTHS_IN_MS = 6 * 30 * 24 * 60 * 60 * 1000;
91
+ async function cleanupOldExpoGoCacheEntriesAsync(cacheDirectory, maxAgeMs = SIX_MONTHS_IN_MS) {
92
+ let cacheEntries;
93
+ try {
94
+ cacheEntries = await _promises().default.readdir(cacheDirectory);
95
+ } catch {
96
+ return;
97
+ }
98
+ const now = Date.now();
99
+ for (const entry of cacheEntries){
100
+ const filePath = _path().default.join(cacheDirectory, entry);
101
+ try {
102
+ const stat = await _promises().default.lstat(filePath);
103
+ if (now - stat.mtimeMs > maxAgeMs) {
104
+ debug(`Removing old app cache entry: ${filePath}`);
105
+ await _promises().default.rm(filePath, {
106
+ recursive: true,
107
+ force: true
108
+ });
109
+ }
110
+ } catch {
111
+ // continue
112
+ }
113
+ }
114
+ }
80
115
  async function downloadExpoGoAsync(platform, { url, sdkVersion }) {
81
116
  const { getFilePath, versionsKey, shouldExtractResults } = platformSettings[platform];
82
117
  const spinner = (0, _ora.ora)({
@@ -97,6 +132,7 @@ async function downloadExpoGoAsync(platform, { url, sdkVersion }) {
97
132
  const filename = _path().default.parse(url).name;
98
133
  try {
99
134
  const outputPath = getFilePath(filename);
135
+ cleanupOldExpoGoCacheEntriesAsync(_path().default.dirname(outputPath));
100
136
  debug(`Downloading Expo Go from "${url}" to "${outputPath}".`);
101
137
  debug(`The requested copy of Expo Go might already be cached in: "${(0, _UserSettings.getExpoHomeDirectory)()}". You can disable the cache with EXPO_NO_CACHE=1`);
102
138
  await (0, _profile.profile)(_downloadAppAsync.downloadAppAsync)({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/downloadExpoGoAsync.ts"],"sourcesContent":["import path from 'path';\nimport ProgressBar from 'progress';\nimport { gt } from 'semver';\n\nimport { downloadAppAsync } from './downloadAppAsync';\nimport { CommandError } from './errors';\nimport { ora } from './ora';\nimport { profile } from './profile';\nimport { createProgressBar } from './progress';\nimport { getVersionsAsync, SDKVersion } from '../api/getVersions';\nimport { getExpoHomeDirectory } from '../api/user/UserSettings';\nimport { Log } from '../log';\n\nconst debug = require('debug')('expo:utils:downloadExpoGo') as typeof console.log;\n\nconst platformSettings: Record<\n string,\n {\n shouldExtractResults: boolean;\n versionsKey: keyof SDKVersion;\n getFilePath: (filename: string) => string;\n }\n> = {\n ios: {\n versionsKey: 'iosClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'ios-simulator-app-cache', `${filename}.app`),\n shouldExtractResults: true,\n },\n android: {\n versionsKey: 'androidClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'android-apk-cache', `${filename}.apk`),\n shouldExtractResults: false,\n },\n};\n\n/**\n * @internal exposed for testing.\n * @returns the matching `SDKVersion` object from the Expo API.\n */\nexport async function getExpoGoVersionEntryAsync(sdkVersion: string): Promise<SDKVersion> {\n const { sdkVersions: versions } = await getVersionsAsync();\n let version: SDKVersion;\n\n if (sdkVersion.toUpperCase() === 'UNVERSIONED') {\n // find the latest version\n const latestVersionKey = Object.keys(versions).reduce((a, b) => {\n if (gt(b, a)) {\n return b;\n }\n return a;\n }, '0.0.0');\n\n Log.warn(\n `Downloading the latest Expo Go client (${latestVersionKey}). This will not fully conform to UNVERSIONED.`\n );\n version = versions[latestVersionKey];\n } else {\n version = versions[sdkVersion];\n }\n\n if (!version) {\n throw new CommandError(`Unable to find a version of Expo Go for SDK ${sdkVersion}`);\n }\n return version;\n}\n\n/** Download the Expo Go app from the Expo servers (if only it was this easy for every app). */\nexport async function downloadExpoGoAsync(\n platform: keyof typeof platformSettings,\n {\n url,\n sdkVersion,\n }: {\n url?: string;\n sdkVersion: string;\n }\n): Promise<string> {\n const { getFilePath, versionsKey, shouldExtractResults } = platformSettings[platform];\n\n const spinner = ora({ text: 'Fetching Expo Go', color: 'white' }).start();\n\n let bar: ProgressBar | null = null;\n\n try {\n if (!url) {\n const version = await getExpoGoVersionEntryAsync(sdkVersion);\n\n debug(`Installing Expo Go version for SDK ${sdkVersion} at URL: ${version[versionsKey]}`);\n url = version[versionsKey] as string;\n }\n } catch (error) {\n spinner.fail();\n throw error;\n }\n\n const filename = path.parse(url).name;\n\n try {\n const outputPath = getFilePath(filename);\n debug(`Downloading Expo Go from \"${url}\" to \"${outputPath}\".`);\n debug(\n `The requested copy of Expo Go might already be cached in: \"${getExpoHomeDirectory()}\". You can disable the cache with EXPO_NO_CACHE=1`\n );\n await profile(downloadAppAsync)({\n url,\n // Save all encrypted cache data to `~/.expo/expo-go`\n cacheDirectory: 'expo-go',\n outputPath,\n extract: shouldExtractResults,\n onProgress({ progress, total }) {\n if (progress && total) {\n if (!bar) {\n if (spinner.isSpinning) {\n spinner.stop();\n }\n bar = createProgressBar('Downloading the Expo Go app [:bar] :percent :etas', {\n width: 64,\n total: 100,\n // clear: true,\n complete: '=',\n incomplete: ' ',\n });\n } else {\n bar.update(progress, total);\n }\n }\n },\n });\n return outputPath;\n } finally {\n spinner.stop();\n (bar as ProgressBar | null)?.terminate();\n }\n}\n"],"names":["downloadExpoGoAsync","getExpoGoVersionEntryAsync","debug","require","platformSettings","ios","versionsKey","getFilePath","filename","path","join","getExpoHomeDirectory","shouldExtractResults","android","sdkVersion","sdkVersions","versions","getVersionsAsync","version","toUpperCase","latestVersionKey","Object","keys","reduce","a","b","gt","Log","warn","CommandError","platform","url","spinner","ora","text","color","start","bar","error","fail","parse","name","outputPath","profile","downloadAppAsync","cacheDirectory","extract","onProgress","progress","total","isSpinning","stop","createProgressBar","width","complete","incomplete","update","terminate"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/downloadExpoGoAsync.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\nimport ProgressBar from 'progress';\nimport { gt } from 'semver';\n\nimport { downloadAppAsync } from './downloadAppAsync';\nimport { CommandError } from './errors';\nimport { ora } from './ora';\nimport { profile } from './profile';\nimport { createProgressBar } from './progress';\nimport { getVersionsAsync, SDKVersion } from '../api/getVersions';\nimport { getExpoHomeDirectory } from '../api/user/UserSettings';\nimport { Log } from '../log';\n\nconst debug = require('debug')('expo:utils:downloadExpoGo') as typeof console.log;\n\nconst platformSettings: Record<\n string,\n {\n shouldExtractResults: boolean;\n versionsKey: keyof SDKVersion;\n getFilePath: (filename: string) => string;\n }\n> = {\n ios: {\n versionsKey: 'iosClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'ios-simulator-app-cache', `${filename}.app`),\n shouldExtractResults: true,\n },\n android: {\n versionsKey: 'androidClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'android-apk-cache', `${filename}.apk`),\n shouldExtractResults: false,\n },\n};\n\n/**\n * @internal exposed for testing.\n * @returns the matching `SDKVersion` object from the Expo API.\n */\nexport async function getExpoGoVersionEntryAsync(sdkVersion: string): Promise<SDKVersion> {\n const { sdkVersions: versions } = await getVersionsAsync();\n let version: SDKVersion;\n\n if (sdkVersion.toUpperCase() === 'UNVERSIONED') {\n // find the latest version\n const latestVersionKey = Object.keys(versions).reduce((a, b) => {\n if (gt(b, a)) {\n return b;\n }\n return a;\n }, '0.0.0');\n\n Log.warn(\n `Downloading the latest Expo Go client (${latestVersionKey}). This will not fully conform to UNVERSIONED.`\n );\n version = versions[latestVersionKey];\n } else {\n version = versions[sdkVersion];\n }\n\n if (!version) {\n throw new CommandError(`Unable to find a version of Expo Go for SDK ${sdkVersion}`);\n }\n return version;\n}\n\nconst SIX_MONTHS_IN_MS = 6 * 30 * 24 * 60 * 60 * 1000;\n\n/** Remove cached Expo Go apps (.apk / .app) that are older than `maxAge` from the given directory. */\nexport async function cleanupOldExpoGoCacheEntriesAsync(\n cacheDirectory: string,\n maxAgeMs: number = SIX_MONTHS_IN_MS\n): Promise<void> {\n let cacheEntries: string[];\n try {\n cacheEntries = await fs.readdir(cacheDirectory);\n } catch {\n return;\n }\n\n const now = Date.now();\n for (const entry of cacheEntries) {\n const filePath = path.join(cacheDirectory, entry);\n try {\n const stat = await fs.lstat(filePath);\n if (now - stat.mtimeMs > maxAgeMs) {\n debug(`Removing old app cache entry: ${filePath}`);\n await fs.rm(filePath, { recursive: true, force: true });\n }\n } catch {\n // continue\n }\n }\n}\n\n/** Download the Expo Go app from the Expo servers (if only it was this easy for every app). */\nexport async function downloadExpoGoAsync(\n platform: keyof typeof platformSettings,\n {\n url,\n sdkVersion,\n }: {\n url?: string;\n sdkVersion: string;\n }\n): Promise<string> {\n const { getFilePath, versionsKey, shouldExtractResults } = platformSettings[platform];\n\n const spinner = ora({ text: 'Fetching Expo Go', color: 'white' }).start();\n\n let bar: ProgressBar | null = null;\n\n try {\n if (!url) {\n const version = await getExpoGoVersionEntryAsync(sdkVersion);\n\n debug(`Installing Expo Go version for SDK ${sdkVersion} at URL: ${version[versionsKey]}`);\n url = version[versionsKey] as string;\n }\n } catch (error) {\n spinner.fail();\n throw error;\n }\n\n const filename = path.parse(url).name;\n\n try {\n const outputPath = getFilePath(filename);\n cleanupOldExpoGoCacheEntriesAsync(path.dirname(outputPath));\n debug(`Downloading Expo Go from \"${url}\" to \"${outputPath}\".`);\n debug(\n `The requested copy of Expo Go might already be cached in: \"${getExpoHomeDirectory()}\". You can disable the cache with EXPO_NO_CACHE=1`\n );\n await profile(downloadAppAsync)({\n url,\n // Save all encrypted cache data to `~/.expo/expo-go`\n cacheDirectory: 'expo-go',\n outputPath,\n extract: shouldExtractResults,\n onProgress({ progress, total }) {\n if (progress && total) {\n if (!bar) {\n if (spinner.isSpinning) {\n spinner.stop();\n }\n bar = createProgressBar('Downloading the Expo Go app [:bar] :percent :etas', {\n width: 64,\n total: 100,\n // clear: true,\n complete: '=',\n incomplete: ' ',\n });\n } else {\n bar.update(progress, total);\n }\n }\n },\n });\n return outputPath;\n } finally {\n spinner.stop();\n (bar as ProgressBar | null)?.terminate();\n }\n}\n"],"names":["cleanupOldExpoGoCacheEntriesAsync","downloadExpoGoAsync","getExpoGoVersionEntryAsync","debug","require","platformSettings","ios","versionsKey","getFilePath","filename","path","join","getExpoHomeDirectory","shouldExtractResults","android","sdkVersion","sdkVersions","versions","getVersionsAsync","version","toUpperCase","latestVersionKey","Object","keys","reduce","a","b","gt","Log","warn","CommandError","SIX_MONTHS_IN_MS","cacheDirectory","maxAgeMs","cacheEntries","fs","readdir","now","Date","entry","filePath","stat","lstat","mtimeMs","rm","recursive","force","platform","url","spinner","ora","text","color","start","bar","error","fail","parse","name","outputPath","dirname","profile","downloadAppAsync","extract","onProgress","progress","total","isSpinning","stop","createProgressBar","width","complete","incomplete","update","terminate"],"mappings":"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"}
@@ -12,6 +12,9 @@ _export(exports, {
12
12
  env: function() {
13
13
  return env;
14
14
  },
15
+ envIsHeadless: function() {
16
+ return envIsHeadless;
17
+ },
15
18
  envIsWebcontainer: function() {
16
19
  return envIsWebcontainer;
17
20
  }
@@ -75,7 +78,7 @@ class Env {
75
78
  return (0, _getenv().boolish)('EXPO_NO_GIT_STATUS', true);
76
79
  }
77
80
  /** Disable auto web setup */ get EXPO_NO_WEB_SETUP() {
78
- return (0, _getenv().boolish)('EXPO_NO_WEB_SETUP', false);
81
+ return (0, _getenv().boolish)('EXPO_NO_WEB_SETUP', envIsHeadless());
79
82
  }
80
83
  /** Disable auto TypeScript setup */ get EXPO_NO_TYPESCRIPT_SETUP() {
81
84
  return (0, _getenv().boolish)('EXPO_NO_TYPESCRIPT_SETUP', false);
@@ -164,11 +167,6 @@ class Env {
164
167
  */ get EXPO_METRO_UNSTABLE_ERRORS() {
165
168
  return (0, _getenv().boolish)('EXPO_METRO_UNSTABLE_ERRORS', true);
166
169
  }
167
- /** Enable the experimental sticky resolver for Metro (Uses Expo Autolinking results and applies them to Metro's resolution)
168
- * @deprecated Replaced by `exp.experiments.autolinkingModuleResolution`
169
- */ get EXPO_USE_STICKY_RESOLVER() {
170
- return (0, _getenv().boolish)('EXPO_USE_STICKY_RESOLVER', false);
171
- }
172
170
  /** Disable Environment Variable injection in client bundles. */ get EXPO_NO_CLIENT_ENV_VARS() {
173
171
  return (0, _getenv().boolish)('EXPO_NO_CLIENT_ENV_VARS', false);
174
172
  }
@@ -218,12 +216,10 @@ class Env {
218
216
  return (0, _getenv().boolish)('EAS_BUILD', false);
219
217
  }
220
218
  /** Disable the React Native Directory compatibility check for new architecture when installing packages */ get EXPO_NO_NEW_ARCH_COMPAT_CHECK() {
221
- return (0, _getenv().boolish)('EXPO_NO_NEW_ARCH_COMPAT_CHECK', false);
219
+ return (0, _getenv().boolish)('EXPO_NO_NEW_ARCH_COMPAT_CHECK', envIsHeadless());
222
220
  }
223
221
  /** Disable the dependency validation when installing other dependencies and starting the project */ get EXPO_NO_DEPENDENCY_VALIDATION() {
224
- // Default to disabling when running in a web container (stackblitz, bolt, etc).
225
- const isWebContainer = _nodeprocess().default.versions.webcontainer != null;
226
- return (0, _getenv().boolish)('EXPO_NO_DEPENDENCY_VALIDATION', isWebContainer);
222
+ return (0, _getenv().boolish)('EXPO_NO_DEPENDENCY_VALIDATION', envIsHeadless());
227
223
  }
228
224
  /** Force Expo CLI to run in webcontainer mode, this has impact on which URL Expo is using by default */ get EXPO_FORCE_WEBCONTAINER_ENV() {
229
225
  return (0, _getenv().boolish)('EXPO_FORCE_WEBCONTAINER_ENV', false);
@@ -249,7 +245,10 @@ class Env {
249
245
  /**
250
246
  * Enable Bonjour advertising of the Expo CLI on local networks
251
247
  */ get EXPO_UNSTABLE_BONJOUR() {
252
- return (0, _getenv().boolish)('EXPO_UNSTABLE_BONJOUR', false);
248
+ return (0, _getenv().boolish)('EXPO_UNSTABLE_BONJOUR', !envIsHeadless());
249
+ }
250
+ /** @internal Configure other environment variables for headless operations */ get EXPO_UNSTABLE_HEADLESS() {
251
+ return (0, _getenv().boolish)('EXPO_UNSTABLE_HEADLESS', envIsWebcontainer());
253
252
  }
254
253
  }
255
254
  const env = new Env();
@@ -257,5 +256,8 @@ function envIsWebcontainer() {
257
256
  // See: https://github.com/unjs/std-env/blob/4b1e03c4efce58249858efc2cc5f5eac727d0adb/src/providers.ts#L134-L143
258
257
  return env.EXPO_FORCE_WEBCONTAINER_ENV || _nodeprocess().default.env.SHELL === '/bin/jsh' && !!_nodeprocess().default.versions.webcontainer;
259
258
  }
259
+ function envIsHeadless() {
260
+ return env.EXPO_UNSTABLE_HEADLESS;
261
+ }
260
262
 
261
263
  //# sourceMappingURL=env.js.map