@expo/cli 1.0.0-canary-20250722-599a28f → 54.0.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/metro-require/require.js +24 -13
- package/build/src/api/getExpoSchema.js +8 -7
- package/build/src/api/getExpoSchema.js.map +1 -1
- package/build/src/expoUpdatesExports.js +28 -0
- package/build/src/expoUpdatesExports.js.map +1 -0
- package/build/src/export/embed/exportEmbedAsync.js +26 -25
- package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
- package/build/src/export/embed/resolveOptions.js +1 -1
- package/build/src/export/embed/resolveOptions.js.map +1 -1
- package/build/src/export/exportApp.js +7 -4
- package/build/src/export/exportApp.js.map +1 -1
- package/build/src/export/exportAssets.js +20 -4
- package/build/src/export/exportAssets.js.map +1 -1
- package/build/src/export/exportAsync.js +2 -2
- package/build/src/export/exportAsync.js.map +1 -1
- package/build/src/export/exportHermes.js +34 -9
- package/build/src/export/exportHermes.js.map +1 -1
- package/build/src/export/exportStaticAsync.js +23 -2
- package/build/src/export/exportStaticAsync.js.map +1 -1
- package/build/src/export/index.js +1 -0
- package/build/src/export/index.js.map +1 -1
- package/build/src/export/metroAssetLocalPath.js.map +1 -1
- package/build/src/export/persistMetroAssets.js.map +1 -1
- package/build/src/export/resolveOptions.js +1 -0
- package/build/src/export/resolveOptions.js.map +1 -1
- package/build/src/export/saveAssets.js +12 -0
- package/build/src/export/saveAssets.js.map +1 -1
- package/build/src/install/checkPackages.js +9 -1
- package/build/src/install/checkPackages.js.map +1 -1
- package/build/src/lint/lintAsync.js +2 -0
- package/build/src/lint/lintAsync.js.map +1 -1
- package/build/src/prebuild/prebuildAsync.js +18 -0
- package/build/src/prebuild/prebuildAsync.js.map +1 -1
- package/build/src/prebuild/resolveLocalTemplate.js +42 -0
- package/build/src/prebuild/resolveLocalTemplate.js.map +1 -0
- package/build/src/prebuild/resolveTemplate.js +17 -7
- package/build/src/prebuild/resolveTemplate.js.map +1 -1
- package/build/src/prebuild/updateFromTemplate.js +1 -0
- package/build/src/prebuild/updateFromTemplate.js.map +1 -1
- package/build/src/prebuild/updatePackageJson.js +5 -3
- package/build/src/prebuild/updatePackageJson.js.map +1 -1
- package/build/src/run/android/resolveOptions.js +2 -2
- package/build/src/run/android/resolveOptions.js.map +1 -1
- package/build/src/run/ios/options/resolveOptions.js +2 -2
- package/build/src/run/ios/options/resolveOptions.js.map +1 -1
- package/build/src/run/ios/runIosAsync.js +3 -0
- package/build/src/run/ios/runIosAsync.js.map +1 -1
- package/build/src/serve/serveAsync.js +5 -2
- package/build/src/serve/serveAsync.js.map +1 -1
- package/build/src/start/platforms/ExpoGoInstaller.js +1 -1
- package/build/src/start/platforms/ExpoGoInstaller.js.map +1 -1
- package/build/src/start/server/DevToolsPluginManager.js +7 -35
- package/build/src/start/server/DevToolsPluginManager.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +88 -56
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +66 -25
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/TerminalReporter.js +6 -6
- package/build/src/start/server/metro/TerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/createExpoAutolinkingResolver.js +121 -0
- package/build/src/start/server/metro/createExpoAutolinkingResolver.js.map +1 -0
- package/build/src/start/server/metro/createExpoFallbackResolver.js +1 -0
- package/build/src/start/server/metro/createExpoFallbackResolver.js.map +1 -1
- package/build/src/start/server/metro/createExpoMetroResolver.js.map +1 -1
- package/build/src/start/server/metro/createJResolver.js.map +1 -1
- package/build/src/start/server/metro/createServerComponentsMiddleware.js +4 -4
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js +54 -8
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/metro/debugging/attachAtlas.js +2 -0
- package/build/src/start/server/metro/debugging/attachAtlas.js.map +1 -1
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +1 -1
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
- package/build/src/start/server/metro/fetchRouterManifest.js +1 -0
- package/build/src/start/server/metro/fetchRouterManifest.js.map +1 -1
- package/build/src/start/server/metro/formatFileCandidates.js.map +1 -1
- package/build/src/start/server/metro/getCssModulesFromBundler.js +10 -9
- package/build/src/start/server/metro/getCssModulesFromBundler.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +44 -40
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/metroErrorInterface.js +79 -12
- package/build/src/start/server/metro/metroErrorInterface.js.map +1 -1
- package/build/src/start/server/metro/metroVirtualModules.js.map +1 -1
- package/build/src/start/server/metro/metroWatchTypeScriptFiles.js.map +1 -1
- package/build/src/start/server/metro/router.js +75 -0
- package/build/src/start/server/metro/router.js.map +1 -1
- package/build/src/start/server/metro/runServer-fork.js +19 -19
- package/build/src/start/server/metro/runServer-fork.js.map +1 -1
- package/build/src/start/server/metro/serializeHtml.js +45 -5
- package/build/src/start/server/metro/serializeHtml.js.map +1 -1
- package/build/src/start/server/metro/waitForMetroToObserveTypeScriptFile.js.map +1 -1
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js +267 -0
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js.map +1 -0
- package/build/src/start/server/metro/withMetroMultiPlatform.js +58 -82
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/metro/withMetroResolvers.js +2 -219
- package/build/src/start/server/metro/withMetroResolvers.js.map +1 -1
- package/build/src/start/server/metro/withMetroSupervisingTransformWorker.js +63 -0
- package/build/src/start/server/metro/withMetroSupervisingTransformWorker.js.map +1 -0
- package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js +1 -1
- package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js.map +1 -1
- package/build/src/start/server/middleware/metroOptions.js +7 -2
- package/build/src/start/server/middleware/metroOptions.js.map +1 -1
- package/build/src/start/server/middleware/resolvePlatform.js +3 -0
- package/build/src/start/server/middleware/resolvePlatform.js.map +1 -1
- package/build/src/start/server/serverLogLikeMetro.js +13 -11
- package/build/src/start/server/serverLogLikeMetro.js.map +1 -1
- package/build/src/start/server/type-generation/routes.js.map +1 -1
- package/build/src/start/server/type-generation/startTypescriptTypeGeneration.js.map +1 -1
- package/build/src/types.d.ts +2 -0
- package/build/src/utils/build-cache-providers/index.js.map +1 -1
- package/build/src/utils/dir.js +7 -0
- package/build/src/utils/dir.js.map +1 -1
- package/build/src/utils/env.js +9 -4
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/errors.js +1 -1
- package/build/src/utils/errors.js.map +1 -1
- package/build/src/utils/git.js +2 -2
- package/build/src/utils/git.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/build/src/utils/tsconfig/resolveWithTsConfigPaths.js.map +1 -1
- package/internal/unstable-expo-updates-exports.d.ts +31 -0
- package/internal/unstable-expo-updates-exports.js +3 -0
- package/package.json +33 -17
- package/static/template/[...rsc]+api.ts +1 -1
- package/build/src/start/server/metro/createExpoStickyResolver.js +0 -137
- package/build/src/start/server/metro/createExpoStickyResolver.js.map +0 -1
- package/build/src/start/server/metro/metroPrivateServer.js +0 -28
- package/build/src/start/server/metro/metroPrivateServer.js.map +0 -1
- package/build/src/utils/jsonSchemaDeref.js +0 -150
- package/build/src/utils/jsonSchemaDeref.js.map +0 -1
|
@@ -12,6 +12,9 @@ _export(exports, {
|
|
|
12
12
|
MetroTerminalReporter: function() {
|
|
13
13
|
return MetroTerminalReporter;
|
|
14
14
|
},
|
|
15
|
+
extractCodeFrame: function() {
|
|
16
|
+
return extractCodeFrame;
|
|
17
|
+
},
|
|
15
18
|
formatUsingNodeStandardLibraryError: function() {
|
|
16
19
|
return formatUsingNodeStandardLibraryError;
|
|
17
20
|
},
|
|
@@ -36,11 +39,19 @@ function _path() {
|
|
|
36
39
|
};
|
|
37
40
|
return data;
|
|
38
41
|
}
|
|
42
|
+
function _util() {
|
|
43
|
+
const data = require("util");
|
|
44
|
+
_util = function() {
|
|
45
|
+
return data;
|
|
46
|
+
};
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
39
49
|
const _TerminalReporter = require("./TerminalReporter");
|
|
40
50
|
const _externals = require("./externals");
|
|
41
51
|
const _env = require("../../../utils/env");
|
|
42
52
|
const _link = require("../../../utils/link");
|
|
43
53
|
const _serverLogLikeMetro = require("../serverLogLikeMetro");
|
|
54
|
+
const _metroErrorInterface = require("./metroErrorInterface");
|
|
44
55
|
function _interop_require_default(obj) {
|
|
45
56
|
return obj && obj.__esModule ? obj : {
|
|
46
57
|
default: obj
|
|
@@ -94,22 +105,46 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
94
105
|
const mode = event.mode === 'NOBRIDGE' || event.mode === 'BRIDGE' ? '' : event.mode ?? '';
|
|
95
106
|
// @ts-expect-error
|
|
96
107
|
if (level === 'warn' || level === 'error') {
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// Fallback on the original error message if we can't symbolicate the stack.
|
|
107
|
-
debug('Error formatting stack', e);
|
|
108
|
-
// Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.
|
|
109
|
-
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, mode, ...event.data);
|
|
110
|
-
});
|
|
111
|
-
return;
|
|
108
|
+
let hasStack = false;
|
|
109
|
+
const parsed = event.data.map((msg)=>{
|
|
110
|
+
// Quick check to see if an unsymbolicated stack is being logged.
|
|
111
|
+
if (msg.includes('.bundle//&platform=')) {
|
|
112
|
+
const stack = (0, _serverLogLikeMetro.parseErrorStringToObject)(msg);
|
|
113
|
+
if (stack) {
|
|
114
|
+
hasStack = true;
|
|
115
|
+
}
|
|
116
|
+
return stack;
|
|
112
117
|
}
|
|
118
|
+
return msg;
|
|
119
|
+
});
|
|
120
|
+
if (hasStack) {
|
|
121
|
+
(async ()=>{
|
|
122
|
+
const symbolicating = parsed.map((p)=>{
|
|
123
|
+
if (typeof p === 'string') return p;
|
|
124
|
+
return (0, _serverLogLikeMetro.maybeSymbolicateAndFormatJSErrorStackLogAsync)(this.projectRoot, level, p);
|
|
125
|
+
});
|
|
126
|
+
let usefulStackCount = 0;
|
|
127
|
+
const fallbackIndices = [];
|
|
128
|
+
const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index)=>{
|
|
129
|
+
if (s.status === 'rejected') {
|
|
130
|
+
debug('Error formatting stack', parsed[index], s.reason);
|
|
131
|
+
return parsed[index];
|
|
132
|
+
} else if (typeof s.value === 'string') {
|
|
133
|
+
return s.value;
|
|
134
|
+
} else {
|
|
135
|
+
if (!s.value.isFallback) {
|
|
136
|
+
usefulStackCount++;
|
|
137
|
+
} else {
|
|
138
|
+
fallbackIndices.push(index);
|
|
139
|
+
}
|
|
140
|
+
return s.value.stack;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// Using EXPO_DEBUG we can print all stack
|
|
144
|
+
const filtered = usefulStackCount && !_env.env.EXPO_DEBUG ? symbolicated.filter((_, index)=>!fallbackIndices.includes(index)) : symbolicated;
|
|
145
|
+
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, mode, ...filtered);
|
|
146
|
+
})();
|
|
147
|
+
return;
|
|
113
148
|
}
|
|
114
149
|
}
|
|
115
150
|
// Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.
|
|
@@ -194,17 +229,12 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
194
229
|
}
|
|
195
230
|
_logBundlingError(error) {
|
|
196
231
|
const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);
|
|
197
|
-
const cause = error.cause;
|
|
198
232
|
if (moduleResolutionError) {
|
|
199
233
|
let message = maybeAppendCodeFrame(moduleResolutionError, error.message);
|
|
200
|
-
|
|
201
|
-
message += `\n\n${cause == null ? void 0 : cause._expoImportStack}`;
|
|
202
|
-
}
|
|
234
|
+
message += '\n\n' + (0, _metroErrorInterface.nearestImportStack)(error);
|
|
203
235
|
return this.terminal.log(message);
|
|
204
236
|
}
|
|
205
|
-
|
|
206
|
-
error.message += `\n\n${cause._expoImportStack}`;
|
|
207
|
-
}
|
|
237
|
+
(0, _metroErrorInterface.attachImportStackToRootMessage)(error);
|
|
208
238
|
return super._logBundlingError(error);
|
|
209
239
|
}
|
|
210
240
|
}
|
|
@@ -239,21 +269,32 @@ function isNodeStdLibraryModule(moduleName) {
|
|
|
239
269
|
return /^node:/.test(moduleName) || _externals.NODE_STDLIB_MODULES.includes(moduleName);
|
|
240
270
|
}
|
|
241
271
|
/** If the code frame can be found then append it to the existing message. */ function maybeAppendCodeFrame(message, rawMessage) {
|
|
242
|
-
const codeFrame = stripMetroInfo(rawMessage);
|
|
272
|
+
const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));
|
|
243
273
|
if (codeFrame) {
|
|
244
274
|
message += '\n' + codeFrame;
|
|
245
275
|
}
|
|
246
276
|
return message;
|
|
247
277
|
}
|
|
278
|
+
function extractCodeFrame(errorMessage) {
|
|
279
|
+
const codeFrameLine = /^(?:\s*(?:>?\s*\d+\s*\||\s*\|).*\n?)+/;
|
|
280
|
+
let wasPreviousLineCodeFrame = null;
|
|
281
|
+
return errorMessage.split('\n').filter((line)=>{
|
|
282
|
+
if (wasPreviousLineCodeFrame === false) return false;
|
|
283
|
+
const keep = codeFrameLine.test((0, _util().stripVTControlCharacters)(line));
|
|
284
|
+
if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;
|
|
285
|
+
else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;
|
|
286
|
+
return keep;
|
|
287
|
+
}).join('\n');
|
|
288
|
+
}
|
|
248
289
|
function stripMetroInfo(errorMessage) {
|
|
249
290
|
// Newer versions of Metro don't include the list.
|
|
250
291
|
if (!errorMessage.includes('4. Remove the cache')) {
|
|
251
|
-
return
|
|
292
|
+
return errorMessage;
|
|
252
293
|
}
|
|
253
294
|
const lines = errorMessage.split('\n');
|
|
254
295
|
const index = lines.findIndex((line)=>line.includes('4. Remove the cache'));
|
|
255
296
|
if (index === -1) {
|
|
256
|
-
return
|
|
297
|
+
return errorMessage;
|
|
257
298
|
}
|
|
258
299
|
return lines.slice(index + 1).join('\n');
|
|
259
300
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import chalk from 'chalk';\nimport { Terminal } from 'metro-core';\nimport path from 'path';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatReactErrorLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n const mode = event.mode === 'NOBRIDGE' || event.mode === 'BRIDGE' ? '' : (event.mode ?? '');\n // @ts-expect-error\n if (level === 'warn' || level === 'error') {\n // Quick check to see if an unsymbolicated stack is being logged.\n const msg = event.data.join('\\n');\n if (msg.includes('.bundle//&platform=')) {\n const parsed = parseErrorStringToObject(msg);\n\n if (parsed) {\n maybeSymbolicateAndFormatReactErrorLogAsync(this.projectRoot, level, parsed)\n .then((res) => {\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, mode, res);\n })\n .catch((e) => {\n // Fallback on the original error message if we can't symbolicate the stack.\n debug('Error formatting stack', e);\n\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...event.data);\n });\n\n return;\n }\n }\n }\n\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n const converted = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (converted <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(converted.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n _logBundlingError(error: SnippetError): void {\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n const cause = error.cause as undefined | { _expoImportStack?: string };\n if (moduleResolutionError) {\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n if (cause?._expoImportStack) {\n message += `\\n\\n${cause?._expoImportStack}`;\n }\n return this.terminal.log(message);\n }\n if (cause?._expoImportStack) {\n error.message += `\\n\\n${cause._expoImportStack}`;\n }\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = stripMetroInfo(rawMessage);\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\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 | null {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return null;\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 null;\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","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","_log","event","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","mode","msg","join","includes","parsed","parseErrorStringToObject","maybeSymbolicateAndFormatReactErrorLogAsync","then","res","logLikeMetro","log","bind","catch","e","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","path","sep","replace","inputFile","entryFile","isAbsolute","relative","status","color","chalk","green","red","_bundleTimers","get","buildID","time","elapsed","micro","Number","converted","tenthFractionOfMicro","toFixed","cyan","bold","dim","plural","totalFileCount","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","_logBundlingError","error","moduleResolutionError","cause","maybeAppendCodeFrame","_expoImportStack","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","lines","split","index","findIndex","line","slice","body","formatted","ios","android","web","environment","trim"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import type { Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n const mode = event.mode === 'NOBRIDGE' || event.mode === 'BRIDGE' ? '' : (event.mode ?? '');\n // @ts-expect-error\n if (level === 'warn' || level === 'error') {\n let hasStack = false;\n const parsed = event.data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') return p;\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(this.projectRoot, level, p);\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...filtered);\n })();\n return;\n }\n }\n\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, mode, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n const converted = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (converted <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(converted.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n _logBundlingError(error: SnippetError): void {\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n if (moduleResolutionError) {\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n message += '\\n\\n' + nearestImportStack(error);\n return this.terminal.log(message);\n }\n\n attachImportStackToRootMessage(error);\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","extractCodeFrame","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","_log","event","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","mode","hasStack","parsed","map","msg","includes","stack","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","status","reason","value","isFallback","push","filtered","filter","_","logLikeMetro","log","bind","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","path","sep","replace","inputFile","entryFile","isAbsolute","relative","color","chalk","green","red","_bundleTimers","get","buildID","time","elapsed","micro","Number","converted","tenthFractionOfMicro","toFixed","cyan","bold","dim","plural","totalFileCount","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundlingError","error","moduleResolutionError","maybeAppendCodeFrame","nearestImportStack","attachImportStackToRootMessage","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","formatted","ios","android","web","environment","trim"],"mappings":"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"}
|
|
@@ -21,16 +21,16 @@ _export(exports, {
|
|
|
21
21
|
return logWarning;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
|
-
function
|
|
25
|
-
const data = /*#__PURE__*/ _interop_require_default(require("
|
|
26
|
-
|
|
24
|
+
function _TerminalReporter() {
|
|
25
|
+
const data = /*#__PURE__*/ _interop_require_default(require("@expo/metro/metro/lib/TerminalReporter"));
|
|
26
|
+
_TerminalReporter = function() {
|
|
27
27
|
return data;
|
|
28
28
|
};
|
|
29
29
|
return data;
|
|
30
30
|
}
|
|
31
|
-
function
|
|
32
|
-
const data = /*#__PURE__*/ _interop_require_default(require("
|
|
33
|
-
|
|
31
|
+
function _chalk() {
|
|
32
|
+
const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
33
|
+
_chalk = function() {
|
|
34
34
|
return data;
|
|
35
35
|
};
|
|
36
36
|
return data;
|
|
@@ -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 chalk from 'chalk';\nimport UpstreamTerminalReporter from 'metro/src/lib/TerminalReporter';\nimport { Terminal } from 'metro-core';\nimport type { WatcherStatus } from 'metro-file-map';\nimport util from 'util';\n\nimport {\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 {\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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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
_dependenciesToRegex: function() {
|
|
13
|
+
return _dependenciesToRegex;
|
|
14
|
+
},
|
|
15
|
+
createAutolinkingModuleResolver: function() {
|
|
16
|
+
return createAutolinkingModuleResolver;
|
|
17
|
+
},
|
|
18
|
+
createAutolinkingModuleResolverInput: function() {
|
|
19
|
+
return createAutolinkingModuleResolverInput;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const debug = require('debug')('expo:start:server:metro:autolinking-resolver');
|
|
23
|
+
// This is a list of known modules we want to always include in sticky resolution
|
|
24
|
+
// Specifying these skips platform- and module-specific checks and always includes them in the output
|
|
25
|
+
const KNOWN_STICKY_DEPENDENCIES = [
|
|
26
|
+
// NOTE: react and react-dom aren't native modules, but must also be deduplicated in bundles
|
|
27
|
+
'react',
|
|
28
|
+
'react-dom',
|
|
29
|
+
// NOTE: react-native won't be in autolinking output, since it's special
|
|
30
|
+
// We include it here manually, since we know it should be an unduplicated direct dependency
|
|
31
|
+
'react-native',
|
|
32
|
+
// Peer dependencies from expo
|
|
33
|
+
'react-native-webview',
|
|
34
|
+
'@expo/dom-webview',
|
|
35
|
+
// Dependencies from expo
|
|
36
|
+
'expo-asset',
|
|
37
|
+
'expo-constants',
|
|
38
|
+
'expo-file-system',
|
|
39
|
+
'expo-font',
|
|
40
|
+
'expo-keep-awake',
|
|
41
|
+
'expo-modules-core',
|
|
42
|
+
// Peer dependencies from expo-router
|
|
43
|
+
'react-native-gesture-handler',
|
|
44
|
+
'react-native-reanimated'
|
|
45
|
+
];
|
|
46
|
+
const AUTOLINKING_PLATFORMS = [
|
|
47
|
+
'android',
|
|
48
|
+
'ios'
|
|
49
|
+
];
|
|
50
|
+
const escapeDependencyName = (dependency)=>dependency.replace(/[*.?()[\]]/g, (x)=>`\\${x}`);
|
|
51
|
+
const _dependenciesToRegex = (dependencies)=>new RegExp(`^(${dependencies.map(escapeDependencyName).join('|')})($|/.*)`);
|
|
52
|
+
const getAutolinkingExports = ()=>require('expo/internal/unstable-autolinking-exports');
|
|
53
|
+
const toPlatformModuleDescription = (dependencies, platform)=>{
|
|
54
|
+
const resolvedModulePaths = {};
|
|
55
|
+
const resolvedModuleNames = [];
|
|
56
|
+
for(const dependencyName in dependencies){
|
|
57
|
+
const dependency = dependencies[dependencyName];
|
|
58
|
+
if (dependency) {
|
|
59
|
+
resolvedModuleNames.push(dependency.name);
|
|
60
|
+
resolvedModulePaths[dependency.name] = dependency.path;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
debug(`Sticky resolution for ${platform} registered ${resolvedModuleNames.length} resolutions:`, resolvedModuleNames);
|
|
64
|
+
return {
|
|
65
|
+
platform,
|
|
66
|
+
moduleTestRe: _dependenciesToRegex(resolvedModuleNames),
|
|
67
|
+
resolvedModulePaths
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
async function createAutolinkingModuleResolverInput({ platforms, projectRoot }) {
|
|
71
|
+
const autolinking = getAutolinkingExports();
|
|
72
|
+
const linker = autolinking.makeCachedDependenciesLinker({
|
|
73
|
+
projectRoot
|
|
74
|
+
});
|
|
75
|
+
return Object.fromEntries(await Promise.all(platforms.filter((platform)=>{
|
|
76
|
+
return AUTOLINKING_PLATFORMS.includes(platform);
|
|
77
|
+
}).map(async (platform)=>{
|
|
78
|
+
const dependencies = await autolinking.scanDependencyResolutionsForPlatform(linker, platform, KNOWN_STICKY_DEPENDENCIES);
|
|
79
|
+
const moduleDescription = toPlatformModuleDescription(dependencies, platform);
|
|
80
|
+
return [
|
|
81
|
+
platform,
|
|
82
|
+
moduleDescription
|
|
83
|
+
];
|
|
84
|
+
})));
|
|
85
|
+
}
|
|
86
|
+
function createAutolinkingModuleResolver(input, { getStrictResolver }) {
|
|
87
|
+
if (!input) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const fileSpecifierRe = /^[\\/]|^\.\.?(?:$|[\\/])/i;
|
|
91
|
+
const isAutolinkingPlatform = (platform)=>!!platform && input[platform] != null;
|
|
92
|
+
return function requestStickyModule(immutableContext, moduleName, platform) {
|
|
93
|
+
// NOTE(@kitten): We currently don't include Web. The `expo-doctor` check already warns
|
|
94
|
+
// about duplicates, and we can try to add Web later on. We should expand expo-modules-autolinking
|
|
95
|
+
// properly to support web first however
|
|
96
|
+
if (!isAutolinkingPlatform(platform)) {
|
|
97
|
+
return null;
|
|
98
|
+
} else if (fileSpecifierRe.test(moduleName)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const moduleDescription = input[platform];
|
|
102
|
+
const moduleMatch = moduleDescription.moduleTestRe.exec(moduleName);
|
|
103
|
+
if (moduleMatch) {
|
|
104
|
+
const resolvedModulePath = moduleDescription.resolvedModulePaths[moduleMatch[1]] || moduleName;
|
|
105
|
+
// We instead resolve as if it was a dependency from within the module (self-require/import)
|
|
106
|
+
const context = {
|
|
107
|
+
...immutableContext,
|
|
108
|
+
nodeModulesPaths: [
|
|
109
|
+
resolvedModulePath
|
|
110
|
+
],
|
|
111
|
+
originModulePath: resolvedModulePath
|
|
112
|
+
};
|
|
113
|
+
const res = getStrictResolver(context, platform)(moduleName);
|
|
114
|
+
debug(`Sticky resolution for ${platform}: ${moduleName} -> from: ${resolvedModulePath}`);
|
|
115
|
+
return res;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=createExpoAutolinkingResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/createExpoAutolinkingResolver.ts"],"sourcesContent":["import type { ResolutionContext } from '@expo/metro/metro-resolver';\nimport type { ResolutionResult as AutolinkingResolutionResult } from 'expo-modules-autolinking/exports';\n\nimport type { StrictResolverFactory } from './withMetroMultiPlatform';\nimport type { ExpoCustomMetroResolver } from './withMetroResolvers';\n\nconst debug = require('debug')(\n 'expo:start:server:metro:autolinking-resolver'\n) as typeof console.log;\n\n// This is a list of known modules we want to always include in sticky resolution\n// Specifying these skips platform- and module-specific checks and always includes them in the output\nconst KNOWN_STICKY_DEPENDENCIES = [\n // NOTE: react and react-dom aren't native modules, but must also be deduplicated in bundles\n 'react',\n 'react-dom',\n // NOTE: react-native won't be in autolinking output, since it's special\n // We include it here manually, since we know it should be an unduplicated direct dependency\n 'react-native',\n // Peer dependencies from expo\n 'react-native-webview',\n '@expo/dom-webview',\n // Dependencies from expo\n 'expo-asset',\n 'expo-constants',\n 'expo-file-system',\n 'expo-font',\n 'expo-keep-awake',\n 'expo-modules-core',\n // Peer dependencies from expo-router\n 'react-native-gesture-handler',\n 'react-native-reanimated',\n];\n\nconst AUTOLINKING_PLATFORMS = ['android', 'ios'] as const;\ntype AutolinkingPlatform = (typeof AUTOLINKING_PLATFORMS)[number];\n\nconst escapeDependencyName = (dependency: string) =>\n dependency.replace(/[*.?()[\\]]/g, (x) => `\\\\${x}`);\n\n/** Converts a list of module names to a regex that may either match bare module names or sub-modules of modules */\nexport const _dependenciesToRegex = (dependencies: string[]) =>\n new RegExp(`^(${dependencies.map(escapeDependencyName).join('|')})($|/.*)`);\n\nconst getAutolinkingExports = (): typeof import('expo/internal/unstable-autolinking-exports') =>\n require('expo/internal/unstable-autolinking-exports');\n\ninterface PlatformModuleDescription {\n platform: AutolinkingPlatform;\n moduleTestRe: RegExp;\n resolvedModulePaths: Record<string, string>;\n}\n\nconst toPlatformModuleDescription = (\n dependencies: AutolinkingResolutionResult,\n platform: AutolinkingPlatform\n): PlatformModuleDescription => {\n const resolvedModulePaths: Record<string, string> = {};\n const resolvedModuleNames: string[] = [];\n for (const dependencyName in dependencies) {\n const dependency = dependencies[dependencyName];\n if (dependency) {\n resolvedModuleNames.push(dependency.name);\n resolvedModulePaths[dependency.name] = dependency.path;\n }\n }\n debug(\n `Sticky resolution for ${platform} registered ${resolvedModuleNames.length} resolutions:`,\n resolvedModuleNames\n );\n return {\n platform,\n moduleTestRe: _dependenciesToRegex(resolvedModuleNames),\n resolvedModulePaths,\n };\n};\n\nexport type AutolinkingModuleResolverInput = {\n [platform in AutolinkingPlatform]?: PlatformModuleDescription;\n};\n\nexport async function createAutolinkingModuleResolverInput({\n platforms,\n projectRoot,\n}: {\n projectRoot: string;\n platforms: string[];\n}): Promise<AutolinkingModuleResolverInput> {\n const autolinking = getAutolinkingExports();\n const linker = autolinking.makeCachedDependenciesLinker({ projectRoot });\n\n return Object.fromEntries(\n await Promise.all(\n platforms\n .filter((platform): platform is AutolinkingPlatform => {\n return AUTOLINKING_PLATFORMS.includes(platform as any);\n })\n .map(async (platform) => {\n const dependencies = await autolinking.scanDependencyResolutionsForPlatform(\n linker,\n platform,\n KNOWN_STICKY_DEPENDENCIES\n );\n const moduleDescription = toPlatformModuleDescription(dependencies, platform);\n return [platform, moduleDescription] satisfies [\n AutolinkingPlatform,\n PlatformModuleDescription,\n ];\n })\n )\n ) as AutolinkingModuleResolverInput;\n}\n\nexport function createAutolinkingModuleResolver(\n input: AutolinkingModuleResolverInput | undefined,\n { getStrictResolver }: { getStrictResolver: StrictResolverFactory }\n): ExpoCustomMetroResolver | undefined {\n if (!input) {\n return undefined;\n }\n\n const fileSpecifierRe = /^[\\\\/]|^\\.\\.?(?:$|[\\\\/])/i;\n const isAutolinkingPlatform = (platform: string | null): platform is AutolinkingPlatform =>\n !!platform && (input as any)[platform] != null;\n\n return function requestStickyModule(immutableContext, moduleName, platform) {\n // NOTE(@kitten): We currently don't include Web. The `expo-doctor` check already warns\n // about duplicates, and we can try to add Web later on. We should expand expo-modules-autolinking\n // properly to support web first however\n if (!isAutolinkingPlatform(platform)) {\n return null;\n } else if (fileSpecifierRe.test(moduleName)) {\n return null;\n }\n\n const moduleDescription = input[platform]!;\n const moduleMatch = moduleDescription.moduleTestRe.exec(moduleName);\n if (moduleMatch) {\n const resolvedModulePath =\n moduleDescription.resolvedModulePaths[moduleMatch[1]] || moduleName;\n // We instead resolve as if it was a dependency from within the module (self-require/import)\n const context: ResolutionContext = {\n ...immutableContext,\n nodeModulesPaths: [resolvedModulePath],\n originModulePath: resolvedModulePath,\n };\n const res = getStrictResolver(context, platform)(moduleName);\n debug(`Sticky resolution for ${platform}: ${moduleName} -> from: ${resolvedModulePath}`);\n return res;\n }\n\n return null;\n };\n}\n"],"names":["_dependenciesToRegex","createAutolinkingModuleResolver","createAutolinkingModuleResolverInput","debug","require","KNOWN_STICKY_DEPENDENCIES","AUTOLINKING_PLATFORMS","escapeDependencyName","dependency","replace","x","dependencies","RegExp","map","join","getAutolinkingExports","toPlatformModuleDescription","platform","resolvedModulePaths","resolvedModuleNames","dependencyName","push","name","path","length","moduleTestRe","platforms","projectRoot","autolinking","linker","makeCachedDependenciesLinker","Object","fromEntries","Promise","all","filter","includes","scanDependencyResolutionsForPlatform","moduleDescription","input","getStrictResolver","undefined","fileSpecifierRe","isAutolinkingPlatform","requestStickyModule","immutableContext","moduleName","test","moduleMatch","exec","resolvedModulePath","context","nodeModulesPaths","originModulePath","res"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/createExpoFallbackResolver.ts"],"sourcesContent":["// This file creates the fallback resolver\n// The fallback resolver applies only to module imports and should be the last resolver\n// in the chain. It applies to failed Node module resolution of modules and will attempt\n// to resolve them to `expo` and `expo-router` dependencies that couldn't be resolved.\n// This resolves isolated dependency issues, where we expect dependencies of `expo`\n// and `expo-router` to be resolvable, due to hoisting, but they aren't hoisted in\n// a user's project.\n// See: https://github.com/expo/expo/pull/34286\n\nimport type { ResolutionContext } from 'metro-resolver';\nimport path from 'path';\n\nimport type { StrictResolver, StrictResolverFactory } from './withMetroMultiPlatform';\nimport type { ExpoCustomMetroResolver } from './withMetroResolvers';\n\n/** A record of dependencies that we know are only used for scripts and config-plugins\n * @privateRemarks\n * This includes dependencies we never resolve indirectly. Generally, we only want\n * to add fallback resolutions for dependencies of `expo` and `expo-router` that\n * are either transpiled into output code or resolved from other Expo packages\n * without them having direct dependencies on these dependencies.\n * Meaning: If you update this list, exclude what a user might use when they\n * forget to specify their own dependencies, rather than what we use ourselves\n * only in `expo` and `expo-router`.\n */\nconst EXCLUDE_ORIGIN_MODULES: Record<string, true | undefined> = {\n '@expo/config': true,\n '@expo/config-plugins': true,\n 'schema-utils': true, // Used by `expo-router/plugin`\n semver: true, // Used by `expo-router/doctor`\n};\n\ninterface PackageMetaPeerDependenciesMetaEntry {\n [propName: string]: unknown;\n optional?: boolean;\n}\n\ninterface PackageMeta {\n readonly [propName: string]: unknown;\n readonly name?: string;\n readonly main?: string;\n readonly exports?: any; // unused\n readonly dependencies?: Record<string, unknown>;\n readonly peerDependencies?: Record<string, unknown>;\n readonly peerDependenciesMeta?: Record<\n string,\n PackageMetaPeerDependenciesMetaEntry | undefined | null\n >;\n}\n\ninterface ModuleDescription {\n originModulePath: string;\n moduleTestRe: RegExp;\n}\n\nconst debug = require('debug')('expo:start:server:metro:fallback-resolver') as typeof console.log;\n\n/** Converts a list of module names to a regex that may either match bare module names or sub-modules of modules */\nconst dependenciesToRegex = (dependencies: string[]) =>\n new RegExp(`^(?:${dependencies.join('|')})(?:$|/)`);\n\n/** Resolves an origin module and outputs a filter regex and target path for it */\nconst getModuleDescriptionWithResolver = (\n context: ResolutionContext,\n resolve: StrictResolver,\n originModuleName: string\n): ModuleDescription | null => {\n let filePath: string | undefined;\n let packageMeta: PackageMeta | undefined | null;\n try {\n const resolution = resolve(path.join(originModuleName, 'package.json'));\n if (resolution.type !== 'sourceFile') {\n debug(`Fallback module resolution failed for origin module: ${originModuleName})`);\n return null;\n }\n filePath = resolution.filePath;\n packageMeta = context.getPackage(filePath);\n if (!packageMeta) {\n return null;\n }\n } catch (error: any) {\n debug(\n `Fallback module resolution threw: ${error.constructor.name}. (module: ${filePath || originModuleName})`\n );\n return null;\n }\n let dependencies: string[] = [];\n if (packageMeta.dependencies) dependencies.push(...Object.keys(packageMeta.dependencies));\n if (packageMeta.peerDependencies) {\n const peerDependenciesMeta = packageMeta.peerDependenciesMeta;\n let peerDependencies = Object.keys(packageMeta.peerDependencies);\n // We explicitly include non-optional peer dependencies. Non-optional peer dependencies of\n // `expo` and `expo-router` are either expected to be accessible on a project-level, since\n // both are meant to be installed is direct dependencies, or shouldn't be accessible when\n // they're fulfilled as isolated dependencies.\n // The exception are only *optional* peer dependencies, since when they're installed\n // automatically by newer package manager behaviour, they may become isolated dependencies\n // that we still wish to access.\n if (peerDependenciesMeta) {\n peerDependencies = peerDependencies.filter((dependency) => {\n const peerMeta = peerDependenciesMeta[dependency];\n return peerMeta && typeof peerMeta === 'object' && peerMeta.optional === true;\n });\n }\n dependencies.push(...peerDependencies);\n }\n // We deduplicate the dependencies and exclude modules that we know are only used for scripts or config-plugins\n dependencies = dependencies.filter((moduleName, index, dependenciesArr) => {\n if (EXCLUDE_ORIGIN_MODULES[moduleName]) return false;\n return dependenciesArr.indexOf(moduleName) === index;\n });\n // Return test regex for dependencies and full origin module path to resolve through\n const originModulePath = path.dirname(filePath);\n return dependencies.length\n ? { originModulePath, moduleTestRe: dependenciesToRegex(dependencies) }\n : null;\n};\n\n/** Creates a fallback module resolver that resolves dependencis of modules named in `originModuleNames` via their path.\n * @remarks\n * The fallback resolver targets modules dependended on by modules named in `originModuleNames` and resolves\n * them from the module root of these origin modules instead.\n * It should only be used as a fallback after normal Node resolution (and other resolvers) have failed for:\n * - the `expo` package\n * - the `expo-router` package\n * Dependencies mentioned as either optional peer dependencies or direct dependencies by these modules may be isolated\n * and inaccessible via standard Node module resolution. This may happen when either transpilation adds these\n * dependencies to other parts of the tree (e.g. `@babel/runtime`) or when a dependency fails to hoist due to either\n * a corrupted dependency tree or when a peer dependency is fulfilled incorrectly (e.g. `expo-asset`)\n * @privateRemarks\n * This does NOT follow Node resolution and is *only* intended to provide a fallback for modules that we depend on\n * ourselves and know we can resolve (via expo or expo-router)!\n */\nexport function createFallbackModuleResolver({\n projectRoot,\n originModuleNames,\n getStrictResolver,\n}: {\n projectRoot: string;\n originModuleNames: string[];\n getStrictResolver: StrictResolverFactory;\n}): ExpoCustomMetroResolver {\n const _moduleDescriptionsCache: Record<string, ModuleDescription | null> = {};\n\n const getModuleDescription = (\n immutableContext: ResolutionContext,\n originModuleName: string,\n platform: string | null\n ) => {\n if (_moduleDescriptionsCache[originModuleName] !== undefined) {\n return _moduleDescriptionsCache[originModuleName];\n }\n // Resolve the origin module itself via the project root rather than the file that requested the missing module\n // The addition of `package.json` doesn't matter here. We just need a file path that'll be turned into a directory path\n // We don't need to modify `nodeModulesPaths` since it's guaranteed to contain the project's node modules paths\n const context: ResolutionContext = {\n ...immutableContext,\n originModulePath: path.join(projectRoot, 'package.json'),\n };\n return (_moduleDescriptionsCache[originModuleName] = getModuleDescriptionWithResolver(\n context,\n getStrictResolver(context, platform),\n originModuleName\n ));\n };\n\n const fileSpecifierRe = /^[\\\\/]|^\\.\\.?(?:$|[\\\\/])/i;\n\n return function requestFallbackModule(immutableContext, moduleName, platform) {\n // Early return if `moduleName` cannot be a module specifier\n // This doesn't have to be accurate as this resolver is a fallback for failed resolutions and\n // we're only doing this to avoid unnecessary resolution work\n if (fileSpecifierRe.test(moduleName)) {\n return null;\n }\n\n for (const originModuleName of originModuleNames) {\n const moduleDescription = getModuleDescription(immutableContext, originModuleName, platform);\n if (moduleDescription && moduleDescription.moduleTestRe.test(moduleName)) {\n // We instead resolve as if it was depended on by the `originModulePath` (the module named in `originModuleNames`)\n const context: ResolutionContext = {\n ...immutableContext,\n nodeModulesPaths: [moduleDescription.originModulePath],\n originModulePath: moduleDescription.originModulePath,\n };\n const res = getStrictResolver(context, platform)(moduleName);\n debug(\n `Fallback resolution for ${platform}: ${moduleName} -> from origin: ${originModuleName}`\n );\n return res;\n }\n }\n\n return null;\n };\n}\n"],"names":["createFallbackModuleResolver","EXCLUDE_ORIGIN_MODULES","semver","debug","require","dependenciesToRegex","dependencies","RegExp","join","getModuleDescriptionWithResolver","context","resolve","originModuleName","filePath","packageMeta","resolution","path","type","getPackage","error","constructor","name","push","Object","keys","peerDependencies","peerDependenciesMeta","filter","dependency","peerMeta","optional","moduleName","index","dependenciesArr","indexOf","originModulePath","dirname","length","moduleTestRe","projectRoot","originModuleNames","getStrictResolver","_moduleDescriptionsCache","getModuleDescription","immutableContext","platform","undefined","fileSpecifierRe","requestFallbackModule","test","moduleDescription","nodeModulesPaths","res"],"mappings":"AAAA,0CAA0C;AAC1C,uFAAuF;AACvF,wFAAwF;AACxF,sFAAsF;AACtF,mFAAmF;AACnF,kFAAkF;AAClF,oBAAoB;AACpB,+CAA+C;;;;;+BA8H/BA;;;eAAAA;;;;gEA3HC;;;;;;;;;;;AAKjB;;;;;;;;;CASC,GACD,MAAMC,yBAA2D;IAC/D,gBAAgB;IAChB,wBAAwB;IACxB,gBAAgB;IAChBC,QAAQ;AACV;AAyBA,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,iHAAiH,GACjH,MAAMC,sBAAsB,CAACC,eAC3B,IAAIC,OAAO,CAAC,IAAI,EAAED,aAAaE,IAAI,CAAC,KAAK,QAAQ,CAAC;AAEpD,gFAAgF,GAChF,MAAMC,mCAAmC,CACvCC,SACAC,SACAC;IAEA,IAAIC;IACJ,IAAIC;IACJ,IAAI;QACF,MAAMC,aAAaJ,QAAQK,eAAI,CAACR,IAAI,CAACI,kBAAkB;QACvD,IAAIG,WAAWE,IAAI,KAAK,cAAc;YACpCd,MAAM,CAAC,qDAAqD,EAAES,iBAAiB,CAAC,CAAC;YACjF,OAAO;QACT;QACAC,WAAWE,WAAWF,QAAQ;QAC9BC,cAAcJ,QAAQQ,UAAU,CAACL;QACjC,IAAI,CAACC,aAAa;YAChB,OAAO;QACT;IACF,EAAE,OAAOK,OAAY;QACnBhB,MACE,CAAC,kCAAkC,EAAEgB,MAAMC,WAAW,CAACC,IAAI,CAAC,WAAW,EAAER,YAAYD,iBAAiB,CAAC,CAAC;QAE1G,OAAO;IACT;IACA,IAAIN,eAAyB,EAAE;IAC/B,IAAIQ,YAAYR,YAAY,EAAEA,aAAagB,IAAI,IAAIC,OAAOC,IAAI,CAACV,YAAYR,YAAY;IACvF,IAAIQ,YAAYW,gBAAgB,EAAE;QAChC,MAAMC,uBAAuBZ,YAAYY,oBAAoB;QAC7D,IAAID,mBAAmBF,OAAOC,IAAI,CAACV,YAAYW,gBAAgB;QAC/D,0FAA0F;QAC1F,0FAA0F;QAC1F,yFAAyF;QACzF,8CAA8C;QAC9C,oFAAoF;QACpF,0FAA0F;QAC1F,gCAAgC;QAChC,IAAIC,sBAAsB;YACxBD,mBAAmBA,iBAAiBE,MAAM,CAAC,CAACC;gBAC1C,MAAMC,WAAWH,oBAAoB,CAACE,WAAW;gBACjD,OAAOC,YAAY,OAAOA,aAAa,YAAYA,SAASC,QAAQ,KAAK;YAC3E;QACF;QACAxB,aAAagB,IAAI,IAAIG;IACvB;IACA,+GAA+G;IAC/GnB,eAAeA,aAAaqB,MAAM,CAAC,CAACI,YAAYC,OAAOC;QACrD,IAAIhC,sBAAsB,CAAC8B,WAAW,EAAE,OAAO;QAC/C,OAAOE,gBAAgBC,OAAO,CAACH,gBAAgBC;IACjD;IACA,oFAAoF;IACpF,MAAMG,mBAAmBnB,eAAI,CAACoB,OAAO,CAACvB;IACtC,OAAOP,aAAa+B,MAAM,GACtB;QAAEF;QAAkBG,cAAcjC,oBAAoBC;IAAc,IACpE;AACN;AAiBO,SAASN,6BAA6B,EAC3CuC,WAAW,EACXC,iBAAiB,EACjBC,iBAAiB,EAKlB;IACC,MAAMC,2BAAqE,CAAC;IAE5E,MAAMC,uBAAuB,CAC3BC,kBACAhC,kBACAiC;QAEA,IAAIH,wBAAwB,CAAC9B,iBAAiB,KAAKkC,WAAW;YAC5D,OAAOJ,wBAAwB,CAAC9B,iBAAiB;QACnD;QACA,+GAA+G;QAC/G,uHAAuH;QACvH,+GAA+G;QAC/G,MAAMF,UAA6B;YACjC,GAAGkC,gBAAgB;YACnBT,kBAAkBnB,eAAI,CAACR,IAAI,CAAC+B,aAAa;QAC3C;QACA,OAAQG,wBAAwB,CAAC9B,iBAAiB,GAAGH,iCACnDC,SACA+B,kBAAkB/B,SAASmC,WAC3BjC;IAEJ;IAEA,MAAMmC,kBAAkB;IAExB,OAAO,SAASC,sBAAsBJ,gBAAgB,EAAEb,UAAU,EAAEc,QAAQ;QAC1E,4DAA4D;QAC5D,6FAA6F;QAC7F,6DAA6D;QAC7D,IAAIE,gBAAgBE,IAAI,CAAClB,aAAa;YACpC,OAAO;QACT;QAEA,KAAK,MAAMnB,oBAAoB4B,kBAAmB;YAChD,MAAMU,oBAAoBP,qBAAqBC,kBAAkBhC,kBAAkBiC;YACnF,IAAIK,qBAAqBA,kBAAkBZ,YAAY,CAACW,IAAI,CAAClB,aAAa;gBACxE,kHAAkH;gBAClH,MAAMrB,UAA6B;oBACjC,GAAGkC,gBAAgB;oBACnBO,kBAAkB;wBAACD,kBAAkBf,gBAAgB;qBAAC;oBACtDA,kBAAkBe,kBAAkBf,gBAAgB;gBACtD;gBACA,MAAMiB,MAAMX,kBAAkB/B,SAASmC,UAAUd;gBACjD5B,MACE,CAAC,wBAAwB,EAAE0C,SAAS,EAAE,EAAEd,WAAW,iBAAiB,EAAEnB,kBAAkB;gBAE1F,OAAOwC;YACT;QACF;QAEA,OAAO;IACT;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/createExpoFallbackResolver.ts"],"sourcesContent":["// This file creates the fallback resolver\n// The fallback resolver applies only to module imports and should be the last resolver\n// in the chain. It applies to failed Node module resolution of modules and will attempt\n// to resolve them to `expo` and `expo-router` dependencies that couldn't be resolved.\n// This resolves isolated dependency issues, where we expect dependencies of `expo`\n// and `expo-router` to be resolvable, due to hoisting, but they aren't hoisted in\n// a user's project.\n// See: https://github.com/expo/expo/pull/34286\n\nimport type { ResolutionContext, PackageJson } from '@expo/metro/metro-resolver/types';\nimport path from 'path';\n\nimport type { StrictResolver, StrictResolverFactory } from './withMetroMultiPlatform';\nimport type { ExpoCustomMetroResolver } from './withMetroResolvers';\n\n/** A record of dependencies that we know are only used for scripts and config-plugins\n * @privateRemarks\n * This includes dependencies we never resolve indirectly. Generally, we only want\n * to add fallback resolutions for dependencies of `expo` and `expo-router` that\n * are either transpiled into output code or resolved from other Expo packages\n * without them having direct dependencies on these dependencies.\n * Meaning: If you update this list, exclude what a user might use when they\n * forget to specify their own dependencies, rather than what we use ourselves\n * only in `expo` and `expo-router`.\n */\nconst EXCLUDE_ORIGIN_MODULES: Record<string, true | undefined> = {\n '@expo/config': true,\n '@expo/config-plugins': true,\n 'schema-utils': true, // Used by `expo-router/plugin`\n semver: true, // Used by `expo-router/doctor`\n};\n\ninterface PackageMetaPeerDependenciesMetaEntry {\n [propName: string]: unknown;\n optional?: boolean;\n}\n\ninterface PackageMeta extends PackageJson {\n readonly [propName: string]: unknown;\n readonly dependencies?: Record<string, unknown>;\n readonly peerDependencies?: Record<string, unknown>;\n readonly peerDependenciesMeta?: Record<\n string,\n PackageMetaPeerDependenciesMetaEntry | undefined | null\n >;\n}\n\ninterface ModuleDescription {\n originModulePath: string;\n moduleTestRe: RegExp;\n}\n\nconst debug = require('debug')('expo:start:server:metro:fallback-resolver') as typeof console.log;\n\n/** Converts a list of module names to a regex that may either match bare module names or sub-modules of modules */\nconst dependenciesToRegex = (dependencies: string[]) =>\n new RegExp(`^(?:${dependencies.join('|')})(?:$|/)`);\n\n/** Resolves an origin module and outputs a filter regex and target path for it */\nconst getModuleDescriptionWithResolver = (\n context: ResolutionContext,\n resolve: StrictResolver,\n originModuleName: string\n): ModuleDescription | null => {\n let filePath: string | undefined;\n let packageMeta: PackageMeta | undefined | null;\n try {\n const resolution = resolve(path.join(originModuleName, 'package.json'));\n if (resolution.type !== 'sourceFile') {\n debug(`Fallback module resolution failed for origin module: ${originModuleName})`);\n return null;\n }\n filePath = resolution.filePath;\n // Upcast PackageJson to PackageMeta\n packageMeta = context.getPackage(filePath) as PackageMeta | null | undefined;\n if (!packageMeta) {\n return null;\n }\n } catch (error: any) {\n debug(\n `Fallback module resolution threw: ${error.constructor.name}. (module: ${filePath || originModuleName})`\n );\n return null;\n }\n let dependencies: string[] = [];\n if (packageMeta.dependencies) dependencies.push(...Object.keys(packageMeta.dependencies));\n if (packageMeta.peerDependencies) {\n const peerDependenciesMeta = packageMeta.peerDependenciesMeta;\n let peerDependencies = Object.keys(packageMeta.peerDependencies);\n // We explicitly include non-optional peer dependencies. Non-optional peer dependencies of\n // `expo` and `expo-router` are either expected to be accessible on a project-level, since\n // both are meant to be installed is direct dependencies, or shouldn't be accessible when\n // they're fulfilled as isolated dependencies.\n // The exception are only *optional* peer dependencies, since when they're installed\n // automatically by newer package manager behaviour, they may become isolated dependencies\n // that we still wish to access.\n if (peerDependenciesMeta) {\n peerDependencies = peerDependencies.filter((dependency) => {\n const peerMeta = peerDependenciesMeta[dependency];\n return peerMeta && typeof peerMeta === 'object' && peerMeta.optional === true;\n });\n }\n dependencies.push(...peerDependencies);\n }\n // We deduplicate the dependencies and exclude modules that we know are only used for scripts or config-plugins\n dependencies = dependencies.filter((moduleName, index, dependenciesArr) => {\n if (EXCLUDE_ORIGIN_MODULES[moduleName]) return false;\n return dependenciesArr.indexOf(moduleName) === index;\n });\n // Return test regex for dependencies and full origin module path to resolve through\n const originModulePath = path.dirname(filePath);\n return dependencies.length\n ? { originModulePath, moduleTestRe: dependenciesToRegex(dependencies) }\n : null;\n};\n\n/** Creates a fallback module resolver that resolves dependencis of modules named in `originModuleNames` via their path.\n * @remarks\n * The fallback resolver targets modules dependended on by modules named in `originModuleNames` and resolves\n * them from the module root of these origin modules instead.\n * It should only be used as a fallback after normal Node resolution (and other resolvers) have failed for:\n * - the `expo` package\n * - the `expo-router` package\n * Dependencies mentioned as either optional peer dependencies or direct dependencies by these modules may be isolated\n * and inaccessible via standard Node module resolution. This may happen when either transpilation adds these\n * dependencies to other parts of the tree (e.g. `@babel/runtime`) or when a dependency fails to hoist due to either\n * a corrupted dependency tree or when a peer dependency is fulfilled incorrectly (e.g. `expo-asset`)\n * @privateRemarks\n * This does NOT follow Node resolution and is *only* intended to provide a fallback for modules that we depend on\n * ourselves and know we can resolve (via expo or expo-router)!\n */\nexport function createFallbackModuleResolver({\n projectRoot,\n originModuleNames,\n getStrictResolver,\n}: {\n projectRoot: string;\n originModuleNames: string[];\n getStrictResolver: StrictResolverFactory;\n}): ExpoCustomMetroResolver {\n const _moduleDescriptionsCache: Record<string, ModuleDescription | null> = {};\n\n const getModuleDescription = (\n immutableContext: ResolutionContext,\n originModuleName: string,\n platform: string | null\n ) => {\n if (_moduleDescriptionsCache[originModuleName] !== undefined) {\n return _moduleDescriptionsCache[originModuleName];\n }\n // Resolve the origin module itself via the project root rather than the file that requested the missing module\n // The addition of `package.json` doesn't matter here. We just need a file path that'll be turned into a directory path\n // We don't need to modify `nodeModulesPaths` since it's guaranteed to contain the project's node modules paths\n const context: ResolutionContext = {\n ...immutableContext,\n originModulePath: path.join(projectRoot, 'package.json'),\n };\n return (_moduleDescriptionsCache[originModuleName] = getModuleDescriptionWithResolver(\n context,\n getStrictResolver(context, platform),\n originModuleName\n ));\n };\n\n const fileSpecifierRe = /^[\\\\/]|^\\.\\.?(?:$|[\\\\/])/i;\n\n return function requestFallbackModule(immutableContext, moduleName, platform) {\n // Early return if `moduleName` cannot be a module specifier\n // This doesn't have to be accurate as this resolver is a fallback for failed resolutions and\n // we're only doing this to avoid unnecessary resolution work\n if (fileSpecifierRe.test(moduleName)) {\n return null;\n }\n\n for (const originModuleName of originModuleNames) {\n const moduleDescription = getModuleDescription(immutableContext, originModuleName, platform);\n if (moduleDescription && moduleDescription.moduleTestRe.test(moduleName)) {\n // We instead resolve as if it was depended on by the `originModulePath` (the module named in `originModuleNames`)\n const context: ResolutionContext = {\n ...immutableContext,\n nodeModulesPaths: [moduleDescription.originModulePath],\n originModulePath: moduleDescription.originModulePath,\n };\n const res = getStrictResolver(context, platform)(moduleName);\n debug(\n `Fallback resolution for ${platform}: ${moduleName} -> from origin: ${originModuleName}`\n );\n return res;\n }\n }\n\n return null;\n };\n}\n"],"names":["createFallbackModuleResolver","EXCLUDE_ORIGIN_MODULES","semver","debug","require","dependenciesToRegex","dependencies","RegExp","join","getModuleDescriptionWithResolver","context","resolve","originModuleName","filePath","packageMeta","resolution","path","type","getPackage","error","constructor","name","push","Object","keys","peerDependencies","peerDependenciesMeta","filter","dependency","peerMeta","optional","moduleName","index","dependenciesArr","indexOf","originModulePath","dirname","length","moduleTestRe","projectRoot","originModuleNames","getStrictResolver","_moduleDescriptionsCache","getModuleDescription","immutableContext","platform","undefined","fileSpecifierRe","requestFallbackModule","test","moduleDescription","nodeModulesPaths","res"],"mappings":"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"}
|