@expo/cli 55.0.8 → 55.0.10
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 +5 -1
- package/build/bin/cli.map +1 -1
- package/build/src/events/builder.js +6 -0
- package/build/src/events/builder.js.map +1 -0
- package/build/src/events/index.js +123 -0
- package/build/src/events/index.js.map +1 -0
- package/build/src/events/stream.js +303 -0
- package/build/src/events/stream.js.map +1 -0
- package/build/src/events/types.js +6 -0
- package/build/src/events/types.js.map +1 -0
- package/build/src/run/android/resolveGradlePropsAsync.js +22 -9
- package/build/src/run/android/resolveGradlePropsAsync.js.map +1 -1
- package/build/src/start/interface/interactiveActions.js +15 -13
- package/build/src/start/interface/interactiveActions.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +178 -78
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +8 -0
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/metroErrorInterface.js +3 -5
- package/build/src/start/server/metro/metroErrorInterface.js.map +1 -1
- package/build/src/utils/env.js +3 -0
- package/build/src/utils/env.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 +7 -7
|
@@ -40,25 +40,38 @@ async function resolveGradlePropsAsync(projectRoot, options, device) {
|
|
|
40
40
|
// NOTE(EvanBacon): Why would this be different? Can we get the different name?
|
|
41
41
|
const appName = 'app';
|
|
42
42
|
const apkDirectory = _path().default.join(projectRoot, 'android', appName, 'build', 'outputs', 'apk');
|
|
43
|
-
// buildDeveloperTrust -> buildtype: trust, flavors:
|
|
43
|
+
// buildDeveloperTrust -> buildtype: trust, flavors: buildDeveloper
|
|
44
44
|
// developmentDebug -> buildType: debug, flavors: development
|
|
45
45
|
// productionRelease -> buildType: release, flavors: production
|
|
46
|
-
//
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
// previewDebugOptimized -> buildType: debugOptimized, flavors: preview
|
|
47
|
+
const parts = variant.split(/(?=[A-Z])/);
|
|
48
|
+
// Special case: merge 'Optimized' suffix with preceding part, e.g. into 'debugOptimized'
|
|
49
|
+
let buildType = parts.pop() ?? 'debug';
|
|
50
|
+
if (parts.length > 0 && buildType === 'Optimized') {
|
|
51
|
+
buildType = parts.pop().toLowerCase() + buildType;
|
|
52
|
+
} else {
|
|
53
|
+
buildType = buildType.toLowerCase();
|
|
54
|
+
}
|
|
55
|
+
let apkVariantDirectory;
|
|
56
|
+
if (parts.length > 0) {
|
|
57
|
+
const flavorPath = parts[0].toLowerCase() + parts.slice(1).join('');
|
|
58
|
+
apkVariantDirectory = _path().default.join(apkDirectory, flavorPath, buildType);
|
|
59
|
+
} else {
|
|
60
|
+
apkVariantDirectory = _path().default.join(apkDirectory, buildType);
|
|
61
|
+
}
|
|
51
62
|
return {
|
|
52
63
|
appName,
|
|
53
64
|
buildType,
|
|
54
|
-
flavors,
|
|
65
|
+
flavors: parts.map((v)=>v.toLowerCase()),
|
|
55
66
|
apkVariantDirectory,
|
|
56
|
-
architectures
|
|
67
|
+
architectures: await getConnectedDeviceABIS(buildType, device, options.allArch)
|
|
57
68
|
};
|
|
58
69
|
}
|
|
59
70
|
async function getConnectedDeviceABIS(buildType, device, allArch) {
|
|
60
71
|
// Follow the same behavior as iOS, only enable this for debug builds
|
|
61
|
-
|
|
72
|
+
// Support both 'debug' and 'debugOptimized' build types
|
|
73
|
+
const isDebugBuild = buildType === 'debug' || buildType === 'debugOptimized';
|
|
74
|
+
if (allArch || !isDebugBuild) {
|
|
62
75
|
return '';
|
|
63
76
|
}
|
|
64
77
|
const abis = await (0, _adb.getDeviceABIsAsync)(device);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/run/android/resolveGradlePropsAsync.ts"],"sourcesContent":["import path from 'path';\n\nimport { Device, getDeviceABIsAsync } from '../../start/platforms/android/adb';\nimport { CommandError } from '../../utils/errors';\n\n// Supported ABIs for Android. see https://developer.android.com/ndk/guides/abis\nconst VALID_ARCHITECTURES = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'];\n\nexport type GradleProps = {\n /** Directory for the APK based on the `variant`. */\n apkVariantDirectory: string;\n /** Name of the app, used in the `apkVariantDirectory`. */\n appName: string;\n /** Last section of the provided `variant`, indicates the starting directory of the file name for the output APK. E.g. \"debug\" or \"release\" */\n buildType: string;\n /** Used to assemble the APK, also included in the output APK filename. */\n flavors?: string[];\n /** Architectures to build for. */\n architectures?: string;\n};\n\nfunction assertVariant(variant?: string) {\n if (variant && typeof variant !== 'string') {\n throw new CommandError('BAD_ARGS', '--variant must be a string');\n }\n return variant ?? 'debug';\n}\n\nexport async function resolveGradlePropsAsync(\n projectRoot: string,\n options: { variant?: string; allArch?: boolean },\n device: Device\n): Promise<GradleProps> {\n const variant = assertVariant(options.variant);\n // NOTE(EvanBacon): Why would this be different? Can we get the different name?\n const appName = 'app';\n\n const apkDirectory = path.join(projectRoot, 'android', appName, 'build', 'outputs', 'apk');\n\n // buildDeveloperTrust -> buildtype: trust, flavors:
|
|
1
|
+
{"version":3,"sources":["../../../../src/run/android/resolveGradlePropsAsync.ts"],"sourcesContent":["import path from 'path';\n\nimport { Device, getDeviceABIsAsync } from '../../start/platforms/android/adb';\nimport { CommandError } from '../../utils/errors';\n\n// Supported ABIs for Android. see https://developer.android.com/ndk/guides/abis\nconst VALID_ARCHITECTURES = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'];\n\nexport type GradleProps = {\n /** Directory for the APK based on the `variant`. */\n apkVariantDirectory: string;\n /** Name of the app, used in the `apkVariantDirectory`. */\n appName: string;\n /** Last section of the provided `variant`, indicates the starting directory of the file name for the output APK. E.g. \"debug\" or \"release\" */\n buildType: string;\n /** Used to assemble the APK, also included in the output APK filename. */\n flavors?: string[];\n /** Architectures to build for. */\n architectures?: string;\n};\n\nfunction assertVariant(variant?: string) {\n if (variant && typeof variant !== 'string') {\n throw new CommandError('BAD_ARGS', '--variant must be a string');\n }\n return variant ?? 'debug';\n}\n\nexport async function resolveGradlePropsAsync(\n projectRoot: string,\n options: { variant?: string; allArch?: boolean },\n device: Device\n): Promise<GradleProps> {\n const variant = assertVariant(options.variant);\n // NOTE(EvanBacon): Why would this be different? Can we get the different name?\n const appName = 'app';\n\n const apkDirectory = path.join(projectRoot, 'android', appName, 'build', 'outputs', 'apk');\n\n // buildDeveloperTrust -> buildtype: trust, flavors: buildDeveloper\n // developmentDebug -> buildType: debug, flavors: development\n // productionRelease -> buildType: release, flavors: production\n // previewDebugOptimized -> buildType: debugOptimized, flavors: preview\n const parts = variant.split(/(?=[A-Z])/);\n\n // Special case: merge 'Optimized' suffix with preceding part, e.g. into 'debugOptimized'\n let buildType = parts.pop() ?? 'debug';\n if (parts.length > 0 && buildType === 'Optimized') {\n buildType = parts.pop()!.toLowerCase() + buildType;\n } else {\n buildType = buildType.toLowerCase();\n }\n\n let apkVariantDirectory: string;\n if (parts.length > 0) {\n const flavorPath = parts[0].toLowerCase() + parts.slice(1).join('');\n apkVariantDirectory = path.join(apkDirectory, flavorPath, buildType);\n } else {\n apkVariantDirectory = path.join(apkDirectory, buildType);\n }\n\n return {\n appName,\n buildType,\n flavors: parts.map((v) => v.toLowerCase()),\n apkVariantDirectory,\n architectures: await getConnectedDeviceABIS(buildType, device, options.allArch),\n };\n}\n\nasync function getConnectedDeviceABIS(\n buildType: string,\n device: Device,\n allArch?: boolean\n): Promise<string> {\n // Follow the same behavior as iOS, only enable this for debug builds\n // Support both 'debug' and 'debugOptimized' build types\n const isDebugBuild = buildType === 'debug' || buildType === 'debugOptimized';\n if (allArch || !isDebugBuild) {\n return '';\n }\n\n const abis = await getDeviceABIsAsync(device);\n\n const validAbis = abis.filter((abi) => VALID_ARCHITECTURES.includes(abi));\n return validAbis.filter((abi, i, arr) => arr.indexOf(abi) === i).join(',');\n}\n"],"names":["resolveGradlePropsAsync","VALID_ARCHITECTURES","assertVariant","variant","CommandError","projectRoot","options","device","appName","apkDirectory","path","join","parts","split","buildType","pop","length","toLowerCase","apkVariantDirectory","flavorPath","slice","flavors","map","v","architectures","getConnectedDeviceABIS","allArch","isDebugBuild","abis","getDeviceABIsAsync","validAbis","filter","abi","includes","i","arr","indexOf"],"mappings":";;;;+BA4BsBA;;;eAAAA;;;;gEA5BL;;;;;;qBAE0B;wBACd;;;;;;AAE7B,gFAAgF;AAChF,MAAMC,sBAAsB;IAAC;IAAe;IAAa;IAAO;CAAS;AAezE,SAASC,cAAcC,OAAgB;IACrC,IAAIA,WAAW,OAAOA,YAAY,UAAU;QAC1C,MAAM,IAAIC,oBAAY,CAAC,YAAY;IACrC;IACA,OAAOD,WAAW;AACpB;AAEO,eAAeH,wBACpBK,WAAmB,EACnBC,OAAgD,EAChDC,MAAc;IAEd,MAAMJ,UAAUD,cAAcI,QAAQH,OAAO;IAC7C,+EAA+E;IAC/E,MAAMK,UAAU;IAEhB,MAAMC,eAAeC,eAAI,CAACC,IAAI,CAACN,aAAa,WAAWG,SAAS,SAAS,WAAW;IAEpF,mEAAmE;IACnE,6DAA6D;IAC7D,+DAA+D;IAC/D,uEAAuE;IACvE,MAAMI,QAAQT,QAAQU,KAAK,CAAC;IAE5B,yFAAyF;IACzF,IAAIC,YAAYF,MAAMG,GAAG,MAAM;IAC/B,IAAIH,MAAMI,MAAM,GAAG,KAAKF,cAAc,aAAa;QACjDA,YAAYF,MAAMG,GAAG,GAAIE,WAAW,KAAKH;IAC3C,OAAO;QACLA,YAAYA,UAAUG,WAAW;IACnC;IAEA,IAAIC;IACJ,IAAIN,MAAMI,MAAM,GAAG,GAAG;QACpB,MAAMG,aAAaP,KAAK,CAAC,EAAE,CAACK,WAAW,KAAKL,MAAMQ,KAAK,CAAC,GAAGT,IAAI,CAAC;QAChEO,sBAAsBR,eAAI,CAACC,IAAI,CAACF,cAAcU,YAAYL;IAC5D,OAAO;QACLI,sBAAsBR,eAAI,CAACC,IAAI,CAACF,cAAcK;IAChD;IAEA,OAAO;QACLN;QACAM;QACAO,SAAST,MAAMU,GAAG,CAAC,CAACC,IAAMA,EAAEN,WAAW;QACvCC;QACAM,eAAe,MAAMC,uBAAuBX,WAAWP,QAAQD,QAAQoB,OAAO;IAChF;AACF;AAEA,eAAeD,uBACbX,SAAiB,EACjBP,MAAc,EACdmB,OAAiB;IAEjB,qEAAqE;IACrE,wDAAwD;IACxD,MAAMC,eAAeb,cAAc,WAAWA,cAAc;IAC5D,IAAIY,WAAW,CAACC,cAAc;QAC5B,OAAO;IACT;IAEA,MAAMC,OAAO,MAAMC,IAAAA,uBAAkB,EAACtB;IAEtC,MAAMuB,YAAYF,KAAKG,MAAM,CAAC,CAACC,MAAQ/B,oBAAoBgC,QAAQ,CAACD;IACpE,OAAOF,UAAUC,MAAM,CAAC,CAACC,KAAKE,GAAGC,MAAQA,IAAIC,OAAO,CAACJ,SAASE,GAAGvB,IAAI,CAAC;AACxE"}
|
|
@@ -92,20 +92,22 @@ class DevServerManagerActions {
|
|
|
92
92
|
})}`);
|
|
93
93
|
rows--;
|
|
94
94
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
if (!_env.env.EXPO_NO_QR_CODE) {
|
|
96
|
+
const qr = (0, _qr.printQRCode)(interstitialPageUrl ?? nativeRuntimeUrl);
|
|
97
|
+
rows -= qr.lines;
|
|
98
|
+
qr.print();
|
|
99
|
+
let qrMessage = '';
|
|
100
|
+
if (!options.devClient) {
|
|
101
|
+
qrMessage = `Scan the QR code above to open in ${(0, _chalk().default)`{bold Expo Go}`}.`;
|
|
102
|
+
} else {
|
|
103
|
+
qrMessage = (0, _chalk().default)`Scan the QR code above to open in a {bold development build}.`;
|
|
104
|
+
qrMessage += ` (${(0, _link.learnMore)('https://expo.fyi/start')})`;
|
|
105
|
+
}
|
|
106
|
+
rows--;
|
|
107
|
+
_log.log((0, _commandsTable.printItem)(qrMessage, {
|
|
108
|
+
dim: true
|
|
109
|
+
}));
|
|
104
110
|
}
|
|
105
|
-
rows--;
|
|
106
|
-
_log.log((0, _commandsTable.printItem)(qrMessage, {
|
|
107
|
-
dim: true
|
|
108
|
-
}));
|
|
109
111
|
if (interstitialPageUrl) {
|
|
110
112
|
rows--;
|
|
111
113
|
_log.log((0, _commandsTable.printItem)((0, _chalk().default)`Choose an app to open your project at {underline ${interstitialPageUrl}}`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/interface/interactiveActions.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { BLT, printHelp, printItem, printUsage, StartOptions } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport { ExpoChoice, selectAsync } from '../../utils/prompts';\nimport { printQRCode } from '../../utils/qr';\nimport { DevServerManager } from '../server/DevServerManager';\nimport {\n openJsInspector,\n queryAllInspectorAppsAsync,\n promptInspectorAppAsync,\n} from '../server/middleware/inspector/JsInspector';\n\nconst debug = require('debug')('expo:start:interface:interactiveActions') as typeof console.log;\n\ninterface MoreToolMenuItem extends ExpoChoice<string> {\n action?: () => unknown;\n}\n\n/** Wraps the DevServerManager and adds an interface for user actions. */\nexport class DevServerManagerActions {\n constructor(\n private devServerManager: DevServerManager,\n private options: Pick<StartOptions, 'devClient' | 'platforms'>\n ) {}\n\n printDevServerInfo(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>\n ) {\n // Keep track of approximately how much space we have to print our usage guide\n let rows = process.stdout.rows || Infinity;\n\n // If native dev server is running, print its URL.\n if (this.devServerManager.getNativeDevServerPort()) {\n const devServer = this.devServerManager.getDefaultDevServer();\n try {\n const nativeRuntimeUrl = devServer.getNativeRuntimeUrl()!;\n const interstitialPageUrl = devServer.getRedirectUrl();\n\n // Print the URL to stdout for tests\n if (env.__EXPO_E2E_TEST) {\n console.info(\n `[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: devServer.getDevServerUrl() })}`\n );\n rows--;\n }\n\n const qr = printQRCode(interstitialPageUrl ?? nativeRuntimeUrl);\n rows -= qr.lines;\n qr.print();\n\n let qrMessage = '';\n if (!options.devClient) {\n qrMessage = `Scan the QR code above to open in ${chalk`{bold Expo Go}`}.`;\n } else {\n qrMessage = chalk`Scan the QR code above to open in a {bold development build}.`;\n qrMessage += ` (${learnMore('https://expo.fyi/start')})`;\n }\n rows--;\n Log.log(printItem(qrMessage, { dim: true }));\n\n if (interstitialPageUrl) {\n rows--;\n Log.log(\n printItem(\n chalk`Choose an app to open your project at {underline ${interstitialPageUrl}}`\n )\n );\n }\n\n rows--;\n Log.log(printItem(chalk`Metro: {underline ${nativeRuntimeUrl}}`));\n } catch (error) {\n console.log('err', error);\n // @ts-ignore: If there is no development build scheme, then skip the QR code.\n if (error.code !== 'NO_DEV_CLIENT_SCHEME') {\n throw error;\n } else {\n const serverUrl = devServer.getDevServerUrl();\n Log.log(printItem(chalk`Metro: {underline ${serverUrl}}`));\n Log.log(printItem(`Linking is disabled because the client scheme cannot be resolved.`));\n rows -= 2;\n }\n }\n }\n\n if (this.options.platforms?.includes('web')) {\n const webDevServer = this.devServerManager.getWebDevServer();\n const webUrl = webDevServer?.getDevServerUrl({ hostType: 'localhost' });\n if (webUrl) {\n Log.log(printItem(chalk`Web: {underline ${webUrl}}`));\n rows--;\n }\n }\n\n printUsage(options, { verbose: false, rows });\n printHelp();\n Log.log();\n }\n\n async openJsInspectorAsync() {\n try {\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n if (!apps.length) {\n return Log.warn(\n chalk`{bold Debug:} No compatible apps connected, React Native DevTools can only be used with Hermes. ${learnMore(\n 'https://docs.expo.dev/guides/using-hermes/'\n )}`\n );\n }\n\n const app = await promptInspectorAppAsync(apps);\n if (!app) {\n return Log.error(chalk`{bold Debug:} No inspectable device selected`);\n }\n\n if (!(await openJsInspector(metroServerOrigin, app))) {\n Log.warn(\n chalk`{bold Debug:} Failed to open the React Native DevTools, see debug logs for more info.`\n );\n }\n } catch (error: any) {\n // Handle aborting prompt\n if (error.code === 'ABORTED') return;\n\n Log.error('Failed to open the React Native DevTools.');\n Log.exception(error);\n }\n }\n\n reloadApp() {\n Log.log(`${BLT} Reloading apps`);\n // Send reload requests over the dev servers\n this.devServerManager.broadcastMessage('reload');\n }\n\n async openMoreToolsAsync() {\n // Options match: Chrome > View > Developer\n try {\n const defaultMenuItems: MoreToolMenuItem[] = [\n { title: 'Inspect elements', value: 'toggleElementInspector' },\n { title: 'Toggle performance monitor', value: 'togglePerformanceMonitor' },\n { title: 'Toggle developer menu', value: 'toggleDevMenu' },\n { title: 'Reload app', value: 'reload' },\n // TODO: Maybe a \"View Source\" option to open code.\n ];\n\n const defaultServerUrl = this.devServerManager\n .getDefaultDevServer()\n .getUrlCreator()\n .constructUrl({ scheme: 'http' });\n\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const plugins = await this.devServerManager.devtoolsPluginManager.queryPluginsAsync();\n\n const menuItems = [\n ...defaultMenuItems,\n ...createDevToolsMenuItems(plugins, defaultServerUrl, metroServerOrigin),\n ];\n\n const value = await selectAsync(chalk`Dev tools {dim (native only)}`, menuItems);\n const menuItem = menuItems.find((item) => item.value === value);\n if (menuItem?.action) {\n menuItem.action();\n } else if (menuItem?.value) {\n this.devServerManager.broadcastMessage('sendDevCommand', { name: menuItem.value });\n }\n } catch (error: any) {\n debug(error);\n // do nothing\n } finally {\n printHelp();\n }\n }\n\n toggleDevMenu() {\n Log.log(`${BLT} Toggling dev menu`);\n this.devServerManager.broadcastMessage('devMenu');\n }\n}\n"],"names":["DevServerManagerActions","debug","require","constructor","devServerManager","options","printDevServerInfo","rows","process","stdout","Infinity","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","qr","printQRCode","lines","print","qrMessage","devClient","chalk","learnMore","Log","log","printItem","dim","error","code","serverUrl","platforms","includes","webDevServer","getWebDevServer","webUrl","hostType","printUsage","verbose","printHelp","openJsInspectorAsync","metroServerOrigin","getJsInspectorBaseUrl","apps","queryAllInspectorAppsAsync","length","warn","app","promptInspectorAppAsync","openJsInspector","exception","reloadApp","BLT","broadcastMessage","openMoreToolsAsync","defaultMenuItems","title","value","defaultServerUrl","getUrlCreator","constructUrl","scheme","plugins","devtoolsPluginManager","queryPluginsAsync","menuItems","createDevToolsMenuItems","selectAsync","menuItem","find","item","action","name","toggleDevMenu"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/interface/interactiveActions.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { BLT, printHelp, printItem, printUsage, StartOptions } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport { ExpoChoice, selectAsync } from '../../utils/prompts';\nimport { printQRCode } from '../../utils/qr';\nimport { DevServerManager } from '../server/DevServerManager';\nimport {\n openJsInspector,\n queryAllInspectorAppsAsync,\n promptInspectorAppAsync,\n} from '../server/middleware/inspector/JsInspector';\n\nconst debug = require('debug')('expo:start:interface:interactiveActions') as typeof console.log;\n\ninterface MoreToolMenuItem extends ExpoChoice<string> {\n action?: () => unknown;\n}\n\n/** Wraps the DevServerManager and adds an interface for user actions. */\nexport class DevServerManagerActions {\n constructor(\n private devServerManager: DevServerManager,\n private options: Pick<StartOptions, 'devClient' | 'platforms'>\n ) {}\n\n printDevServerInfo(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>\n ) {\n // Keep track of approximately how much space we have to print our usage guide\n let rows = process.stdout.rows || Infinity;\n\n // If native dev server is running, print its URL.\n if (this.devServerManager.getNativeDevServerPort()) {\n const devServer = this.devServerManager.getDefaultDevServer();\n try {\n const nativeRuntimeUrl = devServer.getNativeRuntimeUrl()!;\n const interstitialPageUrl = devServer.getRedirectUrl();\n\n // Print the URL to stdout for tests\n if (env.__EXPO_E2E_TEST) {\n console.info(\n `[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: devServer.getDevServerUrl() })}`\n );\n rows--;\n }\n\n if (!env.EXPO_NO_QR_CODE) {\n const qr = printQRCode(interstitialPageUrl ?? nativeRuntimeUrl);\n rows -= qr.lines;\n qr.print();\n\n let qrMessage = '';\n if (!options.devClient) {\n qrMessage = `Scan the QR code above to open in ${chalk`{bold Expo Go}`}.`;\n } else {\n qrMessage = chalk`Scan the QR code above to open in a {bold development build}.`;\n qrMessage += ` (${learnMore('https://expo.fyi/start')})`;\n }\n rows--;\n Log.log(printItem(qrMessage, { dim: true }));\n }\n\n if (interstitialPageUrl) {\n rows--;\n Log.log(\n printItem(\n chalk`Choose an app to open your project at {underline ${interstitialPageUrl}}`\n )\n );\n }\n\n rows--;\n Log.log(printItem(chalk`Metro: {underline ${nativeRuntimeUrl}}`));\n } catch (error) {\n console.log('err', error);\n // @ts-ignore: If there is no development build scheme, then skip the QR code.\n if (error.code !== 'NO_DEV_CLIENT_SCHEME') {\n throw error;\n } else {\n const serverUrl = devServer.getDevServerUrl();\n Log.log(printItem(chalk`Metro: {underline ${serverUrl}}`));\n Log.log(printItem(`Linking is disabled because the client scheme cannot be resolved.`));\n rows -= 2;\n }\n }\n }\n\n if (this.options.platforms?.includes('web')) {\n const webDevServer = this.devServerManager.getWebDevServer();\n const webUrl = webDevServer?.getDevServerUrl({ hostType: 'localhost' });\n if (webUrl) {\n Log.log(printItem(chalk`Web: {underline ${webUrl}}`));\n rows--;\n }\n }\n\n printUsage(options, { verbose: false, rows });\n printHelp();\n Log.log();\n }\n\n async openJsInspectorAsync() {\n try {\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n if (!apps.length) {\n return Log.warn(\n chalk`{bold Debug:} No compatible apps connected, React Native DevTools can only be used with Hermes. ${learnMore(\n 'https://docs.expo.dev/guides/using-hermes/'\n )}`\n );\n }\n\n const app = await promptInspectorAppAsync(apps);\n if (!app) {\n return Log.error(chalk`{bold Debug:} No inspectable device selected`);\n }\n\n if (!(await openJsInspector(metroServerOrigin, app))) {\n Log.warn(\n chalk`{bold Debug:} Failed to open the React Native DevTools, see debug logs for more info.`\n );\n }\n } catch (error: any) {\n // Handle aborting prompt\n if (error.code === 'ABORTED') return;\n\n Log.error('Failed to open the React Native DevTools.');\n Log.exception(error);\n }\n }\n\n reloadApp() {\n Log.log(`${BLT} Reloading apps`);\n // Send reload requests over the dev servers\n this.devServerManager.broadcastMessage('reload');\n }\n\n async openMoreToolsAsync() {\n // Options match: Chrome > View > Developer\n try {\n const defaultMenuItems: MoreToolMenuItem[] = [\n { title: 'Inspect elements', value: 'toggleElementInspector' },\n { title: 'Toggle performance monitor', value: 'togglePerformanceMonitor' },\n { title: 'Toggle developer menu', value: 'toggleDevMenu' },\n { title: 'Reload app', value: 'reload' },\n // TODO: Maybe a \"View Source\" option to open code.\n ];\n\n const defaultServerUrl = this.devServerManager\n .getDefaultDevServer()\n .getUrlCreator()\n .constructUrl({ scheme: 'http' });\n\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const plugins = await this.devServerManager.devtoolsPluginManager.queryPluginsAsync();\n\n const menuItems = [\n ...defaultMenuItems,\n ...createDevToolsMenuItems(plugins, defaultServerUrl, metroServerOrigin),\n ];\n\n const value = await selectAsync(chalk`Dev tools {dim (native only)}`, menuItems);\n const menuItem = menuItems.find((item) => item.value === value);\n if (menuItem?.action) {\n menuItem.action();\n } else if (menuItem?.value) {\n this.devServerManager.broadcastMessage('sendDevCommand', { name: menuItem.value });\n }\n } catch (error: any) {\n debug(error);\n // do nothing\n } finally {\n printHelp();\n }\n }\n\n toggleDevMenu() {\n Log.log(`${BLT} Toggling dev menu`);\n this.devServerManager.broadcastMessage('devMenu');\n }\n}\n"],"names":["DevServerManagerActions","debug","require","constructor","devServerManager","options","printDevServerInfo","rows","process","stdout","Infinity","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","EXPO_NO_QR_CODE","qr","printQRCode","lines","print","qrMessage","devClient","chalk","learnMore","Log","log","printItem","dim","error","code","serverUrl","platforms","includes","webDevServer","getWebDevServer","webUrl","hostType","printUsage","verbose","printHelp","openJsInspectorAsync","metroServerOrigin","getJsInspectorBaseUrl","apps","queryAllInspectorAppsAsync","length","warn","app","promptInspectorAppAsync","openJsInspector","exception","reloadApp","BLT","broadcastMessage","openMoreToolsAsync","defaultMenuItems","title","value","defaultServerUrl","getUrlCreator","constructUrl","scheme","plugins","devtoolsPluginManager","queryPluginsAsync","menuItems","createDevToolsMenuItems","selectAsync","menuItem","find","item","action","name","toggleDevMenu"],"mappings":"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"}
|
|
@@ -12,6 +12,9 @@ _export(exports, {
|
|
|
12
12
|
MetroTerminalReporter: function() {
|
|
13
13
|
return MetroTerminalReporter;
|
|
14
14
|
},
|
|
15
|
+
event: function() {
|
|
16
|
+
return event;
|
|
17
|
+
},
|
|
15
18
|
extractCodeFrame: function() {
|
|
16
19
|
return extractCodeFrame;
|
|
17
20
|
},
|
|
@@ -52,20 +55,35 @@ const _env = require("../../../utils/env");
|
|
|
52
55
|
const _link = require("../../../utils/link");
|
|
53
56
|
const _serverLogLikeMetro = require("../serverLogLikeMetro");
|
|
54
57
|
const _metroErrorInterface = require("./metroErrorInterface");
|
|
58
|
+
const _events = require("../../../events");
|
|
59
|
+
const _ansi = require("../../../utils/ansi");
|
|
55
60
|
function _interop_require_default(obj) {
|
|
56
61
|
return obj && obj.__esModule ? obj : {
|
|
57
62
|
default: obj
|
|
58
63
|
};
|
|
59
64
|
}
|
|
60
65
|
const debug = require('debug')('expo:metro:logger');
|
|
66
|
+
const event = (0, _events.events)('metro', (t)=>[
|
|
67
|
+
t.event(),
|
|
68
|
+
t.event(),
|
|
69
|
+
t.event(),
|
|
70
|
+
t.event(),
|
|
71
|
+
t.event(),
|
|
72
|
+
t.event(),
|
|
73
|
+
t.event(),
|
|
74
|
+
t.event(),
|
|
75
|
+
t.event()
|
|
76
|
+
]);
|
|
61
77
|
const MAX_PROGRESS_BAR_CHAR_WIDTH = 16;
|
|
62
78
|
const DARK_BLOCK_CHAR = '\u2593';
|
|
63
79
|
const LIGHT_BLOCK_CHAR = '\u2591';
|
|
64
80
|
class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
65
|
-
|
|
66
|
-
|
|
81
|
+
#lastFailedBuildID;
|
|
82
|
+
constructor(serverRoot, terminal){
|
|
83
|
+
super(terminal), this.serverRoot = serverRoot;
|
|
67
84
|
}
|
|
68
85
|
_log(event) {
|
|
86
|
+
this.#captureLog(event);
|
|
69
87
|
switch(event.type){
|
|
70
88
|
case 'unstable_server_log':
|
|
71
89
|
var _event_data;
|
|
@@ -97,57 +115,11 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
97
115
|
{
|
|
98
116
|
if (this.shouldFilterClientLog(event)) {
|
|
99
117
|
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
118
|
+
} else if (event.level != null) {
|
|
119
|
+
return this.#onClientLog(event);
|
|
120
|
+
} else {
|
|
103
121
|
break;
|
|
104
122
|
}
|
|
105
|
-
if (level === 'warn' || level === 'error') {
|
|
106
|
-
let hasStack = false;
|
|
107
|
-
const parsed = event.data.map((msg)=>{
|
|
108
|
-
// Quick check to see if an unsymbolicated stack is being logged.
|
|
109
|
-
if (msg.includes('.bundle//&platform=')) {
|
|
110
|
-
const stack = (0, _serverLogLikeMetro.parseErrorStringToObject)(msg);
|
|
111
|
-
if (stack) {
|
|
112
|
-
hasStack = true;
|
|
113
|
-
}
|
|
114
|
-
return stack;
|
|
115
|
-
}
|
|
116
|
-
return msg;
|
|
117
|
-
});
|
|
118
|
-
if (hasStack) {
|
|
119
|
-
(async ()=>{
|
|
120
|
-
const symbolicating = parsed.map((p)=>{
|
|
121
|
-
if (typeof p === 'string') return p;
|
|
122
|
-
return (0, _serverLogLikeMetro.maybeSymbolicateAndFormatJSErrorStackLogAsync)(this.projectRoot, level, p);
|
|
123
|
-
});
|
|
124
|
-
let usefulStackCount = 0;
|
|
125
|
-
const fallbackIndices = [];
|
|
126
|
-
const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index)=>{
|
|
127
|
-
if (s.status === 'rejected') {
|
|
128
|
-
debug('Error formatting stack', parsed[index], s.reason);
|
|
129
|
-
return parsed[index];
|
|
130
|
-
} else if (typeof s.value === 'string') {
|
|
131
|
-
return s.value;
|
|
132
|
-
} else {
|
|
133
|
-
if (!s.value.isFallback) {
|
|
134
|
-
usefulStackCount++;
|
|
135
|
-
} else {
|
|
136
|
-
fallbackIndices.push(index);
|
|
137
|
-
}
|
|
138
|
-
return s.value.stack;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
// Using EXPO_DEBUG we can print all stack
|
|
142
|
-
const filtered = usefulStackCount && !_env.env.EXPO_DEBUG ? symbolicated.filter((_, index)=>!fallbackIndices.includes(index)) : symbolicated;
|
|
143
|
-
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, null, ...filtered);
|
|
144
|
-
})();
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
// Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.
|
|
149
|
-
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, null, ...event.data);
|
|
150
|
-
return;
|
|
151
123
|
}
|
|
152
124
|
}
|
|
153
125
|
return super._log(event);
|
|
@@ -165,38 +137,46 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
165
137
|
const env = getEnvironmentForBuildDetails(progress.bundleDetails);
|
|
166
138
|
const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);
|
|
167
139
|
const inProgress = phase === 'in_progress';
|
|
168
|
-
|
|
169
|
-
if (typeof ((_progress_bundleDetails = progress.bundleDetails) == null ? void 0 : (_progress_bundleDetails_customTransformOptions = _progress_bundleDetails.customTransformOptions) == null ? void 0 : _progress_bundleDetails_customTransformOptions.dom) === 'string' && progress.bundleDetails.customTransformOptions.dom.includes(_path().default.sep)) {
|
|
170
|
-
// Because we use a generated entry file for DOM components, we need to adjust the logging path so it
|
|
171
|
-
// shows a unique path for each component.
|
|
172
|
-
// Here, we take the relative import path and remove all the starting slashes.
|
|
173
|
-
localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\.?\.[\\/])+/, '');
|
|
174
|
-
} else {
|
|
175
|
-
const inputFile = progress.bundleDetails.entryFile;
|
|
176
|
-
localPath = _path().default.isAbsolute(inputFile) ? _path().default.relative(this.projectRoot, inputFile) : inputFile;
|
|
177
|
-
}
|
|
140
|
+
const localPath = typeof ((_progress_bundleDetails = progress.bundleDetails) == null ? void 0 : (_progress_bundleDetails_customTransformOptions = _progress_bundleDetails.customTransformOptions) == null ? void 0 : _progress_bundleDetails_customTransformOptions.dom) === 'string' && progress.bundleDetails.customTransformOptions.dom.includes(_path().default.sep) ? progress.bundleDetails.customTransformOptions.dom.replace(/^(\.?\.[\\/])+/, '') : this.#normalizePath(progress.bundleDetails.entryFile);
|
|
178
141
|
if (!inProgress) {
|
|
179
142
|
const status = phase === 'done' ? `Bundled ` : `Bundling failed `;
|
|
180
143
|
const color = phase === 'done' ? _chalk().default.green : _chalk().default.red;
|
|
181
144
|
const startTime = this._bundleTimers.get(progress.bundleDetails.buildID);
|
|
182
145
|
let time = '';
|
|
146
|
+
let ms = null;
|
|
183
147
|
if (startTime != null) {
|
|
184
148
|
const elapsed = this._getElapsedTime(startTime);
|
|
185
149
|
const micro = Number(elapsed) / 1000;
|
|
186
|
-
|
|
150
|
+
ms = Number(elapsed) / 1e6;
|
|
187
151
|
// If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.
|
|
188
|
-
if (
|
|
152
|
+
if (ms <= 0.5) {
|
|
189
153
|
const tenthFractionOfMicro = (micro * 10 / 1000).toFixed(0);
|
|
190
154
|
// Format as microseconds to nearest tenth
|
|
191
155
|
time = _chalk().default.cyan.bold(`0.${tenthFractionOfMicro}ms`);
|
|
192
156
|
} else {
|
|
193
|
-
time = _chalk().default.dim(
|
|
157
|
+
time = _chalk().default.dim(ms.toFixed(0) + 'ms');
|
|
194
158
|
}
|
|
195
159
|
}
|
|
160
|
+
if (phase === 'done') {
|
|
161
|
+
event('bundling:done', {
|
|
162
|
+
id: progress.bundleDetails.buildID ?? null,
|
|
163
|
+
total: progress.totalFileCount,
|
|
164
|
+
ms
|
|
165
|
+
});
|
|
166
|
+
}
|
|
196
167
|
// iOS Bundled 150ms
|
|
197
168
|
const plural = progress.totalFileCount === 1 ? '' : 's';
|
|
198
169
|
return color(platform + status) + time + _chalk().default.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`);
|
|
199
170
|
}
|
|
171
|
+
event('bundling:progress', {
|
|
172
|
+
id: progress.bundleDetails.buildID ?? null,
|
|
173
|
+
progress: progress.ratio,
|
|
174
|
+
total: progress.totalFileCount,
|
|
175
|
+
current: progress.transformedFileCount
|
|
176
|
+
});
|
|
177
|
+
if ((0, _events.shouldReduceLogs)()) {
|
|
178
|
+
return '';
|
|
179
|
+
}
|
|
200
180
|
const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);
|
|
201
181
|
const _progress = inProgress ? _chalk().default.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) + _chalk().default.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) + _chalk().default.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) + _chalk().default.dim(`(${progress.transformedFileCount.toString().padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`) : '';
|
|
202
182
|
return platform + _chalk().default.reset.dim(`${_path().default.dirname(localPath)}${_path().default.sep}`) + _chalk().default.bold(_path().default.basename(localPath)) + ' ' + _progress;
|
|
@@ -225,25 +205,145 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
225
205
|
].join('\n')));
|
|
226
206
|
}
|
|
227
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Workaround to link build ids to bundling errors.
|
|
210
|
+
* This works because `_logBundleBuildFailed` is called before `_logBundlingError` in synchronous manner.
|
|
211
|
+
* https://github.com/facebook/metro/blob/main/packages/metro/src/Server.js#L939-L945
|
|
212
|
+
*/ _logBundleBuildFailed(buildID) {
|
|
213
|
+
this.#lastFailedBuildID = buildID;
|
|
214
|
+
super._logBundleBuildFailed(buildID);
|
|
215
|
+
}
|
|
228
216
|
_logBundlingError(error) {
|
|
229
|
-
const
|
|
217
|
+
const importStack = (0, _metroErrorInterface.nearestImportStack)(error);
|
|
218
|
+
const moduleResolutionError = formatUsingNodeStandardLibraryError(this.serverRoot, error);
|
|
230
219
|
if (moduleResolutionError) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
220
|
+
const message = maybeAppendCodeFrame(moduleResolutionError, error.message);
|
|
221
|
+
event('bundling:failed', {
|
|
222
|
+
id: this.#lastFailedBuildID ?? null,
|
|
223
|
+
message: (0, _ansi.stripAnsi)(message) ?? null,
|
|
224
|
+
importStack: importStack ?? null,
|
|
225
|
+
filename: error.filename ?? null,
|
|
226
|
+
targetModuleName: this.#normalizePath(error.targetModuleName),
|
|
227
|
+
originModulePath: this.#normalizePath(error.originModulePath)
|
|
228
|
+
});
|
|
229
|
+
return this.terminal.log(importStack ? `${message}\n\n${importStack}` : message);
|
|
230
|
+
} else {
|
|
231
|
+
event('bundling:failed', {
|
|
232
|
+
id: this.#lastFailedBuildID ?? null,
|
|
233
|
+
message: (0, _ansi.stripAnsi)(error.message) ?? null,
|
|
234
|
+
importStack: importStack ?? null,
|
|
235
|
+
filename: error.filename ?? null,
|
|
236
|
+
targetModuleName: error.targetModuleName ?? null,
|
|
237
|
+
originModulePath: error.originModulePath ?? null
|
|
238
|
+
});
|
|
239
|
+
(0, _metroErrorInterface.attachImportStackToRootMessage)(error, importStack);
|
|
240
|
+
// NOTE(@kitten): Metro drops the stack forcefully when it finds a `SyntaxError`. However,
|
|
241
|
+
// this is really unhelpful, since it prevents debugging Babel plugins or reporting bugs
|
|
242
|
+
// in Babel plugins or a transformer entirely
|
|
243
|
+
if (error.snippet == null && error.stack != null && error instanceof SyntaxError) {
|
|
244
|
+
error.message = error.stack;
|
|
245
|
+
delete error.stack;
|
|
246
|
+
}
|
|
247
|
+
return super._logBundlingError(error);
|
|
234
248
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
249
|
+
}
|
|
250
|
+
#onClientLog(evt) {
|
|
251
|
+
const { level = 'log', data } = evt;
|
|
252
|
+
if (level === 'warn' || level === 'error') {
|
|
253
|
+
let hasStack = false;
|
|
254
|
+
const parsed = data.map((msg)=>{
|
|
255
|
+
// Quick check to see if an unsymbolicated stack is being logged.
|
|
256
|
+
if (typeof msg === 'string' && msg.includes('.bundle//&platform=')) {
|
|
257
|
+
const stack = (0, _serverLogLikeMetro.parseErrorStringToObject)(msg);
|
|
258
|
+
if (stack) {
|
|
259
|
+
hasStack = true;
|
|
260
|
+
}
|
|
261
|
+
return stack;
|
|
262
|
+
}
|
|
263
|
+
return msg;
|
|
264
|
+
});
|
|
265
|
+
if (hasStack) {
|
|
266
|
+
(async ()=>{
|
|
267
|
+
const symbolicating = parsed.map((p)=>{
|
|
268
|
+
if (typeof p === 'string') {
|
|
269
|
+
return p;
|
|
270
|
+
} else if (p && typeof p === 'object' && 'message' in p && typeof p.message === 'string') {
|
|
271
|
+
return (0, _serverLogLikeMetro.maybeSymbolicateAndFormatJSErrorStackLogAsync)(this.serverRoot, level, p);
|
|
272
|
+
} else {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
let usefulStackCount = 0;
|
|
277
|
+
const fallbackIndices = [];
|
|
278
|
+
const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index)=>{
|
|
279
|
+
if (s.status === 'rejected') {
|
|
280
|
+
debug('Error formatting stack', parsed[index], s.reason);
|
|
281
|
+
return parsed[index];
|
|
282
|
+
} else if (!s.value) {
|
|
283
|
+
return parsed[index];
|
|
284
|
+
} else if (typeof s.value === 'string') {
|
|
285
|
+
return s.value;
|
|
286
|
+
} else {
|
|
287
|
+
if (!s.value.isFallback) {
|
|
288
|
+
usefulStackCount++;
|
|
289
|
+
} else {
|
|
290
|
+
fallbackIndices.push(index);
|
|
291
|
+
}
|
|
292
|
+
return s.value.stack;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
// Using EXPO_DEBUG we can print all stack
|
|
296
|
+
const filtered = usefulStackCount && !_env.env.EXPO_DEBUG ? symbolicated.filter((_, index)=>!fallbackIndices.includes(index)) : symbolicated;
|
|
297
|
+
event('client_log', {
|
|
298
|
+
level,
|
|
299
|
+
data: symbolicated
|
|
300
|
+
});
|
|
301
|
+
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, null, ...filtered);
|
|
302
|
+
})();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
242
305
|
}
|
|
243
|
-
|
|
306
|
+
event('client_log', {
|
|
307
|
+
level,
|
|
308
|
+
data
|
|
309
|
+
});
|
|
310
|
+
// Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.
|
|
311
|
+
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, null, ...data);
|
|
312
|
+
}
|
|
313
|
+
#captureLog(evt) {
|
|
314
|
+
switch(evt.type){
|
|
315
|
+
case 'bundle_build_started':
|
|
316
|
+
{
|
|
317
|
+
var _evt_bundleDetails_customTransformOptions, _evt_bundleDetails, _evt_bundleDetails_customTransformOptions1;
|
|
318
|
+
const entry = typeof ((_evt_bundleDetails = evt.bundleDetails) == null ? void 0 : (_evt_bundleDetails_customTransformOptions = _evt_bundleDetails.customTransformOptions) == null ? void 0 : _evt_bundleDetails_customTransformOptions.dom) === 'string' && evt.bundleDetails.customTransformOptions.dom.includes(_path().default.sep) ? evt.bundleDetails.customTransformOptions.dom.replace(/^(\.?\.[\\/])+/, '') : this.#normalizePath(evt.bundleDetails.entryFile);
|
|
319
|
+
return event('bundling:started', {
|
|
320
|
+
id: evt.buildID,
|
|
321
|
+
platform: evt.bundleDetails.platform ?? null,
|
|
322
|
+
environment: ((_evt_bundleDetails_customTransformOptions1 = evt.bundleDetails.customTransformOptions) == null ? void 0 : _evt_bundleDetails_customTransformOptions1.environment) ?? null,
|
|
323
|
+
entry
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
case 'unstable_server_log':
|
|
327
|
+
return event('server_log', {
|
|
328
|
+
level: evt.level ?? null,
|
|
329
|
+
data: evt.data ?? null
|
|
330
|
+
});
|
|
331
|
+
case 'client_log':
|
|
332
|
+
// Handled separately: see this.#onClientLog
|
|
333
|
+
return;
|
|
334
|
+
case 'hmr_client_error':
|
|
335
|
+
case 'cache_write_error':
|
|
336
|
+
case 'cache_read_error':
|
|
337
|
+
return event(evt.type, {
|
|
338
|
+
message: evt.error.message
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
#normalizePath(dest) {
|
|
343
|
+
return dest != null && _path().default.isAbsolute(dest) ? _path().default.relative(this.serverRoot, dest) : dest || null;
|
|
244
344
|
}
|
|
245
345
|
}
|
|
246
|
-
function formatUsingNodeStandardLibraryError(
|
|
346
|
+
function formatUsingNodeStandardLibraryError(serverRoot, error) {
|
|
247
347
|
if (!error.message) {
|
|
248
348
|
return null;
|
|
249
349
|
}
|
|
@@ -251,7 +351,7 @@ function formatUsingNodeStandardLibraryError(projectRoot, error) {
|
|
|
251
351
|
if (!targetModuleName || !originModulePath) {
|
|
252
352
|
return null;
|
|
253
353
|
}
|
|
254
|
-
const relativePath = _path().default.relative(
|
|
354
|
+
const relativePath = _path().default.relative(serverRoot, originModulePath);
|
|
255
355
|
const DOCS_PAGE_URL = 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';
|
|
256
356
|
if (isNodeStdLibraryModule(targetModuleName)) {
|
|
257
357
|
if (originModulePath.includes('node_modules')) {
|