@expo/cli 56.0.5 → 56.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/cli +1 -1
- package/build/src/events/index.js +1 -1
- package/build/src/start/checkDependenciesOnStart.js +41 -8
- package/build/src/start/checkDependenciesOnStart.js.map +1 -1
- package/build/src/start/interface/commandsTable.js.map +1 -1
- package/build/src/start/interface/interactiveActions.js +7 -1
- package/build/src/start/interface/interactiveActions.js.map +1 -1
- package/build/src/start/interface/startInterface.js +7 -27
- package/build/src/start/interface/startInterface.js.map +1 -1
- package/build/src/start/resolveOptions.js +2 -2
- package/build/src/start/resolveOptions.js.map +1 -1
- package/build/src/start/server/getStaticRenderFunctions.js +7 -19
- package/build/src/start/server/getStaticRenderFunctions.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +4 -12
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +58 -8
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/TerminalReporter.js +18 -0
- package/build/src/start/server/metro/TerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/createFileMap-fork.js +2 -17
- package/build/src/start/server/metro/createFileMap-fork.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +46 -3
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/runServer-fork.js +1 -8
- package/build/src/start/server/metro/runServer-fork.js.map +1 -1
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js +48 -26
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +17 -4
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/DomComponentsMiddleware.js +0 -8
- package/build/src/start/server/middleware/DomComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/metroOptions.js +3 -2
- package/build/src/start/server/middleware/metroOptions.js.map +1 -1
- package/build/src/start/server/serverLogLikeMetro.js +5 -28
- package/build/src/start/server/serverLogLikeMetro.js.map +1 -1
- package/build/src/start/startAsync.js +6 -7
- package/build/src/start/startAsync.js.map +1 -1
- package/build/src/utils/composeMetroIgnorePatterns.js +69 -0
- package/build/src/utils/composeMetroIgnorePatterns.js.map +1 -0
- package/build/src/utils/port.js +7 -0
- package/build/src/utils/port.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +17 -19
|
@@ -57,6 +57,7 @@ const _serverLogLikeMetro = require("../serverLogLikeMetro");
|
|
|
57
57
|
const _metroErrorInterface = require("./metroErrorInterface");
|
|
58
58
|
const _events = require("../../../events");
|
|
59
59
|
const _ansi = require("../../../utils/ansi");
|
|
60
|
+
const _interactive = require("../../../utils/interactive");
|
|
60
61
|
function _interop_require_default(obj) {
|
|
61
62
|
return obj && obj.__esModule ? obj : {
|
|
62
63
|
default: obj
|
|
@@ -82,6 +83,17 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
82
83
|
constructor(serverRoot, terminal){
|
|
83
84
|
super(terminal), this.serverRoot = serverRoot;
|
|
84
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Suppress status messages in non-interactive mode.
|
|
88
|
+
* In TTY mode, Terminal overwrites status lines in-place (progress bars).
|
|
89
|
+
* In non-TTY mode, Terminal writes status via a 3500ms throttle, producing
|
|
90
|
+
* permanent output that interleaves with log messages like "Bundled Xms".
|
|
91
|
+
*/ _getStatusMessage() {
|
|
92
|
+
if (!(0, _interactive.isInteractive)()) {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
return super._getStatusMessage();
|
|
96
|
+
}
|
|
85
97
|
_log(event) {
|
|
86
98
|
this.#captureLog(event);
|
|
87
99
|
switch(event.type){
|
|
@@ -250,7 +262,11 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
250
262
|
}
|
|
251
263
|
}
|
|
252
264
|
#onClientLog(evt) {
|
|
253
|
-
const { level = 'log'
|
|
265
|
+
const { level = 'log' } = evt;
|
|
266
|
+
// Apply printf-style format substitution (e.g. %s, %d) that browsers handle
|
|
267
|
+
// natively in console methods but Node/Metro terminal logging does not.
|
|
268
|
+
const data = applyConsoleFormatting(evt.data);
|
|
269
|
+
const platformTag = getPlatformTagForClientLog(evt.mode);
|
|
254
270
|
if (level === 'warn' || level === 'error') {
|
|
255
271
|
let hasStack = false;
|
|
256
272
|
const parsed = data.map((msg)=>{
|
|
@@ -300,7 +316,7 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
300
316
|
level,
|
|
301
317
|
data: symbolicated
|
|
302
318
|
});
|
|
303
|
-
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level,
|
|
319
|
+
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, platformTag, ...filtered);
|
|
304
320
|
})();
|
|
305
321
|
return;
|
|
306
322
|
}
|
|
@@ -310,7 +326,7 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
310
326
|
data
|
|
311
327
|
});
|
|
312
328
|
// Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.
|
|
313
|
-
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level,
|
|
329
|
+
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, platformTag, ...data);
|
|
314
330
|
}
|
|
315
331
|
#captureLog(evt) {
|
|
316
332
|
switch(evt.type){
|
|
@@ -408,14 +424,48 @@ function stripMetroInfo(errorMessage) {
|
|
|
408
424
|
/** @returns if the message matches the initial startup log */ function isAppRegistryStartupMessage(body) {
|
|
409
425
|
return body.length === 1 && (/^Running application "main" with appParams:/.test(body[0]) || /^Running "main" with \{/.test(body[0]));
|
|
410
426
|
}
|
|
427
|
+
/** Apply printf-style format substitutions (%s, %d, %i, %f, %o, %O) that browsers handle natively */ function applyConsoleFormatting(data) {
|
|
428
|
+
if (data.length <= 1 || typeof data[0] !== 'string' || !/%[sdifoO%]/.test(data[0])) {
|
|
429
|
+
return data;
|
|
430
|
+
}
|
|
431
|
+
return [
|
|
432
|
+
(0, _util().format)(...data)
|
|
433
|
+
];
|
|
434
|
+
}
|
|
435
|
+
/** @returns formatted platform name for a client log event, or null if no prefix should be shown */ function getPlatformTagForClientLog(mode) {
|
|
436
|
+
switch(mode){
|
|
437
|
+
case 'ios':
|
|
438
|
+
return 'iOS';
|
|
439
|
+
case 'android':
|
|
440
|
+
return 'Android';
|
|
441
|
+
case 'web':
|
|
442
|
+
return 'Web';
|
|
443
|
+
case 'dom':
|
|
444
|
+
return 'DOM';
|
|
445
|
+
default:
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
411
449
|
/** @returns platform specific tag for a `BundleDetails` object */ function getPlatformTagForBuildDetails(bundleDetails) {
|
|
412
450
|
const platform = (bundleDetails == null ? void 0 : bundleDetails.platform) ?? null;
|
|
413
451
|
if (platform) {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
452
|
+
let formatted;
|
|
453
|
+
switch(platform){
|
|
454
|
+
case 'ios':
|
|
455
|
+
formatted = 'iOS';
|
|
456
|
+
break;
|
|
457
|
+
case 'android':
|
|
458
|
+
formatted = 'Android';
|
|
459
|
+
break;
|
|
460
|
+
case 'web':
|
|
461
|
+
formatted = 'Web';
|
|
462
|
+
break;
|
|
463
|
+
case 'dom':
|
|
464
|
+
formatted = 'DOM';
|
|
465
|
+
break;
|
|
466
|
+
default:
|
|
467
|
+
formatted = platform;
|
|
468
|
+
}
|
|
419
469
|
return `${_chalk().default.bold(formatted)} `;
|
|
420
470
|
}
|
|
421
471
|
return '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import type { Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport type {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\nimport { events, shouldReduceLogs } from '../../../events';\nimport { stripAnsi } from '../../../utils/ansi';\n\ntype ClientLogLevel =\n | 'trace'\n | 'info'\n | 'error'\n | 'warn'\n | 'log'\n | 'group'\n | 'groupCollapsed'\n | 'groupEnd'\n | 'debug';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\n// prettier-ignore\nexport const event = events('metro', (t) => [\n t.event<'bundling:started', {\n id: string;\n platform: null | string;\n environment: null | string;\n entry: string;\n }>(),\n t.event<'bundling:done', {\n id: string | null;\n ms: number | null;\n total: number;\n }>(),\n t.event<'bundling:failed', {\n id: string | null;\n filename: string | null;\n message: string | null;\n importStack: string | null;\n targetModuleName: string | null;\n originModulePath: string | null;\n }>(),\n t.event<'bundling:progress', {\n id: string | null;\n progress: number;\n current: number;\n total: number;\n }>(),\n t.event<'server_log', {\n level: 'info' | 'warn' | 'error' | null;\n data: string | unknown[] | null;\n }>(),\n t.event<'client_log', {\n level: ClientLogLevel | null;\n data: unknown[] | null;\n }>(),\n t.event<'hmr_client_error', {\n message: string;\n }>(),\n t.event<'cache_write_error', {\n message: string;\n }>(),\n t.event<'cache_read_error', {\n message: string;\n }>(),\n]);\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n #lastFailedBuildID: string | undefined;\n\n constructor(\n public serverRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n this.#captureLog(event);\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n } else if (event.level != null) {\n return this.#onClientLog(event);\n } else {\n break;\n }\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n const localPath =\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ? progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '')\n : this.#normalizePath(progress.bundleDetails.entryFile);\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n let ms: number | null = null;\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n ms = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (ms <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(ms.toFixed(0) + 'ms');\n }\n }\n\n if (phase === 'done') {\n event('bundling:done', {\n id: progress.bundleDetails.buildID ?? null,\n total: progress.totalFileCount,\n ms,\n });\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n event('bundling:progress', {\n id: progress.bundleDetails.buildID ?? null,\n progress: progress.ratio,\n total: progress.totalFileCount,\n current: progress.transformedFileCount,\n });\n if (shouldReduceLogs()) {\n return '';\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n if (!shouldReduceLogs()) {\n this.terminal.log(chalk.dim('Starting Metro Bundler') + '\\n');\n }\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n /**\n * Workaround to link build ids to bundling errors.\n * This works because `_logBundleBuildFailed` is called before `_logBundlingError` in synchronous manner.\n * https://github.com/facebook/metro/blob/main/packages/metro/src/Server.js#L939-L945\n */\n _logBundleBuildFailed(buildID: string): void {\n this.#lastFailedBuildID = buildID;\n super._logBundleBuildFailed(buildID);\n }\n\n _logBundlingError(error: SnippetError): void {\n const importStack = nearestImportStack(error);\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.serverRoot, error);\n\n if (moduleResolutionError) {\n const message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n event('bundling:failed', {\n id: this.#lastFailedBuildID ?? null,\n message: stripAnsi(message) ?? null,\n importStack: importStack ?? null,\n filename: error.filename ?? null,\n targetModuleName: this.#normalizePath(error.targetModuleName),\n originModulePath: this.#normalizePath(error.originModulePath),\n });\n\n return this.terminal.log(importStack ? `${message}\\n\\n${importStack}` : message);\n } else {\n event('bundling:failed', {\n id: this.#lastFailedBuildID ?? null,\n message: stripAnsi(error.message) ?? null,\n importStack: importStack ?? null,\n filename: error.filename ?? null,\n targetModuleName: error.targetModuleName ?? null,\n originModulePath: error.originModulePath ?? null,\n });\n\n attachImportStackToRootMessage(error, importStack);\n\n // NOTE(@kitten): Metro drops the stack forcefully when it finds a `SyntaxError`. However,\n // this is really unhelpful, since it prevents debugging Babel plugins or reporting bugs\n // in Babel plugins or a transformer entirely\n if (error.snippet == null && error.stack != null && error instanceof SyntaxError) {\n error.message = error.stack;\n delete error.stack;\n }\n\n return super._logBundlingError(error);\n }\n }\n\n #onClientLog(evt: { type: 'client_log'; level?: ClientLogLevel; data: unknown[] }) {\n const { level = 'log', data } = evt;\n if (level === 'warn' || (level as string) === 'error') {\n let hasStack = false;\n const parsed = data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (typeof msg === 'string' && msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') {\n return p;\n } else if (\n p &&\n typeof p === 'object' &&\n 'message' in p &&\n typeof p.message === 'string'\n ) {\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(\n this.serverRoot,\n level,\n p as any\n );\n } else {\n return null;\n }\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (!s.value) {\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n\n event('client_log', { level, data: symbolicated });\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...filtered);\n })();\n return;\n }\n }\n\n event('client_log', { level, data });\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...data);\n }\n\n #captureLog(evt: TerminalReportableEvent) {\n switch (evt.type) {\n case 'bundle_build_started': {\n const entry =\n typeof evt.bundleDetails?.customTransformOptions?.dom === 'string' &&\n evt.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ? evt.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '')\n : this.#normalizePath(evt.bundleDetails.entryFile);\n return event('bundling:started', {\n id: evt.buildID,\n platform: evt.bundleDetails.platform ?? null,\n environment: evt.bundleDetails.customTransformOptions?.environment ?? null,\n entry,\n });\n }\n case 'unstable_server_log':\n return event('server_log', {\n level: evt.level ?? null,\n data: evt.data ?? null,\n });\n case 'client_log':\n // Handled separately: see this.#onClientLog\n return;\n case 'hmr_client_error':\n case 'cache_write_error':\n case 'cache_read_error':\n return event(evt.type, {\n message: evt.error.message,\n });\n }\n }\n\n #normalizePath<T extends string | null>(dest: T | undefined): T | string {\n return dest != null && path.isAbsolute(dest)\n ? path.relative(this.serverRoot, dest)\n : ((dest || null) as T);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n serverRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(serverRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","event","extractCodeFrame","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","events","t","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","serverRoot","terminal","_log","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","includes","path","sep","replace","entryFile","status","color","chalk","green","red","_bundleTimers","get","buildID","time","ms","elapsed","micro","Number","tenthFractionOfMicro","toFixed","cyan","bold","dim","id","total","totalFileCount","plural","reset","ratio","current","transformedFileCount","shouldReduceLogs","filledBar","Math","floor","_progress","bgGreen","repeat","bgWhite","white","padStart","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","log","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundleBuildFailed","_logBundlingError","error","importStack","nearestImportStack","moduleResolutionError","maybeAppendCodeFrame","stripAnsi","filename","targetModuleName","originModulePath","attachImportStackToRootMessage","snippet","stack","SyntaxError","evt","hasStack","parsed","map","msg","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","reason","value","isFallback","push","filtered","filter","_","logLikeMetro","bind","entry","environment","dest","isAbsolute","relative","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","formatted","ios","android","web","trim"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import type { Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { format as utilFormat, stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport type {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\nimport { events, shouldReduceLogs } from '../../../events';\nimport { stripAnsi } from '../../../utils/ansi';\nimport { isInteractive } from '../../../utils/interactive';\n\ntype ClientLogLevel =\n | 'trace'\n | 'info'\n | 'error'\n | 'warn'\n | 'log'\n | 'group'\n | 'groupCollapsed'\n | 'groupEnd'\n | 'debug';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\n// prettier-ignore\nexport const event = events('metro', (t) => [\n t.event<'bundling:started', {\n id: string;\n platform: null | string;\n environment: null | string;\n entry: string;\n }>(),\n t.event<'bundling:done', {\n id: string | null;\n ms: number | null;\n total: number;\n }>(),\n t.event<'bundling:failed', {\n id: string | null;\n filename: string | null;\n message: string | null;\n importStack: string | null;\n targetModuleName: string | null;\n originModulePath: string | null;\n }>(),\n t.event<'bundling:progress', {\n id: string | null;\n progress: number;\n current: number;\n total: number;\n }>(),\n t.event<'server_log', {\n level: 'info' | 'warn' | 'error' | null;\n data: string | unknown[] | null;\n }>(),\n t.event<'client_log', {\n level: ClientLogLevel | null;\n data: unknown[] | null;\n }>(),\n t.event<'hmr_client_error', {\n message: string;\n }>(),\n t.event<'cache_write_error', {\n message: string;\n }>(),\n t.event<'cache_read_error', {\n message: string;\n }>(),\n]);\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n #lastFailedBuildID: string | undefined;\n\n constructor(\n public serverRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n /**\n * Suppress status messages in non-interactive mode.\n * In TTY mode, Terminal overwrites status lines in-place (progress bars).\n * In non-TTY mode, Terminal writes status via a 3500ms throttle, producing\n * permanent output that interleaves with log messages like \"Bundled Xms\".\n */\n _getStatusMessage(): string {\n if (!isInteractive()) {\n return '';\n }\n return super._getStatusMessage();\n }\n\n _log(event: TerminalReportableEvent): void {\n this.#captureLog(event);\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n } else if (event.level != null) {\n return this.#onClientLog(event);\n } else {\n break;\n }\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n const localPath =\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ? progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '')\n : this.#normalizePath(progress.bundleDetails.entryFile);\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n let ms: number | null = null;\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n ms = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (ms <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(ms.toFixed(0) + 'ms');\n }\n }\n\n if (phase === 'done') {\n event('bundling:done', {\n id: progress.bundleDetails.buildID ?? null,\n total: progress.totalFileCount,\n ms,\n });\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n event('bundling:progress', {\n id: progress.bundleDetails.buildID ?? null,\n progress: progress.ratio,\n total: progress.totalFileCount,\n current: progress.transformedFileCount,\n });\n if (shouldReduceLogs()) {\n return '';\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n if (!shouldReduceLogs()) {\n this.terminal.log(chalk.dim('Starting Metro Bundler') + '\\n');\n }\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n /**\n * Workaround to link build ids to bundling errors.\n * This works because `_logBundleBuildFailed` is called before `_logBundlingError` in synchronous manner.\n * https://github.com/facebook/metro/blob/main/packages/metro/src/Server.js#L939-L945\n */\n _logBundleBuildFailed(buildID: string): void {\n this.#lastFailedBuildID = buildID;\n super._logBundleBuildFailed(buildID);\n }\n\n _logBundlingError(error: SnippetError): void {\n const importStack = nearestImportStack(error);\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.serverRoot, error);\n\n if (moduleResolutionError) {\n const message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n event('bundling:failed', {\n id: this.#lastFailedBuildID ?? null,\n message: stripAnsi(message) ?? null,\n importStack: importStack ?? null,\n filename: error.filename ?? null,\n targetModuleName: this.#normalizePath(error.targetModuleName),\n originModulePath: this.#normalizePath(error.originModulePath),\n });\n\n return this.terminal.log(importStack ? `${message}\\n\\n${importStack}` : message);\n } else {\n event('bundling:failed', {\n id: this.#lastFailedBuildID ?? null,\n message: stripAnsi(error.message) ?? null,\n importStack: importStack ?? null,\n filename: error.filename ?? null,\n targetModuleName: error.targetModuleName ?? null,\n originModulePath: error.originModulePath ?? null,\n });\n\n attachImportStackToRootMessage(error, importStack);\n\n // NOTE(@kitten): Metro drops the stack forcefully when it finds a `SyntaxError`. However,\n // this is really unhelpful, since it prevents debugging Babel plugins or reporting bugs\n // in Babel plugins or a transformer entirely\n if (error.snippet == null && error.stack != null && error instanceof SyntaxError) {\n error.message = error.stack;\n delete error.stack;\n }\n\n return super._logBundlingError(error);\n }\n }\n\n #onClientLog(evt: {\n type: 'client_log';\n level?: ClientLogLevel;\n data: unknown[];\n mode?: string;\n }) {\n const { level = 'log' } = evt;\n // Apply printf-style format substitution (e.g. %s, %d) that browsers handle\n // natively in console methods but Node/Metro terminal logging does not.\n const data = applyConsoleFormatting(evt.data);\n const platformTag = getPlatformTagForClientLog(evt.mode);\n if (level === 'warn' || (level as string) === 'error') {\n let hasStack = false;\n const parsed = data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (typeof msg === 'string' && msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') {\n return p;\n } else if (\n p &&\n typeof p === 'object' &&\n 'message' in p &&\n typeof p.message === 'string'\n ) {\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(\n this.serverRoot,\n level,\n p as any\n );\n } else {\n return null;\n }\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (!s.value) {\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n\n event('client_log', { level, data: symbolicated });\n logLikeMetro(this.terminal.log.bind(this.terminal), level, platformTag, ...filtered);\n })();\n return;\n }\n }\n\n event('client_log', { level, data });\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, platformTag, ...data);\n }\n\n #captureLog(evt: TerminalReportableEvent) {\n switch (evt.type) {\n case 'bundle_build_started': {\n const entry =\n typeof evt.bundleDetails?.customTransformOptions?.dom === 'string' &&\n evt.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ? evt.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '')\n : this.#normalizePath(evt.bundleDetails.entryFile);\n return event('bundling:started', {\n id: evt.buildID,\n platform: evt.bundleDetails.platform ?? null,\n environment: evt.bundleDetails.customTransformOptions?.environment ?? null,\n entry,\n });\n }\n case 'unstable_server_log':\n return event('server_log', {\n level: evt.level ?? null,\n data: evt.data ?? null,\n });\n case 'client_log':\n // Handled separately: see this.#onClientLog\n return;\n case 'hmr_client_error':\n case 'cache_write_error':\n case 'cache_read_error':\n return event(evt.type, {\n message: evt.error.message,\n });\n }\n }\n\n #normalizePath<T extends string | null>(dest: T | undefined): T | string {\n return dest != null && path.isAbsolute(dest)\n ? path.relative(this.serverRoot, dest)\n : ((dest || null) as T);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n serverRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(serverRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** Apply printf-style format substitutions (%s, %d, %i, %f, %o, %O) that browsers handle natively */\nfunction applyConsoleFormatting(data: unknown[]): unknown[] {\n if (data.length <= 1 || typeof data[0] !== 'string' || !/%[sdifoO%]/.test(data[0])) {\n return data;\n }\n return [utilFormat(...(data as [string, ...unknown[]]))];\n}\n\n/** @returns formatted platform name for a client log event, or null if no prefix should be shown */\nfunction getPlatformTagForClientLog(mode?: string): string | null {\n switch (mode) {\n case 'ios':\n return 'iOS';\n case 'android':\n return 'Android';\n case 'web':\n return 'Web';\n case 'dom':\n return 'DOM';\n default:\n return null;\n }\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n let formatted: string;\n switch (platform) {\n case 'ios':\n formatted = 'iOS';\n break;\n case 'android':\n formatted = 'Android';\n break;\n case 'web':\n formatted = 'Web';\n break;\n case 'dom':\n formatted = 'DOM';\n break;\n default:\n formatted = platform;\n }\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","event","extractCodeFrame","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","events","t","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","serverRoot","terminal","_getStatusMessage","isInteractive","_log","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","includes","path","sep","replace","entryFile","status","color","chalk","green","red","_bundleTimers","get","buildID","time","ms","elapsed","micro","Number","tenthFractionOfMicro","toFixed","cyan","bold","dim","id","total","totalFileCount","plural","reset","ratio","current","transformedFileCount","shouldReduceLogs","filledBar","Math","floor","_progress","bgGreen","repeat","bgWhite","white","padStart","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","log","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundleBuildFailed","_logBundlingError","error","importStack","nearestImportStack","moduleResolutionError","maybeAppendCodeFrame","stripAnsi","filename","targetModuleName","originModulePath","attachImportStackToRootMessage","snippet","stack","SyntaxError","evt","applyConsoleFormatting","platformTag","getPlatformTagForClientLog","mode","hasStack","parsed","map","msg","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","reason","value","isFallback","push","filtered","filter","_","logLikeMetro","bind","entry","environment","dest","isAbsolute","relative","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","utilFormat","formatted","trim"],"mappings":"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"}
|
|
@@ -62,6 +62,24 @@ function logError(terminal, format, ...args) {
|
|
|
62
62
|
}
|
|
63
63
|
const XTerminalReporter = _TerminalReporter().default;
|
|
64
64
|
class TerminalReporter extends XTerminalReporter {
|
|
65
|
+
/**
|
|
66
|
+
* Override Metro's update() to clear the status before _log() runs.
|
|
67
|
+
*
|
|
68
|
+
* Metro's Terminal.#update() is async and snapshots #nextStatusStr at the start.
|
|
69
|
+
* When _log() calls terminal.log(), Terminal starts #update() which captures
|
|
70
|
+
* whatever status is currently set — often a stale progress bar. This progress bar
|
|
71
|
+
* gets written as permanent output between log lines because the next #update()
|
|
72
|
+
* cycle (which would clear it) runs 33ms later.
|
|
73
|
+
*
|
|
74
|
+
* By clearing the status to empty before _log(), Terminal's #update() captures
|
|
75
|
+
* an empty status and doesn't write any progress bars alongside log lines.
|
|
76
|
+
* The correct status is then restored by terminal.status() at the end.
|
|
77
|
+
*/ update(event) {
|
|
78
|
+
if (event.type !== 'bundle_transform_progressed' && event.type !== 'bundle_transform_progressed_throttled') {
|
|
79
|
+
this.terminal.status('');
|
|
80
|
+
}
|
|
81
|
+
super.update(event);
|
|
82
|
+
}
|
|
65
83
|
_log(event) {
|
|
66
84
|
switch(event.type){
|
|
67
85
|
case 'transform_cache_reset':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/TerminalReporter.ts"],"sourcesContent":["// This file represents an abstraction on the metro TerminalReporter.\n// We use this abstraction to safely extend the TerminalReporter for our own custom logging.\nimport UpstreamTerminalReporter from '@expo/metro/metro/lib/TerminalReporter';\nimport type { Terminal } from '@expo/metro/metro-core';\nimport type { WatcherStatus } from '@expo/metro/metro-file-map';\nimport chalk from 'chalk';\nimport util from 'util';\n\nimport type {\n BundleDetails,\n BundleProgressUpdate,\n TerminalReportableEvent,\n TerminalReporterInterface,\n} from './TerminalReporter.types';\nimport { stripAnsi } from '../../../utils/ansi';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\n/**\n * A standard way to log a warning to the terminal. This should not be called\n * from some arbitrary Metro logic, only from the reporters. Instead of\n * calling this, add a new type of ReportableEvent instead, and implement a\n * proper handler in the reporter(s).\n */\nexport function logWarning(terminal: Terminal, format: string, ...args: any[]): void {\n const str = util.format(format, ...args);\n terminal.log('%s: %s', chalk.yellow('warning'), str);\n}\n\n/**\n * Similar to `logWarning`, but for messages that require the user to act.\n */\nexport function logError(terminal: Terminal, format: string, ...args: any[]): void {\n terminal.log(\n '%s: %s',\n chalk.red('error'),\n // Syntax errors may have colors applied for displaying code frames\n // in various places outside of where Metro is currently running.\n // If the current terminal does not support color, we'll strip the colors\n // here.\n util.format(chalk.supportsColor ? format : stripAnsi(format), ...args)\n );\n}\n\nconst XTerminalReporter = UpstreamTerminalReporter as unknown as TerminalReporterInterface;\n\n/** Extended TerminalReporter class but with proper types and extra functionality to avoid using the `_log` method directly in subclasses. */\nexport class TerminalReporter extends XTerminalReporter implements TerminalReporterInterface {\n /**\n * A cache of { [buildID]: BundleDetails } which can be used to\n * add more contextual logs. BundleDetails is currently only sent with `bundle_build_started`\n * so we need to cache the details in order to print the platform info with other event types.\n */\n _bundleDetails: Map<string, BundleDetails> = new Map();\n\n /** Keep track of how long a bundle takes to complete */\n _bundleTimers: Map<string, bigint> = new Map();\n\n /** Keep track of bundle processes that should not be logged. */\n _hiddenBundleEvents: Set<string> = new Set();\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'transform_cache_reset':\n return this.transformCacheReset();\n case 'dep_graph_loading':\n return this.dependencyGraphLoading(event.hasReducedPerformance);\n case 'client_log':\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n break;\n }\n return super._log(event);\n }\n\n /** Gives subclasses an easy interface for filtering out logs. Return `true` to skip. */\n shouldFilterClientLog(event: TerminalReportableEvent): boolean {\n return false;\n }\n\n /** Gives subclasses an easy interface for filtering out bundle events, specifically for source maps. Return `true` to skip. */\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return false;\n }\n\n /** Cache has been reset. */\n transformCacheReset(): void {}\n\n /** One of the first logs that will be printed. */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {}\n\n /**\n * Custom log event representing the end of the bundling.\n *\n * @param event event object.\n * @param duration duration of the build in milliseconds.\n */\n bundleBuildEnded(event: TerminalReportableEvent, duration: bigint | number): void {}\n\n // Add a custom format to logs that come from the worker threads.\n // `| <contents>`\n _logWorkerChunk(origin: 'stdout' | 'stderr', chunk: string): void {\n const lines = chunk.split('\\n');\n if (lines.length >= 1 && lines[lines.length - 1] === '') {\n lines.splice(lines.length - 1, 1);\n }\n\n const originTag = origin === 'stdout' ? chalk.dim('|') : chalk.yellow('|');\n lines.forEach((line: string) => {\n this.terminal.log(originTag, line);\n });\n }\n\n _logWatcherStatus(status: WatcherStatus) {\n // Metro logs this warning twice. This helps reduce the noise.\n\n if (status.type === 'watchman_warning') {\n return;\n }\n return super._logWatcherStatus(status);\n }\n\n /**\n * This function is exclusively concerned with updating the internal state.\n * No logging or status updates should be done at this point.\n */\n _updateState(\n event: TerminalReportableEvent & { bundleDetails?: BundleDetails; buildID?: string }\n ) {\n // Append the buildID to the bundleDetails.\n if (event.bundleDetails) {\n event.bundleDetails.buildID = event.buildID;\n }\n\n const buildID = event.bundleDetails?.buildID ?? event.buildID;\n\n if (buildID && !this._hiddenBundleEvents.has(buildID)) {\n if (this.shouldFilterBundleEvent(event)) {\n debug('skipping bundle events for', buildID, event);\n this._hiddenBundleEvents.add(buildID);\n } else {\n super._updateState(event);\n }\n } else {\n super._updateState(event);\n }\n\n switch (event.type) {\n case 'bundle_build_done':\n case 'bundle_build_failed': {\n const startTime = this._bundleTimers.get(event.buildID);\n // Observed a bug in Metro where the `bundle_build_done` is invoked twice during a static bundle\n // i.e. `expo export`.\n if (startTime == null) {\n break;\n }\n\n this.bundleBuildEnded(event, startTime ? process.hrtime.bigint() - startTime : 0);\n this._bundleTimers.delete(event.buildID);\n break;\n }\n case 'bundle_build_started':\n this._bundleDetails.set(event.buildID, event.bundleDetails);\n this._bundleTimers.set(event.buildID, process.hrtime.bigint());\n break;\n }\n }\n\n /**\n * We use Math.pow(ratio, 2) to as a conservative measure of progress because\n * we know the `totalCount` is going to progressively increase as well. We\n * also prevent the ratio from going backwards.\n */\n _updateBundleProgress(options: BundleProgressUpdate) {\n super._updateBundleProgress(options);\n\n const currentProgress = this._activeBundles.get(options.buildID);\n if (!currentProgress) {\n return;\n }\n\n // Fix an issue where the transformer is faster than the resolver,\n // locking the progress bar at 100% after transforming the first and only resolved file (1/1).\n if (currentProgress.ratio === 1 && options.totalFileCount === 1) {\n Object.assign(currentProgress, { ...currentProgress, ratio: 0 });\n }\n }\n}\n"],"names":["TerminalReporter","logError","logWarning","debug","require","terminal","format","args","str","util","log","chalk","yellow","red","supportsColor","stripAnsi","XTerminalReporter","UpstreamTerminalReporter","_log","event","type","transformCacheReset","dependencyGraphLoading","hasReducedPerformance","shouldFilterClientLog","shouldFilterBundleEvent","bundleBuildEnded","duration","_logWorkerChunk","origin","chunk","lines","split","length","splice","originTag","dim","forEach","line","_logWatcherStatus","status","_updateState","bundleDetails","buildID","_hiddenBundleEvents","has","add","startTime","_bundleTimers","get","process","hrtime","bigint","delete","_bundleDetails","set","_updateBundleProgress","options","currentProgress","_activeBundles","ratio","totalFileCount","Object","assign","Map","Set"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/TerminalReporter.ts"],"sourcesContent":["// This file represents an abstraction on the metro TerminalReporter.\n// We use this abstraction to safely extend the TerminalReporter for our own custom logging.\nimport UpstreamTerminalReporter from '@expo/metro/metro/lib/TerminalReporter';\nimport type { Terminal } from '@expo/metro/metro-core';\nimport type { WatcherStatus } from '@expo/metro/metro-file-map';\nimport chalk from 'chalk';\nimport util from 'util';\n\nimport type {\n BundleDetails,\n BundleProgressUpdate,\n TerminalReportableEvent,\n TerminalReporterInterface,\n} from './TerminalReporter.types';\nimport { stripAnsi } from '../../../utils/ansi';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\n/**\n * A standard way to log a warning to the terminal. This should not be called\n * from some arbitrary Metro logic, only from the reporters. Instead of\n * calling this, add a new type of ReportableEvent instead, and implement a\n * proper handler in the reporter(s).\n */\nexport function logWarning(terminal: Terminal, format: string, ...args: any[]): void {\n const str = util.format(format, ...args);\n terminal.log('%s: %s', chalk.yellow('warning'), str);\n}\n\n/**\n * Similar to `logWarning`, but for messages that require the user to act.\n */\nexport function logError(terminal: Terminal, format: string, ...args: any[]): void {\n terminal.log(\n '%s: %s',\n chalk.red('error'),\n // Syntax errors may have colors applied for displaying code frames\n // in various places outside of where Metro is currently running.\n // If the current terminal does not support color, we'll strip the colors\n // here.\n util.format(chalk.supportsColor ? format : stripAnsi(format), ...args)\n );\n}\n\nconst XTerminalReporter = UpstreamTerminalReporter as unknown as TerminalReporterInterface;\n\n/** Extended TerminalReporter class but with proper types and extra functionality to avoid using the `_log` method directly in subclasses. */\nexport class TerminalReporter extends XTerminalReporter implements TerminalReporterInterface {\n /**\n * A cache of { [buildID]: BundleDetails } which can be used to\n * add more contextual logs. BundleDetails is currently only sent with `bundle_build_started`\n * so we need to cache the details in order to print the platform info with other event types.\n */\n _bundleDetails: Map<string, BundleDetails> = new Map();\n\n /** Keep track of how long a bundle takes to complete */\n _bundleTimers: Map<string, bigint> = new Map();\n\n /** Keep track of bundle processes that should not be logged. */\n _hiddenBundleEvents: Set<string> = new Set();\n\n /**\n * Override Metro's update() to clear the status before _log() runs.\n *\n * Metro's Terminal.#update() is async and snapshots #nextStatusStr at the start.\n * When _log() calls terminal.log(), Terminal starts #update() which captures\n * whatever status is currently set — often a stale progress bar. This progress bar\n * gets written as permanent output between log lines because the next #update()\n * cycle (which would clear it) runs 33ms later.\n *\n * By clearing the status to empty before _log(), Terminal's #update() captures\n * an empty status and doesn't write any progress bars alongside log lines.\n * The correct status is then restored by terminal.status() at the end.\n */\n update(event: TerminalReportableEvent): void {\n if (\n event.type !== 'bundle_transform_progressed' &&\n event.type !== ('bundle_transform_progressed_throttled' as string)\n ) {\n this.terminal.status('');\n }\n super.update(event);\n }\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'transform_cache_reset':\n return this.transformCacheReset();\n case 'dep_graph_loading':\n return this.dependencyGraphLoading(event.hasReducedPerformance);\n case 'client_log':\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n break;\n }\n return super._log(event);\n }\n\n /** Gives subclasses an easy interface for filtering out logs. Return `true` to skip. */\n shouldFilterClientLog(event: TerminalReportableEvent): boolean {\n return false;\n }\n\n /** Gives subclasses an easy interface for filtering out bundle events, specifically for source maps. Return `true` to skip. */\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return false;\n }\n\n /** Cache has been reset. */\n transformCacheReset(): void {}\n\n /** One of the first logs that will be printed. */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {}\n\n /**\n * Custom log event representing the end of the bundling.\n *\n * @param event event object.\n * @param duration duration of the build in milliseconds.\n */\n bundleBuildEnded(event: TerminalReportableEvent, duration: bigint | number): void {}\n\n // Add a custom format to logs that come from the worker threads.\n // `| <contents>`\n _logWorkerChunk(origin: 'stdout' | 'stderr', chunk: string): void {\n const lines = chunk.split('\\n');\n if (lines.length >= 1 && lines[lines.length - 1] === '') {\n lines.splice(lines.length - 1, 1);\n }\n\n const originTag = origin === 'stdout' ? chalk.dim('|') : chalk.yellow('|');\n lines.forEach((line: string) => {\n this.terminal.log(originTag, line);\n });\n }\n\n _logWatcherStatus(status: WatcherStatus) {\n // Metro logs this warning twice. This helps reduce the noise.\n\n if (status.type === 'watchman_warning') {\n return;\n }\n return super._logWatcherStatus(status);\n }\n\n /**\n * This function is exclusively concerned with updating the internal state.\n * No logging or status updates should be done at this point.\n */\n _updateState(\n event: TerminalReportableEvent & { bundleDetails?: BundleDetails; buildID?: string }\n ) {\n // Append the buildID to the bundleDetails.\n if (event.bundleDetails) {\n event.bundleDetails.buildID = event.buildID;\n }\n\n const buildID = event.bundleDetails?.buildID ?? event.buildID;\n\n if (buildID && !this._hiddenBundleEvents.has(buildID)) {\n if (this.shouldFilterBundleEvent(event)) {\n debug('skipping bundle events for', buildID, event);\n this._hiddenBundleEvents.add(buildID);\n } else {\n super._updateState(event);\n }\n } else {\n super._updateState(event);\n }\n\n switch (event.type) {\n case 'bundle_build_done':\n case 'bundle_build_failed': {\n const startTime = this._bundleTimers.get(event.buildID);\n // Observed a bug in Metro where the `bundle_build_done` is invoked twice during a static bundle\n // i.e. `expo export`.\n if (startTime == null) {\n break;\n }\n\n this.bundleBuildEnded(event, startTime ? process.hrtime.bigint() - startTime : 0);\n this._bundleTimers.delete(event.buildID);\n break;\n }\n case 'bundle_build_started':\n this._bundleDetails.set(event.buildID, event.bundleDetails);\n this._bundleTimers.set(event.buildID, process.hrtime.bigint());\n break;\n }\n }\n\n /**\n * We use Math.pow(ratio, 2) to as a conservative measure of progress because\n * we know the `totalCount` is going to progressively increase as well. We\n * also prevent the ratio from going backwards.\n */\n _updateBundleProgress(options: BundleProgressUpdate) {\n super._updateBundleProgress(options);\n\n const currentProgress = this._activeBundles.get(options.buildID);\n if (!currentProgress) {\n return;\n }\n\n // Fix an issue where the transformer is faster than the resolver,\n // locking the progress bar at 100% after transforming the first and only resolved file (1/1).\n if (currentProgress.ratio === 1 && options.totalFileCount === 1) {\n Object.assign(currentProgress, { ...currentProgress, ratio: 0 });\n }\n }\n}\n"],"names":["TerminalReporter","logError","logWarning","debug","require","terminal","format","args","str","util","log","chalk","yellow","red","supportsColor","stripAnsi","XTerminalReporter","UpstreamTerminalReporter","update","event","type","status","_log","transformCacheReset","dependencyGraphLoading","hasReducedPerformance","shouldFilterClientLog","shouldFilterBundleEvent","bundleBuildEnded","duration","_logWorkerChunk","origin","chunk","lines","split","length","splice","originTag","dim","forEach","line","_logWatcherStatus","_updateState","bundleDetails","buildID","_hiddenBundleEvents","has","add","startTime","_bundleTimers","get","process","hrtime","bigint","delete","_bundleDetails","set","_updateBundleProgress","options","currentProgress","_activeBundles","ratio","totalFileCount","Object","assign","Map","Set"],"mappings":"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"}
|
|
@@ -45,6 +45,7 @@ function _nodepath() {
|
|
|
45
45
|
};
|
|
46
46
|
return data;
|
|
47
47
|
}
|
|
48
|
+
const _composeMetroIgnorePatterns = require("../../../utils/composeMetroIgnorePatterns");
|
|
48
49
|
function _interop_require_default(obj) {
|
|
49
50
|
return obj && obj.__esModule ? obj : {
|
|
50
51
|
default: obj
|
|
@@ -93,23 +94,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
93
94
|
}
|
|
94
95
|
function getIgnorePattern(config) {
|
|
95
96
|
const { blockList, blacklistRE } = config.resolver;
|
|
96
|
-
|
|
97
|
-
if (!ignorePattern) {
|
|
98
|
-
return / ^/;
|
|
99
|
-
}
|
|
100
|
-
const combine = (regexes)=>{
|
|
101
|
-
var _regexes_;
|
|
102
|
-
return new RegExp(regexes.map((regex, index)=>{
|
|
103
|
-
if (regex.flags !== regexes[0].flags) {
|
|
104
|
-
throw new Error('Cannot combine blockList patterns, because they have different flags:\n' + ' - Pattern 0: ' + regexes[0].toString() + '\n' + ` - Pattern ${index}: ` + regexes[index].toString());
|
|
105
|
-
}
|
|
106
|
-
return '(' + regex.source + ')';
|
|
107
|
-
}).join('|'), ((_regexes_ = regexes[0]) == null ? void 0 : _regexes_.flags) ?? '');
|
|
108
|
-
};
|
|
109
|
-
if (Array.isArray(ignorePattern)) {
|
|
110
|
-
return combine(ignorePattern);
|
|
111
|
-
}
|
|
112
|
-
return ignorePattern;
|
|
97
|
+
return (0, _composeMetroIgnorePatterns.composeMetroIgnorePatterns)(blacklistRE || blockList);
|
|
113
98
|
}
|
|
114
99
|
function createFileMap(config, options) {
|
|
115
100
|
const watch = (options == null ? void 0 : options.watch) == null ? !_ciinfo().default.isCI : options.watch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/createFileMap-fork.ts"],"sourcesContent":["// Copyright © 2024 650 Industries.\n// Copyright (c) Meta Platforms, Inc. and affiliates.\n//\n// Forks https://github.com/facebook/metro/blob/01b4ad6/packages/metro/src/node-haste/DependencyGraph/createFileMap.js\n// and redirects to `@expo/metro-file-map`\n\nimport type MetroServer from '@expo/metro/metro/Server';\nimport type { ConfigT } from '@expo/metro/metro-config';\nimport FileMap, { DependencyPlugin, DiskCacheManager, HastePlugin } from '@expo/metro-file-map';\nimport ciInfo from 'ci-info';\nimport path from 'node:path';\n\nfunction getIgnorePattern(config: ConfigT): RegExp {\n const { blockList, blacklistRE } = config.resolver;\n const ignorePattern = blacklistRE || blockList;\n if (!ignorePattern) {\n return / ^/;\n }\n const combine = (regexes: RegExp[]) =>\n new RegExp(\n regexes\n .map((regex, index) => {\n if (regex.flags !== regexes[0]!.flags) {\n throw new Error(\n 'Cannot combine blockList patterns, because they have different flags:\\n' +\n ' - Pattern 0: ' +\n regexes[0]!.toString() +\n '\\n' +\n ` - Pattern ${index}: ` +\n regexes[index]!.toString()\n );\n }\n return '(' + regex.source + ')';\n })\n .join('|'),\n regexes[0]?.flags ?? ''\n );\n if (Array.isArray(ignorePattern)) {\n return combine(ignorePattern);\n }\n return ignorePattern;\n}\n\ninterface CreateFileMapOptions {\n extractDependencies?: boolean;\n throwOnModuleCollision?: boolean;\n watch?: boolean;\n cacheFilePrefix?: string;\n}\n\n/**\n * Creates a `FileMap` using `@expo/metro-file-map`, matching the same config\n * interpretation as Metro's original `createFileMap`.\n */\nexport default function createFileMap(config: ConfigT, options?: CreateFileMapOptions) {\n const watch = options?.watch == null ? !ciInfo.isCI : options.watch;\n\n const { enabled: autoSaveEnabled, ...autoSaveOpts } = config.watcher.unstable_autoSaveCache ?? {};\n const autoSave = watch && autoSaveEnabled ? autoSaveOpts : false;\n\n const plugins = [...(config.unstable_fileMapPlugins ?? [])];\n let dependencyPlugin: DependencyPlugin | null = null;\n\n if (config.resolver.dependencyExtractor != null && options?.extractDependencies !== false) {\n dependencyPlugin = new DependencyPlugin({\n dependencyExtractor: config.resolver.dependencyExtractor,\n computeDependencies: true,\n });\n plugins.push(dependencyPlugin);\n }\n\n const hasteMap = new HastePlugin({\n platforms: new Set([...config.resolver.platforms, FileMap.H.NATIVE_PLATFORM]),\n hasteImplModulePath: config.resolver.hasteImplModulePath ?? null,\n enableHastePackages: config.resolver.enableGlobalPackages,\n rootDir: config.projectRoot,\n failValidationOnConflicts: options?.throwOnModuleCollision ?? true,\n });\n plugins.push(hasteMap);\n\n const projectRoot = config.projectRoot;\n const serverRoot = config.server.unstable_serverRoot;\n const enableFallback = !!config.resolver.unstable_onDemandFilesystem;\n\n // NOTE(@kitten): We allow the on-demand filesystem to escape the server root and access any file,\n // - if we're using the CLI from `expo/expo` on an external project (e.g. in CI(\n // - if the user explicitly sets the experimental flag to 'UNSTABLE_ALLOW_ALL'\n const scopeFallback =\n enableFallback &&\n config.resolver.unstable_onDemandFilesystem !== 'UNSTABLE_ALLOW_ALL' &&\n isDirectoryIn(__dirname, serverRoot ?? projectRoot);\n\n const fileMap = new FileMap({\n // NOTE(@kitten): Dropped `config.unstable_fileMapCacheManagerFactory`\n cacheManagerFactory: (factoryParams: any) => {\n return new DiskCacheManager(factoryParams, {\n cacheDirectory: config.fileMapCacheDirectory ?? config.hasteMapCacheDirectory,\n cacheFilePrefix: options?.cacheFilePrefix,\n autoSave,\n });\n },\n perfLoggerFactory: config.unstable_perfLoggerFactory,\n computeSha1: !config.watcher.unstable_lazySha1,\n enableSymlinks: true,\n // NOTE(@kitten): @expo/metro-file-map fork adds `enableFallback` and `scopeFallback`\n enableFallback,\n scopeFallback,\n extensions: Array.from(\n new Set([\n ...config.resolver.sourceExts,\n ...config.resolver.assetExts,\n ...config.watcher.additionalExts,\n ])\n ),\n healthCheck: config.watcher.healthCheck,\n ignorePattern: getIgnorePattern(config),\n maxWorkers: config.maxWorkers,\n plugins,\n retainAllFiles: true,\n resetCache: config.resetCache,\n rootDir: projectRoot,\n roots: config.watchFolders,\n useWatchman: config.resolver.useWatchman ?? false,\n watch,\n watchmanDeferStates: config.watcher.watchman.deferStates,\n // NOTE: (@expo/metro-file-map fork) New option is required for `scopeFallback: true` checks\n serverRoot,\n });\n\n return {\n fileMap,\n hasteMap,\n dependencyPlugin,\n };\n}\n\nfunction isDirectoryIn(targetPath: string, rootPath: string) {\n return targetPath === rootPath || targetPath.startsWith(rootPath + path.sep);\n}\n\nfunction assertMetroFileMapPatched(metro: { getBundler(): any }): void {\n const depGraph = metro.getBundler().getBundler()?._depGraph;\n const fileMap = depGraph?._haste;\n if (!fileMap || !fileMap.__expo) {\n throw new Error(\n '@expo/metro-file-map was not used by Metro. ' +\n \"The DependencyGraph's file map does not have the __expo flag, \" +\n 'which means the createFileMap module export was not replaced before ' +\n 'Metro instantiated. Ensure replaceMetroFileMap() is called before runServer().'\n );\n }\n}\n\nexport async function replaceMetroFileMap<T extends { readonly metro: MetroServer }>(\n immediate: () => T | PromiseLike<T>\n): Promise<T> {\n const createFileMapModule = require('@expo/metro/metro/node-haste/DependencyGraph/createFileMap');\n Object.defineProperty(createFileMapModule, 'default', {\n enumerable: true,\n configurable: false,\n writable: false,\n value: createFileMap,\n });\n const result = await immediate();\n assertMetroFileMapPatched(result.metro);\n return result;\n}\n"],"names":["createFileMap","replaceMetroFileMap","getIgnorePattern","config","blockList","blacklistRE","resolver","ignorePattern","combine","regexes","RegExp","map","regex","index","flags","Error","toString","source","join","Array","isArray","options","watch","ciInfo","isCI","enabled","autoSaveEnabled","autoSaveOpts","watcher","unstable_autoSaveCache","autoSave","plugins","unstable_fileMapPlugins","dependencyPlugin","dependencyExtractor","extractDependencies","DependencyPlugin","computeDependencies","push","hasteMap","HastePlugin","platforms","Set","FileMap","H","NATIVE_PLATFORM","hasteImplModulePath","enableHastePackages","enableGlobalPackages","rootDir","projectRoot","failValidationOnConflicts","throwOnModuleCollision","serverRoot","server","unstable_serverRoot","enableFallback","unstable_onDemandFilesystem","scopeFallback","isDirectoryIn","__dirname","fileMap","cacheManagerFactory","factoryParams","DiskCacheManager","cacheDirectory","fileMapCacheDirectory","hasteMapCacheDirectory","cacheFilePrefix","perfLoggerFactory","unstable_perfLoggerFactory","computeSha1","unstable_lazySha1","enableSymlinks","extensions","from","sourceExts","assetExts","additionalExts","healthCheck","maxWorkers","retainAllFiles","resetCache","roots","watchFolders","useWatchman","watchmanDeferStates","watchman","deferStates","targetPath","rootPath","startsWith","path","sep","assertMetroFileMapPatched","metro","depGraph","getBundler","_depGraph","_haste","__expo","immediate","createFileMapModule","require","Object","defineProperty","enumerable","configurable","writable","value","result"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/createFileMap-fork.ts"],"sourcesContent":["// Copyright © 2024 650 Industries.\n// Copyright (c) Meta Platforms, Inc. and affiliates.\n//\n// Forks https://github.com/facebook/metro/blob/01b4ad6/packages/metro/src/node-haste/DependencyGraph/createFileMap.js\n// and redirects to `@expo/metro-file-map`\n\nimport type MetroServer from '@expo/metro/metro/Server';\nimport type { ConfigT } from '@expo/metro/metro-config';\nimport FileMap, { DependencyPlugin, DiskCacheManager, HastePlugin } from '@expo/metro-file-map';\nimport ciInfo from 'ci-info';\nimport path from 'node:path';\n\nimport { composeMetroIgnorePatterns } from '../../../utils/composeMetroIgnorePatterns';\n\nfunction getIgnorePattern(config: ConfigT): RegExp {\n const { blockList, blacklistRE } = config.resolver;\n return composeMetroIgnorePatterns(blacklistRE || blockList);\n}\n\ninterface CreateFileMapOptions {\n extractDependencies?: boolean;\n throwOnModuleCollision?: boolean;\n watch?: boolean;\n cacheFilePrefix?: string;\n}\n\n/**\n * Creates a `FileMap` using `@expo/metro-file-map`, matching the same config\n * interpretation as Metro's original `createFileMap`.\n */\nexport default function createFileMap(config: ConfigT, options?: CreateFileMapOptions) {\n const watch = options?.watch == null ? !ciInfo.isCI : options.watch;\n\n const { enabled: autoSaveEnabled, ...autoSaveOpts } = config.watcher.unstable_autoSaveCache ?? {};\n const autoSave = watch && autoSaveEnabled ? autoSaveOpts : false;\n\n const plugins = [...(config.unstable_fileMapPlugins ?? [])];\n let dependencyPlugin: DependencyPlugin | null = null;\n\n if (config.resolver.dependencyExtractor != null && options?.extractDependencies !== false) {\n dependencyPlugin = new DependencyPlugin({\n dependencyExtractor: config.resolver.dependencyExtractor,\n computeDependencies: true,\n });\n plugins.push(dependencyPlugin);\n }\n\n const hasteMap = new HastePlugin({\n platforms: new Set([...config.resolver.platforms, FileMap.H.NATIVE_PLATFORM]),\n hasteImplModulePath: config.resolver.hasteImplModulePath ?? null,\n enableHastePackages: config.resolver.enableGlobalPackages,\n rootDir: config.projectRoot,\n failValidationOnConflicts: options?.throwOnModuleCollision ?? true,\n });\n plugins.push(hasteMap);\n\n const projectRoot = config.projectRoot;\n const serverRoot = config.server.unstable_serverRoot;\n const enableFallback = !!config.resolver.unstable_onDemandFilesystem;\n\n // NOTE(@kitten): We allow the on-demand filesystem to escape the server root and access any file,\n // - if we're using the CLI from `expo/expo` on an external project (e.g. in CI(\n // - if the user explicitly sets the experimental flag to 'UNSTABLE_ALLOW_ALL'\n const scopeFallback =\n enableFallback &&\n config.resolver.unstable_onDemandFilesystem !== 'UNSTABLE_ALLOW_ALL' &&\n isDirectoryIn(__dirname, serverRoot ?? projectRoot);\n\n const fileMap = new FileMap({\n // NOTE(@kitten): Dropped `config.unstable_fileMapCacheManagerFactory`\n cacheManagerFactory: (factoryParams: any) => {\n return new DiskCacheManager(factoryParams, {\n cacheDirectory: config.fileMapCacheDirectory ?? config.hasteMapCacheDirectory,\n cacheFilePrefix: options?.cacheFilePrefix,\n autoSave,\n });\n },\n perfLoggerFactory: config.unstable_perfLoggerFactory,\n computeSha1: !config.watcher.unstable_lazySha1,\n enableSymlinks: true,\n // NOTE(@kitten): @expo/metro-file-map fork adds `enableFallback` and `scopeFallback`\n enableFallback,\n scopeFallback,\n extensions: Array.from(\n new Set([\n ...config.resolver.sourceExts,\n ...config.resolver.assetExts,\n ...config.watcher.additionalExts,\n ])\n ),\n healthCheck: config.watcher.healthCheck,\n ignorePattern: getIgnorePattern(config),\n maxWorkers: config.maxWorkers,\n plugins,\n retainAllFiles: true,\n resetCache: config.resetCache,\n rootDir: projectRoot,\n roots: config.watchFolders,\n useWatchman: config.resolver.useWatchman ?? false,\n watch,\n watchmanDeferStates: config.watcher.watchman.deferStates,\n // NOTE: (@expo/metro-file-map fork) New option is required for `scopeFallback: true` checks\n serverRoot,\n });\n\n return {\n fileMap,\n hasteMap,\n dependencyPlugin,\n };\n}\n\nfunction isDirectoryIn(targetPath: string, rootPath: string) {\n return targetPath === rootPath || targetPath.startsWith(rootPath + path.sep);\n}\n\nfunction assertMetroFileMapPatched(metro: { getBundler(): any }): void {\n const depGraph = metro.getBundler().getBundler()?._depGraph;\n const fileMap = depGraph?._haste;\n if (!fileMap || !fileMap.__expo) {\n throw new Error(\n '@expo/metro-file-map was not used by Metro. ' +\n \"The DependencyGraph's file map does not have the __expo flag, \" +\n 'which means the createFileMap module export was not replaced before ' +\n 'Metro instantiated. Ensure replaceMetroFileMap() is called before runServer().'\n );\n }\n}\n\nexport async function replaceMetroFileMap<T extends { readonly metro: MetroServer }>(\n immediate: () => T | PromiseLike<T>\n): Promise<T> {\n const createFileMapModule = require('@expo/metro/metro/node-haste/DependencyGraph/createFileMap');\n Object.defineProperty(createFileMapModule, 'default', {\n enumerable: true,\n configurable: false,\n writable: false,\n value: createFileMap,\n });\n const result = await immediate();\n assertMetroFileMapPatched(result.metro);\n return result;\n}\n"],"names":["createFileMap","replaceMetroFileMap","getIgnorePattern","config","blockList","blacklistRE","resolver","composeMetroIgnorePatterns","options","watch","ciInfo","isCI","enabled","autoSaveEnabled","autoSaveOpts","watcher","unstable_autoSaveCache","autoSave","plugins","unstable_fileMapPlugins","dependencyPlugin","dependencyExtractor","extractDependencies","DependencyPlugin","computeDependencies","push","hasteMap","HastePlugin","platforms","Set","FileMap","H","NATIVE_PLATFORM","hasteImplModulePath","enableHastePackages","enableGlobalPackages","rootDir","projectRoot","failValidationOnConflicts","throwOnModuleCollision","serverRoot","server","unstable_serverRoot","enableFallback","unstable_onDemandFilesystem","scopeFallback","isDirectoryIn","__dirname","fileMap","cacheManagerFactory","factoryParams","DiskCacheManager","cacheDirectory","fileMapCacheDirectory","hasteMapCacheDirectory","cacheFilePrefix","perfLoggerFactory","unstable_perfLoggerFactory","computeSha1","unstable_lazySha1","enableSymlinks","extensions","Array","from","sourceExts","assetExts","additionalExts","healthCheck","ignorePattern","maxWorkers","retainAllFiles","resetCache","roots","watchFolders","useWatchman","watchmanDeferStates","watchman","deferStates","targetPath","rootPath","startsWith","path","sep","assertMetroFileMapPatched","metro","depGraph","getBundler","_depGraph","_haste","__expo","Error","immediate","createFileMapModule","require","Object","defineProperty","enumerable","configurable","writable","value","result"],"mappings":"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"}
|
|
@@ -120,12 +120,22 @@ const event = (0, _events.events)('metro', (t)=>[
|
|
|
120
120
|
function asWritable(input) {
|
|
121
121
|
return input;
|
|
122
122
|
}
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Extends Metro's Terminal to intercept all console methods so they don't
|
|
125
|
+
* corrupt the progress bar status lines.
|
|
126
|
+
*
|
|
127
|
+
* console.log/info are routed through terminal.log() (stdout, managed).
|
|
128
|
+
* console.warn/error are routed through logStderr() which clears the
|
|
129
|
+
* status from stdout before writing to stderr, then restores it.
|
|
130
|
+
* Without this, unmanaged stderr writes shift the cursor and cause
|
|
131
|
+
* progress bars to get stuck as permanent output.
|
|
132
|
+
*/ class LogRespectingTerminal extends _metrocore().Terminal {
|
|
133
|
+
#stderrQueue;
|
|
134
|
+
#drainingStderr;
|
|
125
135
|
constructor(stream){
|
|
126
136
|
super(stream, {
|
|
127
137
|
ttyPrint: true
|
|
128
|
-
});
|
|
138
|
+
}), this.#stderrQueue = [], this.#drainingStderr = false;
|
|
129
139
|
const sendLog = (...msg)=>{
|
|
130
140
|
if (!msg.length) {
|
|
131
141
|
this.log('');
|
|
@@ -136,8 +146,41 @@ class LogRespectingTerminal extends _metrocore().Terminal {
|
|
|
136
146
|
// Flush the logs to the terminal immediately so logs at the end of the process are not lost.
|
|
137
147
|
this.flush();
|
|
138
148
|
};
|
|
149
|
+
const sendStderr = (...msg)=>{
|
|
150
|
+
if (!msg.length) {
|
|
151
|
+
this.logStderr('');
|
|
152
|
+
} else {
|
|
153
|
+
const [format, ...args] = msg;
|
|
154
|
+
this.logStderr(require('util').format(format, ...args));
|
|
155
|
+
}
|
|
156
|
+
};
|
|
139
157
|
console.log = sendLog;
|
|
140
158
|
console.info = sendLog;
|
|
159
|
+
console.warn = sendStderr;
|
|
160
|
+
console.error = sendStderr;
|
|
161
|
+
}
|
|
162
|
+
/** Write to stderr without corrupting Terminal's cursor tracking. */ logStderr(line) {
|
|
163
|
+
if (!process.stdout.isTTY) {
|
|
164
|
+
process.stderr.write(line + '\n');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
this.#stderrQueue.push(line);
|
|
168
|
+
this.#drainStderr();
|
|
169
|
+
}
|
|
170
|
+
async #drainStderr() {
|
|
171
|
+
if (this.#drainingStderr) return;
|
|
172
|
+
this.#drainingStderr = true;
|
|
173
|
+
while(this.#stderrQueue.length > 0){
|
|
174
|
+
// Clear status, flush to ensure it's removed from screen
|
|
175
|
+
const prev = this.status('');
|
|
176
|
+
await this.flush();
|
|
177
|
+
// Write to stderr while status is cleared
|
|
178
|
+
const lines = this.#stderrQueue.splice(0);
|
|
179
|
+
process.stderr.write(lines.join('\n') + '\n');
|
|
180
|
+
// Restore status
|
|
181
|
+
this.status(prev);
|
|
182
|
+
}
|
|
183
|
+
this.#drainingStderr = false;
|
|
141
184
|
}
|
|
142
185
|
}
|
|
143
186
|
// Share one instance of Terminal for all instances of Metro.
|