@expo/cli 54.1.0-canary-20251023-4c86f95 → 54.1.0-canary-20260119-17896bf
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/add-module.js +4 -1
- package/build/bin/cli +3 -1
- package/build/bin/cli.map +1 -1
- package/build/src/export/embed/exportEmbedAsync.js +1 -2
- package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
- package/build/src/install/applyPlugins.js +2 -1
- package/build/src/install/applyPlugins.js.map +1 -1
- package/build/src/install/fixPackages.js +1 -1
- package/build/src/install/fixPackages.js.map +1 -1
- package/build/src/install/installAsync.js +1 -1
- package/build/src/install/installAsync.js.map +1 -1
- package/build/src/install/utils/parsePackageSpecifier.js +24 -0
- package/build/src/install/utils/parsePackageSpecifier.js.map +1 -0
- package/build/src/run/ios/runIosAsync.js +8 -0
- package/build/src/run/ios/runIosAsync.js.map +1 -1
- package/build/src/start/interface/commandsTable.js.map +1 -1
- package/build/src/start/interface/interactiveActions.js +14 -9
- package/build/src/start/interface/interactiveActions.js.map +1 -1
- package/build/src/start/interface/startInterface.js +3 -0
- package/build/src/start/interface/startInterface.js.map +1 -1
- package/build/src/start/platforms/android/adb.js +1 -1
- package/build/src/start/platforms/android/adb.js.map +1 -1
- package/build/src/start/server/DevToolsPluginManager.js +8 -4
- package/build/src/start/server/DevToolsPluginManager.js.map +1 -1
- package/build/src/start/server/MCP.js +28 -5
- package/build/src/start/server/MCP.js.map +1 -1
- package/build/src/start/server/UrlCreator.js +1 -1
- package/build/src/start/server/UrlCreator.js.map +1 -1
- package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js +10 -2
- package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +29 -155
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +151 -33
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/createExpoAutolinkingResolver.js +1 -3
- package/build/src/start/server/metro/createExpoAutolinkingResolver.js.map +1 -1
- package/build/src/start/server/metro/createExpoFallbackResolver.js +1 -3
- package/build/src/start/server/metro/createExpoFallbackResolver.js.map +1 -1
- package/build/src/start/server/metro/createServerComponentsMiddleware.js +1 -2
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js +2 -2
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/metro/debugging/createDebugMiddleware.js +23 -9
- package/build/src/start/server/metro/debugging/createDebugMiddleware.js.map +1 -1
- package/build/src/start/server/metro/dev-server/compression.js +45 -0
- package/build/src/start/server/metro/dev-server/compression.js.map +1 -0
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +2 -2
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
- package/build/src/start/server/metro/externals.js +11 -0
- package/build/src/start/server/metro/externals.js.map +1 -1
- package/build/src/start/server/metro/fetchRouterManifest.js +1 -1
- package/build/src/start/server/metro/fetchRouterManifest.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +98 -27
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/log-box/LogBoxLog.js +7 -11
- package/build/src/start/server/metro/log-box/LogBoxLog.js.map +1 -1
- package/build/src/start/server/metro/log-box/LogBoxSymbolication.js.map +1 -1
- package/build/src/start/server/metro/metroErrorInterface.js +43 -14
- package/build/src/start/server/metro/metroErrorInterface.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +74 -57
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/CorsMiddleware.js +43 -12
- package/build/src/start/server/middleware/CorsMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/CreateFileMiddleware.js +63 -24
- package/build/src/start/server/middleware/CreateFileMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js +3 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ManifestMiddleware.js +14 -9
- package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
- package/build/src/start/startAsync.js +12 -9
- package/build/src/start/startAsync.js.map +1 -1
- package/build/src/utils/env.js +36 -2
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/interactive.js +1 -1
- package/build/src/utils/interactive.js.map +1 -1
- package/build/src/utils/jsonl.js +243 -0
- package/build/src/utils/jsonl.js.map +1 -0
- package/build/src/utils/net.js +43 -0
- package/build/src/utils/net.js.map +1 -0
- package/build/src/utils/progress.js +5 -0
- package/build/src/utils/progress.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/build/src/utils/url.js +4 -8
- package/build/src/utils/url.js.map +1 -1
- package/package.json +25 -28
- package/static/canary/react-is/cjs/react-is.development.js +133 -0
- package/static/canary/react-is/cjs/react-is.production.js +130 -0
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactFabric-dev.js +16820 -0
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactFabric-prod.js +10552 -0
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactFabric-profiling.js +11255 -0
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +17064 -0
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +10742 -0
- package/static/canary/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +11450 -0
- package/static/canary/scheduler/cjs/scheduler-unstable_mock.development.js +414 -0
- package/static/canary/scheduler/cjs/scheduler-unstable_mock.production.js +406 -0
- package/static/canary/scheduler/cjs/scheduler-unstable_post_task.development.js +150 -0
- package/static/canary/scheduler/cjs/scheduler-unstable_post_task.production.js +140 -0
- package/static/canary/scheduler/cjs/scheduler.development.js +364 -0
- package/static/canary/scheduler/cjs/scheduler.native.development.js +350 -0
- package/static/canary/scheduler/cjs/scheduler.native.production.js +330 -0
- package/static/canary/scheduler/cjs/scheduler.production.js +340 -0
- package/static/canary-full/node_modules/react/LICENSE +21 -0
- package/static/canary-full/node_modules/react/README.md +37 -0
- package/static/canary-full/node_modules/react/cjs/react-compiler-runtime.development.js +24 -0
- package/static/canary-full/node_modules/react/cjs/react-compiler-runtime.production.js +16 -0
- package/static/canary-full/node_modules/react/cjs/react-compiler-runtime.profiling.js +16 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-dev-runtime.development.js +349 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-dev-runtime.production.js +14 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-dev-runtime.profiling.js +14 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-dev-runtime.react-server.development.js +385 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-dev-runtime.react-server.production.js +40 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-runtime.development.js +358 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-runtime.production.js +34 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-runtime.profiling.js +34 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-runtime.react-server.development.js +385 -0
- package/static/canary-full/node_modules/react/cjs/react-jsx-runtime.react-server.production.js +40 -0
- package/static/canary-full/node_modules/react/cjs/react.development.js +1250 -0
- package/static/canary-full/node_modules/react/cjs/react.production.js +544 -0
- package/static/canary-full/node_modules/react/cjs/react.react-server.development.js +815 -0
- package/static/canary-full/node_modules/react/cjs/react.react-server.production.js +429 -0
- package/static/canary-full/node_modules/react/compiler-runtime.js +14 -0
- package/static/canary-full/node_modules/react/index.js +7 -0
- package/static/canary-full/node_modules/react/jsx-dev-runtime.js +7 -0
- package/static/canary-full/node_modules/react/jsx-dev-runtime.react-server.js +7 -0
- package/static/canary-full/node_modules/react/jsx-runtime.js +7 -0
- package/static/canary-full/node_modules/react/jsx-runtime.react-server.js +7 -0
- package/static/canary-full/node_modules/react/package.json +51 -0
- package/static/canary-full/node_modules/react/react.react-server.js +7 -0
- package/static/canary-full/node_modules/react-dom/LICENSE +21 -0
- package/static/canary-full/node_modules/react-dom/README.md +60 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-client.development.js +25089 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-client.production.js +15426 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-profiling.development.js +25476 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-profiling.profiling.js +16296 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server-legacy.browser.development.js +9035 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +5892 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js +9035 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +5972 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.browser.development.js +9424 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.browser.production.js +6384 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.bun.development.js +8739 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.bun.production.js +5967 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.edge.development.js +9443 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.edge.production.js +6477 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.node.development.js +9317 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-server.node.production.js +6372 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-test-utils.development.js +24 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom-test-utils.production.js +21 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom.development.js +424 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom.production.js +210 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom.react-server.development.js +340 -0
- package/static/canary-full/node_modules/react-dom/cjs/react-dom.react-server.production.js +152 -0
- package/static/canary-full/node_modules/react-dom/client.js +38 -0
- package/static/canary-full/node_modules/react-dom/client.react-server.js +5 -0
- package/static/canary-full/node_modules/react-dom/index.js +38 -0
- package/static/canary-full/node_modules/react-dom/package.json +117 -0
- package/static/canary-full/node_modules/react-dom/profiling.js +38 -0
- package/static/canary-full/node_modules/react-dom/profiling.react-server.js +5 -0
- package/static/canary-full/node_modules/react-dom/react-dom.react-server.js +7 -0
- package/static/canary-full/node_modules/react-dom/server.browser.js +18 -0
- package/static/canary-full/node_modules/react-dom/server.bun.js +19 -0
- package/static/canary-full/node_modules/react-dom/server.edge.js +19 -0
- package/static/canary-full/node_modules/react-dom/server.js +3 -0
- package/static/canary-full/node_modules/react-dom/server.node.js +18 -0
- package/static/canary-full/node_modules/react-dom/server.react-server.js +5 -0
- package/static/canary-full/node_modules/react-dom/static.browser.js +12 -0
- package/static/canary-full/node_modules/react-dom/static.edge.js +12 -0
- package/static/canary-full/node_modules/react-dom/static.js +3 -0
- package/static/canary-full/node_modules/react-dom/static.node.js +12 -0
- package/static/canary-full/node_modules/react-dom/static.react-server.js +5 -0
- package/static/canary-full/node_modules/react-dom/test-utils.js +7 -0
- package/build/src/start/interface/cliExtensionMenuItemHandler.js +0 -173
- package/build/src/start/interface/cliExtensionMenuItemHandler.js.map +0 -1
- package/build/src/start/interface/createDevToolsMenuItems.js +0 -159
- package/build/src/start/interface/createDevToolsMenuItems.js.map +0 -1
- package/build/src/start/server/DevToolsPlugin.js +0 -60
- package/build/src/start/server/DevToolsPlugin.js.map +0 -1
- package/build/src/start/server/DevToolsPlugin.schema.js +0 -79
- package/build/src/start/server/DevToolsPlugin.schema.js.map +0 -1
- package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js +0 -119
- package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js.map +0 -1
- package/build/src/start/server/DevToolsPluginCliExtensionResults.js +0 -61
- package/build/src/start/server/DevToolsPluginCliExtensionResults.js.map +0 -1
- package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js +0 -75
- package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js.map +0 -1
|
@@ -15,6 +15,9 @@ _export(exports, {
|
|
|
15
15
|
extractCodeFrame: function() {
|
|
16
16
|
return extractCodeFrame;
|
|
17
17
|
},
|
|
18
|
+
formatSnippetErrorForJSONL: function() {
|
|
19
|
+
return formatSnippetErrorForJSONL;
|
|
20
|
+
},
|
|
18
21
|
formatUsingNodeStandardLibraryError: function() {
|
|
19
22
|
return formatUsingNodeStandardLibraryError;
|
|
20
23
|
},
|
|
@@ -25,6 +28,13 @@ _export(exports, {
|
|
|
25
28
|
return stripMetroInfo;
|
|
26
29
|
}
|
|
27
30
|
});
|
|
31
|
+
function _metrocore() {
|
|
32
|
+
const data = require("@expo/metro/metro-core");
|
|
33
|
+
_metrocore = function() {
|
|
34
|
+
return data;
|
|
35
|
+
};
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
28
38
|
function _chalk() {
|
|
29
39
|
const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
30
40
|
_chalk = function() {
|
|
@@ -48,7 +58,9 @@ function _util() {
|
|
|
48
58
|
}
|
|
49
59
|
const _TerminalReporter = require("./TerminalReporter");
|
|
50
60
|
const _externals = require("./externals");
|
|
61
|
+
const _ansi = require("../../../utils/ansi");
|
|
51
62
|
const _env = require("../../../utils/env");
|
|
63
|
+
const _jsonl = require("../../../utils/jsonl");
|
|
52
64
|
const _link = require("../../../utils/link");
|
|
53
65
|
const _serverLogLikeMetro = require("../serverLogLikeMetro");
|
|
54
66
|
const _metroErrorInterface = require("./metroErrorInterface");
|
|
@@ -63,36 +75,60 @@ const DARK_BLOCK_CHAR = '\u2593';
|
|
|
63
75
|
const LIGHT_BLOCK_CHAR = '\u2591';
|
|
64
76
|
class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
65
77
|
constructor(projectRoot, terminal){
|
|
66
|
-
super(terminal), this.projectRoot = projectRoot;
|
|
78
|
+
super(terminal), this.projectRoot = projectRoot, this.lastFailedBuildID = undefined;
|
|
67
79
|
}
|
|
68
80
|
_log(event) {
|
|
81
|
+
const jsonlReporter = (0, _jsonl.getJsonlReporter)();
|
|
69
82
|
switch(event.type){
|
|
70
|
-
case '
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return;
|
|
83
|
+
case 'bundle_build_started':
|
|
84
|
+
{
|
|
85
|
+
const details = event.bundleDetails;
|
|
86
|
+
if (details) {
|
|
87
|
+
var _details_customTransformOptions;
|
|
88
|
+
const platform = details.platform || 'unknown';
|
|
89
|
+
const environment = (_details_customTransformOptions = details.customTransformOptions) == null ? void 0 : _details_customTransformOptions.environment;
|
|
90
|
+
jsonlReporter.emitBundlingStarted({
|
|
91
|
+
id: event.buildID,
|
|
92
|
+
platform,
|
|
93
|
+
path: details.entryFile,
|
|
94
|
+
environment
|
|
95
|
+
});
|
|
84
96
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'unstable_server_log':
|
|
100
|
+
{
|
|
101
|
+
var _event_data;
|
|
102
|
+
if (typeof ((_event_data = event.data) == null ? void 0 : _event_data[0]) === 'string') {
|
|
103
|
+
const message = event.data[0];
|
|
104
|
+
if (message.match(/JavaScript logs have moved/)) {
|
|
105
|
+
// Hide this very loud message from upstream React Native in favor of the note in the terminal UI:
|
|
106
|
+
// The "› Press j │ open debugger"
|
|
107
|
+
// logger?.info(
|
|
108
|
+
// '\u001B[1m\u001B[7m💡 JavaScript logs have moved!\u001B[22m They can now be ' +
|
|
109
|
+
// 'viewed in React Native DevTools. Tip: Type \u001B[1mj\u001B[22m in ' +
|
|
110
|
+
// 'the terminal to open (requires Google Chrome or Microsoft Edge).' +
|
|
111
|
+
// '\u001B[27m',
|
|
112
|
+
// );
|
|
91
113
|
return;
|
|
92
114
|
}
|
|
115
|
+
if (!_env.env.EXPO_DEBUG) {
|
|
116
|
+
// In the context of developing an iOS app or website, the MetroInspectorProxy "connection" logs are very confusing.
|
|
117
|
+
// 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.
|
|
118
|
+
// 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.
|
|
119
|
+
if (message.match(/Connection (closed|established|failed|terminated)/i)) {
|
|
120
|
+
// Skip logging.
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
93
124
|
}
|
|
125
|
+
// In JSONL mode, emit server log events and skip normal terminal logging
|
|
126
|
+
if (jsonlReporter.emitServerLog({
|
|
127
|
+
level: event.level,
|
|
128
|
+
value: event.data ?? []
|
|
129
|
+
})) return;
|
|
130
|
+
break;
|
|
94
131
|
}
|
|
95
|
-
break;
|
|
96
132
|
case 'client_log':
|
|
97
133
|
{
|
|
98
134
|
if (this.shouldFilterClientLog(event)) {
|
|
@@ -140,11 +176,21 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
140
176
|
});
|
|
141
177
|
// Using EXPO_DEBUG we can print all stack
|
|
142
178
|
const filtered = usefulStackCount && !_env.env.EXPO_DEBUG ? symbolicated.filter((_, index)=>!fallbackIndices.includes(index)) : symbolicated;
|
|
179
|
+
if (jsonlReporter.emitConsole({
|
|
180
|
+
level,
|
|
181
|
+
source: 'client',
|
|
182
|
+
value: filtered
|
|
183
|
+
})) return;
|
|
143
184
|
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, null, ...filtered);
|
|
144
185
|
})();
|
|
145
186
|
return;
|
|
146
187
|
}
|
|
147
188
|
}
|
|
189
|
+
if (jsonlReporter.emitConsole({
|
|
190
|
+
level,
|
|
191
|
+
source: 'client',
|
|
192
|
+
value: event.data
|
|
193
|
+
})) return;
|
|
148
194
|
// Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.
|
|
149
195
|
(0, _serverLogLikeMetro.logLikeMetro)(this.terminal.log.bind(this.terminal), level, null, ...event.data);
|
|
150
196
|
return;
|
|
@@ -162,6 +208,7 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
162
208
|
* @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`
|
|
163
209
|
*/ _getBundleStatusMessage(progress, phase) {
|
|
164
210
|
var _progress_bundleDetails_customTransformOptions, _progress_bundleDetails;
|
|
211
|
+
const jsonlReporter = (0, _jsonl.getJsonlReporter)();
|
|
165
212
|
const env = getEnvironmentForBuildDetails(progress.bundleDetails);
|
|
166
213
|
const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);
|
|
167
214
|
const inProgress = phase === 'in_progress';
|
|
@@ -176,30 +223,55 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
176
223
|
localPath = _path().default.isAbsolute(inputFile) ? _path().default.relative(this.projectRoot, inputFile) : inputFile;
|
|
177
224
|
}
|
|
178
225
|
if (!inProgress) {
|
|
179
|
-
const status = phase === 'done' ? `Bundled ` : `Bundling failed `;
|
|
180
|
-
const color = phase === 'done' ? _chalk().default.green : _chalk().default.red;
|
|
181
226
|
const startTime = this._bundleTimers.get(progress.bundleDetails.buildID);
|
|
182
|
-
let time =
|
|
227
|
+
let time = undefined;
|
|
183
228
|
if (startTime != null) {
|
|
184
229
|
const elapsed = this._getElapsedTime(startTime);
|
|
185
|
-
const micro = Number(elapsed) / 1000;
|
|
186
230
|
const converted = Number(elapsed) / 1e6;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
231
|
+
time = converted;
|
|
232
|
+
}
|
|
233
|
+
// Emit bundling.done in JSONL mode and return empty string
|
|
234
|
+
if (phase === 'done') {
|
|
235
|
+
if (jsonlReporter.emitBundlingDone({
|
|
236
|
+
id: progress.bundleDetails.buildID,
|
|
237
|
+
duration: time,
|
|
238
|
+
totalModules: progress.totalFileCount
|
|
239
|
+
})) {
|
|
240
|
+
return '';
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Return empty string for failed phase in JSONL mode (error is emitted by _logBundlingError)
|
|
244
|
+
if (phase === 'failed' && jsonlReporter.isEnabled) {
|
|
245
|
+
return '';
|
|
246
|
+
}
|
|
247
|
+
const status = phase === 'done' ? `Bundled ` : `Bundling failed `;
|
|
248
|
+
const color = phase === 'done' ? _chalk().default.green : _chalk().default.red;
|
|
249
|
+
let timeLabel = '';
|
|
250
|
+
// If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.
|
|
251
|
+
if (time !== undefined) {
|
|
252
|
+
if (time <= 0.5) {
|
|
190
253
|
// Format as microseconds to nearest tenth
|
|
191
|
-
|
|
254
|
+
timeLabel = _chalk().default.cyan.bold(`${time.toFixed(1)}ms`);
|
|
192
255
|
} else {
|
|
193
|
-
|
|
256
|
+
timeLabel = _chalk().default.dim(time.toFixed(0) + 'ms');
|
|
194
257
|
}
|
|
195
258
|
}
|
|
196
259
|
// iOS Bundled 150ms
|
|
197
260
|
const plural = progress.totalFileCount === 1 ? '' : 's';
|
|
198
|
-
return color(platform + status) +
|
|
261
|
+
return color(platform + status) + timeLabel + _chalk().default.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`);
|
|
199
262
|
}
|
|
200
263
|
const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);
|
|
201
264
|
const _progress = inProgress ? _chalk().default.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) + _chalk().default.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) + _chalk().default.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) + _chalk().default.dim(`(${progress.transformedFileCount.toString().padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`) : '';
|
|
202
|
-
|
|
265
|
+
if ((0, _jsonl.getJsonlReporter)().emitBundlingProgress({
|
|
266
|
+
id: progress.bundleDetails.buildID ?? 'unknown',
|
|
267
|
+
progress: progress.ratio,
|
|
268
|
+
total: progress.totalFileCount,
|
|
269
|
+
current: progress.transformedFileCount
|
|
270
|
+
})) {
|
|
271
|
+
return '';
|
|
272
|
+
} else {
|
|
273
|
+
return platform + _chalk().default.reset.dim(`${_path().default.dirname(localPath)}${_path().default.sep}`) + _chalk().default.bold(_path().default.basename(localPath)) + ' ' + _progress;
|
|
274
|
+
}
|
|
203
275
|
}
|
|
204
276
|
_logInitializing(port, hasReducedPerformance) {
|
|
205
277
|
// Don't print a giant logo...
|
|
@@ -225,17 +297,63 @@ class MetroTerminalReporter extends _TerminalReporter.TerminalReporter {
|
|
|
225
297
|
].join('\n')));
|
|
226
298
|
}
|
|
227
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Workaround to link build ids to bundling errors.
|
|
302
|
+
* This works because `_logBundleBuildFailed` is called before `_logBundlingError` in synchronous manner.
|
|
303
|
+
* https://github.com/facebook/metro/blob/main/packages/metro/src/Server.js#L939-L945
|
|
304
|
+
*/ _logBundleBuildFailed(buildID) {
|
|
305
|
+
this.lastFailedBuildID = buildID;
|
|
306
|
+
super._logBundleBuildFailed(buildID);
|
|
307
|
+
}
|
|
228
308
|
_logBundlingError(error) {
|
|
309
|
+
// Reset the last failed build id after it's used
|
|
310
|
+
// Bundling errors can also be emitted during hot reload,
|
|
311
|
+
// where bundling id is not available.
|
|
312
|
+
// https://github.com/facebook/metro/blob/main/packages/metro/src/HmrServer.js#L384
|
|
313
|
+
const lastFailedBuildID = this.lastFailedBuildID;
|
|
314
|
+
this.lastFailedBuildID = undefined;
|
|
229
315
|
const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);
|
|
230
316
|
if (moduleResolutionError) {
|
|
317
|
+
if ((0, _jsonl.getJsonlReporter)().emitBundlingError({
|
|
318
|
+
id: lastFailedBuildID,
|
|
319
|
+
value: (0, _ansi.stripAnsi)(moduleResolutionError) ?? '',
|
|
320
|
+
filename: error.filename
|
|
321
|
+
})) return;
|
|
231
322
|
let message = maybeAppendCodeFrame(moduleResolutionError, error.message);
|
|
232
323
|
message += '\n\n' + (0, _metroErrorInterface.nearestImportStack)(error);
|
|
233
324
|
return this.terminal.log(message);
|
|
234
325
|
}
|
|
235
326
|
(0, _metroErrorInterface.attachImportStackToRootMessage)(error);
|
|
327
|
+
// NOTE(@kitten): Metro drops the stack forcefully when it finds a `SyntaxError`. However,
|
|
328
|
+
// this is really unhelpful, since it prevents debugging Babel plugins or reporting bugs
|
|
329
|
+
// in Babel plugins or a transformer entirely
|
|
330
|
+
if (error.snippet == null && error.stack != null && error instanceof SyntaxError) {
|
|
331
|
+
error.message = error.stack;
|
|
332
|
+
delete error.stack;
|
|
333
|
+
}
|
|
334
|
+
if ((0, _jsonl.getJsonlReporter)().emitBundlingError({
|
|
335
|
+
id: lastFailedBuildID,
|
|
336
|
+
value: (0, _ansi.stripAnsi)(formatSnippetErrorForJSONL(error)) ?? '',
|
|
337
|
+
filename: error.filename
|
|
338
|
+
})) return;
|
|
236
339
|
return super._logBundlingError(error);
|
|
237
340
|
}
|
|
238
341
|
}
|
|
342
|
+
function formatSnippetErrorForJSONL(error) {
|
|
343
|
+
if (error instanceof _metrocore().AmbiguousModuleResolutionError) {
|
|
344
|
+
const he = error.hasteError;
|
|
345
|
+
const message = 'ambiguous resolution: module `' + `${error.fromModulePath}\` tries to require \`${he.hasteName}\`, ` + 'but there are several files providing this module. You can delete ' + 'or fix them: \n\n' + Object.keys(he.duplicatesSet).sort().map((dupFilePath)=>` * \`${dupFilePath}\`\n`).join('');
|
|
346
|
+
return message;
|
|
347
|
+
}
|
|
348
|
+
let { message } = error;
|
|
349
|
+
if (error.filename && !message.includes(error.filename)) {
|
|
350
|
+
message += ` [${error.filename}]`;
|
|
351
|
+
}
|
|
352
|
+
if (error.snippet != null) {
|
|
353
|
+
message += '\n' + error.snippet;
|
|
354
|
+
}
|
|
355
|
+
return message;
|
|
356
|
+
}
|
|
239
357
|
function formatUsingNodeStandardLibraryError(projectRoot, error) {
|
|
240
358
|
if (!error.message) {
|
|
241
359
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import type { Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { env } from '../../../utils/env';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n switch (event.type) {\n case 'unstable_server_log':\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n break;\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n if (level === 'warn' || (level as string) === 'error') {\n let hasStack = false;\n const parsed = event.data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') return p;\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(this.projectRoot, level, p);\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...filtered);\n })();\n return;\n }\n }\n\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: string = '';\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const micro = Number(elapsed) / 1000;\n const converted = Number(elapsed) / 1e6;\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (converted <= 0.5) {\n const tenthFractionOfMicro = ((micro * 10) / 1000).toFixed(0);\n // Format as microseconds to nearest tenth\n time = chalk.cyan.bold(`0.${tenthFractionOfMicro}ms`);\n } else {\n time = chalk.dim(converted.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n time +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n _logBundlingError(error: SnippetError): void {\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n if (moduleResolutionError) {\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n message += '\\n\\n' + nearestImportStack(error);\n return this.terminal.log(message);\n }\n\n attachImportStackToRootMessage(error);\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","extractCodeFrame","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","_log","event","type","data","message","match","env","EXPO_DEBUG","shouldFilterClientLog","level","hasStack","parsed","map","msg","includes","stack","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","status","reason","value","isFallback","push","filtered","filter","_","logLikeMetro","log","bind","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","bundleDetails","platform","getPlatformTagForBuildDetails","inProgress","localPath","customTransformOptions","dom","path","sep","replace","inputFile","entryFile","isAbsolute","relative","color","chalk","green","red","_bundleTimers","get","buildID","time","elapsed","micro","Number","converted","tenthFractionOfMicro","toFixed","cyan","bold","dim","plural","totalFileCount","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundlingError","error","moduleResolutionError","maybeAppendCodeFrame","nearestImportStack","attachImportStackToRootMessage","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","formatted","ios","android","web","environment","trim"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/MetroTerminalReporter.ts"],"sourcesContent":["import { AmbiguousModuleResolutionError, type Terminal } from '@expo/metro/metro-core';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { stripVTControlCharacters } from 'util';\n\nimport { logWarning, TerminalReporter } from './TerminalReporter';\nimport {\n BuildPhase,\n BundleDetails,\n BundleProgress,\n SnippetError,\n TerminalReportableEvent,\n} from './TerminalReporter.types';\nimport { NODE_STDLIB_MODULES } from './externals';\nimport { stripAnsi } from '../../../utils/ansi';\nimport { env } from '../../../utils/env';\nimport { getJsonlReporter } from '../../../utils/jsonl';\nimport { learnMore } from '../../../utils/link';\nimport {\n logLikeMetro,\n maybeSymbolicateAndFormatJSErrorStackLogAsync,\n parseErrorStringToObject,\n} from '../serverLogLikeMetro';\nimport { attachImportStackToRootMessage, nearestImportStack } from './metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst MAX_PROGRESS_BAR_CHAR_WIDTH = 16;\nconst DARK_BLOCK_CHAR = '\\u2593';\nconst LIGHT_BLOCK_CHAR = '\\u2591';\n/**\n * Extends the default Metro logger and adds some additional features.\n * Also removes the giant Metro logo from the output.\n */\nexport class MetroTerminalReporter extends TerminalReporter {\n private lastFailedBuildID: string | undefined = undefined;\n\n constructor(\n public projectRoot: string,\n terminal: Terminal\n ) {\n super(terminal);\n }\n\n _log(event: TerminalReportableEvent): void {\n const jsonlReporter = getJsonlReporter();\n\n switch (event.type) {\n case 'bundle_build_started': {\n const details = event.bundleDetails;\n if (details) {\n const platform = details.platform || 'unknown';\n const environment = details.customTransformOptions?.environment;\n jsonlReporter.emitBundlingStarted({\n id: event.buildID!,\n platform,\n path: details.entryFile,\n environment,\n });\n }\n break;\n }\n case 'unstable_server_log': {\n if (typeof event.data?.[0] === 'string') {\n const message = event.data[0];\n if (message.match(/JavaScript logs have moved/)) {\n // Hide this very loud message from upstream React Native in favor of the note in the terminal UI:\n // The \"› Press j │ open debugger\"\n\n // logger?.info(\n // '\\u001B[1m\\u001B[7m💡 JavaScript logs have moved!\\u001B[22m They can now be ' +\n // 'viewed in React Native DevTools. Tip: Type \\u001B[1mj\\u001B[22m in ' +\n // 'the terminal to open (requires Google Chrome or Microsoft Edge).' +\n // '\\u001B[27m',\n // );\n return;\n }\n\n if (!env.EXPO_DEBUG) {\n // In the context of developing an iOS app or website, the MetroInspectorProxy \"connection\" logs are very confusing.\n // Here we'll hide them behind EXPO_DEBUG or DEBUG=expo:*. In the future we can reformat them to clearly indicate that the \"Connection\" is regarding the debugger.\n // These logs are also confusing because they can say \"connection established\" even when the debugger is not in a usable state. Really they belong in a UI or behind some sort of debug logging.\n if (message.match(/Connection (closed|established|failed|terminated)/i)) {\n // Skip logging.\n return;\n }\n }\n }\n\n // In JSONL mode, emit server log events and skip normal terminal logging\n if (\n jsonlReporter.emitServerLog({\n level: event.level,\n value: event.data ?? [],\n })\n )\n return;\n break;\n }\n case 'client_log': {\n if (this.shouldFilterClientLog(event)) {\n return;\n }\n const { level } = event;\n\n if (!level) {\n break;\n }\n\n if (level === 'warn' || (level as string) === 'error') {\n let hasStack = false;\n const parsed = event.data.map((msg) => {\n // Quick check to see if an unsymbolicated stack is being logged.\n if (msg.includes('.bundle//&platform=')) {\n const stack = parseErrorStringToObject(msg);\n if (stack) {\n hasStack = true;\n }\n return stack;\n }\n return msg;\n });\n\n if (hasStack) {\n (async () => {\n const symbolicating = parsed.map((p) => {\n if (typeof p === 'string') return p;\n return maybeSymbolicateAndFormatJSErrorStackLogAsync(this.projectRoot, level, p);\n });\n\n let usefulStackCount = 0;\n const fallbackIndices: number[] = [];\n const symbolicated = (await Promise.allSettled(symbolicating)).map((s, index) => {\n if (s.status === 'rejected') {\n debug('Error formatting stack', parsed[index], s.reason);\n return parsed[index];\n } else if (typeof s.value === 'string') {\n return s.value;\n } else {\n if (!s.value.isFallback) {\n usefulStackCount++;\n } else {\n fallbackIndices.push(index);\n }\n return s.value.stack;\n }\n });\n\n // Using EXPO_DEBUG we can print all stack\n const filtered =\n usefulStackCount && !env.EXPO_DEBUG\n ? symbolicated.filter((_, index) => !fallbackIndices.includes(index))\n : symbolicated;\n if (\n jsonlReporter.emitConsole({\n level,\n source: 'client',\n value: filtered,\n })\n )\n return;\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...filtered);\n })();\n return;\n }\n }\n\n if (\n jsonlReporter.emitConsole({\n level,\n source: 'client',\n value: event.data,\n })\n )\n return;\n // Overwrite the Metro terminal logging so we can improve the warnings, symbolicate stacks, and inject extra info.\n logLikeMetro(this.terminal.log.bind(this.terminal), level, null, ...event.data);\n return;\n }\n }\n return super._log(event);\n }\n\n // Used for testing\n _getElapsedTime(startTime: bigint): bigint {\n return process.hrtime.bigint() - startTime;\n }\n /**\n * Extends the bundle progress to include the current platform that we're bundling.\n *\n * @returns `iOS path/to/bundle.js ▓▓▓▓▓░░░░░░░░░░░ 36.6% (4790/7922)`\n */\n _getBundleStatusMessage(progress: BundleProgress, phase: BuildPhase): string {\n const jsonlReporter = getJsonlReporter();\n\n const env = getEnvironmentForBuildDetails(progress.bundleDetails);\n const platform = env || getPlatformTagForBuildDetails(progress.bundleDetails);\n const inProgress = phase === 'in_progress';\n\n let localPath: string;\n\n if (\n typeof progress.bundleDetails?.customTransformOptions?.dom === 'string' &&\n progress.bundleDetails.customTransformOptions.dom.includes(path.sep)\n ) {\n // Because we use a generated entry file for DOM components, we need to adjust the logging path so it\n // shows a unique path for each component.\n // Here, we take the relative import path and remove all the starting slashes.\n localPath = progress.bundleDetails.customTransformOptions.dom.replace(/^(\\.?\\.[\\\\/])+/, '');\n } else {\n const inputFile = progress.bundleDetails.entryFile;\n\n localPath = path.isAbsolute(inputFile)\n ? path.relative(this.projectRoot, inputFile)\n : inputFile;\n }\n\n if (!inProgress) {\n const startTime = this._bundleTimers.get(progress.bundleDetails.buildID!);\n\n let time: number | undefined = undefined;\n\n if (startTime != null) {\n const elapsed: bigint = this._getElapsedTime(startTime);\n const converted = Number(elapsed) / 1e6;\n time = converted;\n }\n\n // Emit bundling.done in JSONL mode and return empty string\n if (phase === 'done') {\n if (\n jsonlReporter.emitBundlingDone({\n id: progress.bundleDetails.buildID!,\n duration: time,\n totalModules: progress.totalFileCount,\n })\n ) {\n return '';\n }\n }\n\n // Return empty string for failed phase in JSONL mode (error is emitted by _logBundlingError)\n if (phase === 'failed' && jsonlReporter.isEnabled) {\n return '';\n }\n\n const status = phase === 'done' ? `Bundled ` : `Bundling failed `;\n const color = phase === 'done' ? chalk.green : chalk.red;\n\n let timeLabel: string = '';\n // If the milliseconds are < 0.5 then it will display as 0, so we display in microseconds.\n if (time !== undefined) {\n if (time <= 0.5) {\n // Format as microseconds to nearest tenth\n timeLabel = chalk.cyan.bold(`${time.toFixed(1)}ms`);\n } else {\n timeLabel = chalk.dim(time.toFixed(0) + 'ms');\n }\n }\n\n // iOS Bundled 150ms\n const plural = progress.totalFileCount === 1 ? '' : 's';\n return (\n color(platform + status) +\n timeLabel +\n chalk.reset.dim(` ${localPath} (${progress.totalFileCount} module${plural})`)\n );\n }\n\n const filledBar = Math.floor(progress.ratio * MAX_PROGRESS_BAR_CHAR_WIDTH);\n\n const _progress = inProgress\n ? chalk.green.bgGreen(DARK_BLOCK_CHAR.repeat(filledBar)) +\n chalk.bgWhite.white(LIGHT_BLOCK_CHAR.repeat(MAX_PROGRESS_BAR_CHAR_WIDTH - filledBar)) +\n chalk.bold(` ${(100 * progress.ratio).toFixed(1).padStart(4)}% `) +\n chalk.dim(\n `(${progress.transformedFileCount\n .toString()\n .padStart(progress.totalFileCount.toString().length)}/${progress.totalFileCount})`\n )\n : '';\n\n if (\n getJsonlReporter().emitBundlingProgress({\n id: progress.bundleDetails.buildID ?? 'unknown',\n progress: progress.ratio,\n total: progress.totalFileCount,\n current: progress.transformedFileCount,\n })\n ) {\n return '';\n } else {\n return (\n platform +\n chalk.reset.dim(`${path.dirname(localPath)}${path.sep}`) +\n chalk.bold(path.basename(localPath)) +\n ' ' +\n _progress\n );\n }\n }\n\n _logInitializing(port: number, hasReducedPerformance: boolean): void {\n // Don't print a giant logo...\n this.terminal.log(chalk.dim('Starting Metro Bundler'));\n }\n\n shouldFilterClientLog(event: { type: 'client_log'; data: unknown[] }): boolean {\n return isAppRegistryStartupMessage(event.data);\n }\n\n shouldFilterBundleEvent(event: TerminalReportableEvent): boolean {\n return 'bundleDetails' in event && event.bundleDetails?.bundleType === 'map';\n }\n\n /** Print the cache clear message. */\n transformCacheReset(): void {\n logWarning(\n this.terminal,\n chalk`Bundler cache is empty, rebuilding {dim (this may take a minute)}`\n );\n }\n\n /** One of the first logs that will be printed */\n dependencyGraphLoading(hasReducedPerformance: boolean): void {\n // this.terminal.log('Dependency graph is loading...');\n if (hasReducedPerformance) {\n // Extends https://github.com/facebook/metro/blob/347b1d7ed87995d7951aaa9fd597c04b06013dac/packages/metro/src/lib/TerminalReporter.js#L283-L290\n this.terminal.log(\n chalk.red(\n [\n 'Metro is operating with reduced performance.',\n 'Fix the problem above and restart Metro.',\n ].join('\\n')\n )\n );\n }\n }\n\n /**\n * Workaround to link build ids to bundling errors.\n * This works because `_logBundleBuildFailed` is called before `_logBundlingError` in synchronous manner.\n * https://github.com/facebook/metro/blob/main/packages/metro/src/Server.js#L939-L945\n */\n _logBundleBuildFailed(buildID: string): void {\n this.lastFailedBuildID = buildID;\n super._logBundleBuildFailed(buildID);\n }\n\n _logBundlingError(error: SnippetError): void {\n // Reset the last failed build id after it's used\n // Bundling errors can also be emitted during hot reload,\n // where bundling id is not available.\n // https://github.com/facebook/metro/blob/main/packages/metro/src/HmrServer.js#L384\n const lastFailedBuildID = this.lastFailedBuildID;\n this.lastFailedBuildID = undefined;\n\n const moduleResolutionError = formatUsingNodeStandardLibraryError(this.projectRoot, error);\n if (moduleResolutionError) {\n if (\n getJsonlReporter().emitBundlingError({\n id: lastFailedBuildID,\n value: stripAnsi(moduleResolutionError) ?? '',\n filename: error.filename,\n })\n )\n return;\n\n let message = maybeAppendCodeFrame(moduleResolutionError, error.message);\n message += '\\n\\n' + nearestImportStack(error);\n return this.terminal.log(message);\n }\n\n attachImportStackToRootMessage(error);\n\n // NOTE(@kitten): Metro drops the stack forcefully when it finds a `SyntaxError`. However,\n // this is really unhelpful, since it prevents debugging Babel plugins or reporting bugs\n // in Babel plugins or a transformer entirely\n if (error.snippet == null && error.stack != null && error instanceof SyntaxError) {\n error.message = error.stack;\n delete error.stack;\n }\n\n if (\n getJsonlReporter().emitBundlingError({\n id: lastFailedBuildID,\n value: stripAnsi(formatSnippetErrorForJSONL(error)) ?? '',\n filename: error.filename,\n })\n )\n return;\n\n return super._logBundlingError(error);\n }\n}\n\n/**\n * Based on Metro's default `_logBundlingError` implementation.\n * https://github.com/facebook/metro/blob/main/packages/metro/src/lib/TerminalReporter.js#L308\n */\nexport function formatSnippetErrorForJSONL(error: SnippetError): string {\n if (error instanceof AmbiguousModuleResolutionError) {\n const he = error.hasteError;\n const message =\n 'ambiguous resolution: module `' +\n `${error.fromModulePath}\\` tries to require \\`${he.hasteName}\\`, ` +\n 'but there are several files providing this module. You can delete ' +\n 'or fix them: \\n\\n' +\n Object.keys(he.duplicatesSet)\n .sort()\n .map((dupFilePath) => ` * \\`${dupFilePath}\\`\\n`)\n .join('');\n return message;\n }\n\n let { message } = error;\n\n if (error.filename && !message.includes(error.filename)) {\n message += ` [${error.filename}]`;\n }\n\n if (error.snippet != null) {\n message += '\\n' + error.snippet;\n }\n\n return message;\n}\n\n/**\n * Formats an error where the user is attempting to import a module from the Node.js standard library.\n * Exposed for testing.\n *\n * @param error\n * @returns error message or null if not a module resolution error\n */\nexport function formatUsingNodeStandardLibraryError(\n projectRoot: string,\n error: SnippetError\n): string | null {\n if (!error.message) {\n return null;\n }\n const { targetModuleName, originModulePath } = error;\n if (!targetModuleName || !originModulePath) {\n return null;\n }\n const relativePath = path.relative(projectRoot, originModulePath);\n\n const DOCS_PAGE_URL =\n 'https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries';\n\n if (isNodeStdLibraryModule(targetModuleName)) {\n if (originModulePath.includes('node_modules')) {\n return [\n `The package at \"${chalk.bold(\n relativePath\n )}\" attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n } else {\n return [\n `You attempted to import the Node standard library module \"${chalk.bold(\n targetModuleName\n )}\" from \"${chalk.bold(relativePath)}\".`,\n `It failed because the native React runtime does not include the Node standard library.`,\n learnMore(DOCS_PAGE_URL),\n ].join('\\n');\n }\n }\n return `Unable to resolve \"${targetModuleName}\" from \"${relativePath}\"`;\n}\n\nexport function isNodeStdLibraryModule(moduleName: string): boolean {\n return /^node:/.test(moduleName) || NODE_STDLIB_MODULES.includes(moduleName);\n}\n\n/** If the code frame can be found then append it to the existing message. */\nfunction maybeAppendCodeFrame(message: string, rawMessage: string): string {\n const codeFrame = extractCodeFrame(stripMetroInfo(rawMessage));\n if (codeFrame) {\n message += '\\n' + codeFrame;\n }\n return message;\n}\n\n/** Extract fist code frame presented in the error message */\nexport function extractCodeFrame(errorMessage: string): string {\n const codeFrameLine = /^(?:\\s*(?:>?\\s*\\d+\\s*\\||\\s*\\|).*\\n?)+/;\n let wasPreviousLineCodeFrame: boolean | null = null;\n return errorMessage\n .split('\\n')\n .filter((line) => {\n if (wasPreviousLineCodeFrame === false) return false;\n const keep = codeFrameLine.test(stripVTControlCharacters(line));\n if (keep && wasPreviousLineCodeFrame === null) wasPreviousLineCodeFrame = true;\n else if (!keep && wasPreviousLineCodeFrame) wasPreviousLineCodeFrame = false;\n return keep;\n })\n .join('\\n');\n}\n\n/**\n * Remove the Metro cache clearing steps if they exist.\n * In future versions we won't need this.\n * Returns the remaining code frame logs.\n */\nexport function stripMetroInfo(errorMessage: string): string {\n // Newer versions of Metro don't include the list.\n if (!errorMessage.includes('4. Remove the cache')) {\n return errorMessage;\n }\n const lines = errorMessage.split('\\n');\n const index = lines.findIndex((line) => line.includes('4. Remove the cache'));\n if (index === -1) {\n return errorMessage;\n }\n return lines.slice(index + 1).join('\\n');\n}\n\n/** @returns if the message matches the initial startup log */\nfunction isAppRegistryStartupMessage(body: any[]): boolean {\n return (\n body.length === 1 &&\n (/^Running application \"main\" with appParams:/.test(body[0]) ||\n /^Running \"main\" with \\{/.test(body[0]))\n );\n}\n\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getPlatformTagForBuildDetails(bundleDetails?: BundleDetails | null): string {\n const platform = bundleDetails?.platform ?? null;\n if (platform) {\n const formatted = { ios: 'iOS', android: 'Android', web: 'Web' }[platform] || platform;\n return `${chalk.bold(formatted)} `;\n }\n\n return '';\n}\n/** @returns platform specific tag for a `BundleDetails` object */\nfunction getEnvironmentForBuildDetails(bundleDetails?: BundleDetails | null): string {\n // Expo CLI will pass `customTransformOptions.environment = 'node'` when bundling for the server.\n const env = bundleDetails?.customTransformOptions?.environment ?? null;\n if (env === 'node') {\n return chalk.bold('λ') + ' ';\n } else if (env === 'react-server') {\n return chalk.bold(`RSC(${getPlatformTagForBuildDetails(bundleDetails).trim()})`) + ' ';\n }\n\n if (\n bundleDetails?.customTransformOptions?.dom &&\n typeof bundleDetails?.customTransformOptions?.dom === 'string'\n ) {\n return chalk.bold(`DOM`) + ' ';\n }\n\n return '';\n}\n"],"names":["MetroTerminalReporter","extractCodeFrame","formatSnippetErrorForJSONL","formatUsingNodeStandardLibraryError","isNodeStdLibraryModule","stripMetroInfo","debug","require","MAX_PROGRESS_BAR_CHAR_WIDTH","DARK_BLOCK_CHAR","LIGHT_BLOCK_CHAR","TerminalReporter","constructor","projectRoot","terminal","lastFailedBuildID","undefined","_log","event","jsonlReporter","getJsonlReporter","type","details","bundleDetails","platform","environment","customTransformOptions","emitBundlingStarted","id","buildID","path","entryFile","data","message","match","env","EXPO_DEBUG","emitServerLog","level","value","shouldFilterClientLog","hasStack","parsed","map","msg","includes","stack","parseErrorStringToObject","symbolicating","p","maybeSymbolicateAndFormatJSErrorStackLogAsync","usefulStackCount","fallbackIndices","symbolicated","Promise","allSettled","s","index","status","reason","isFallback","push","filtered","filter","_","emitConsole","source","logLikeMetro","log","bind","_getElapsedTime","startTime","process","hrtime","bigint","_getBundleStatusMessage","progress","phase","getEnvironmentForBuildDetails","getPlatformTagForBuildDetails","inProgress","localPath","dom","sep","replace","inputFile","isAbsolute","relative","_bundleTimers","get","time","elapsed","converted","Number","emitBundlingDone","duration","totalModules","totalFileCount","isEnabled","color","chalk","green","red","timeLabel","cyan","bold","toFixed","dim","plural","reset","filledBar","Math","floor","ratio","_progress","bgGreen","repeat","bgWhite","white","padStart","transformedFileCount","toString","length","emitBundlingProgress","total","current","dirname","basename","_logInitializing","port","hasReducedPerformance","isAppRegistryStartupMessage","shouldFilterBundleEvent","bundleType","transformCacheReset","logWarning","dependencyGraphLoading","join","_logBundleBuildFailed","_logBundlingError","error","moduleResolutionError","emitBundlingError","stripAnsi","filename","maybeAppendCodeFrame","nearestImportStack","attachImportStackToRootMessage","snippet","SyntaxError","AmbiguousModuleResolutionError","he","hasteError","fromModulePath","hasteName","Object","keys","duplicatesSet","sort","dupFilePath","targetModuleName","originModulePath","relativePath","DOCS_PAGE_URL","learnMore","moduleName","test","NODE_STDLIB_MODULES","rawMessage","codeFrame","errorMessage","codeFrameLine","wasPreviousLineCodeFrame","split","line","keep","stripVTControlCharacters","lines","findIndex","slice","body","formatted","ios","android","web","trim"],"mappings":"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"}
|
|
@@ -106,9 +106,7 @@ function createAutolinkingModuleResolver(input, { getStrictResolver }) {
|
|
|
106
106
|
// We instead resolve as if it was a dependency from within the module (self-require/import)
|
|
107
107
|
const context = {
|
|
108
108
|
...immutableContext,
|
|
109
|
-
nodeModulesPaths: [
|
|
110
|
-
resolvedModulePath
|
|
111
|
-
],
|
|
109
|
+
nodeModulesPaths: [],
|
|
112
110
|
originModulePath: resolvedModulePath
|
|
113
111
|
};
|
|
114
112
|
const res = getStrictResolver(context, platform)(moduleName);
|
|
@@ -1 +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', 'web'] 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: [
|
|
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', 'web'] 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: [],\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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"}
|
|
@@ -125,9 +125,7 @@ function createFallbackModuleResolver({ projectRoot, originModuleNames, getStric
|
|
|
125
125
|
// We instead resolve as if it was depended on by the `originModulePath` (the module named in `originModuleNames`)
|
|
126
126
|
const context = {
|
|
127
127
|
...immutableContext,
|
|
128
|
-
nodeModulesPaths: [
|
|
129
|
-
moduleDescription.originModulePath
|
|
130
|
-
],
|
|
128
|
+
nodeModulesPaths: [],
|
|
131
129
|
// NOTE(@kitten): We need to add a fake filename here. Metro performs a `path.dirname` on this path
|
|
132
130
|
// and then searches `${path.dirname(originModulePath)}/node_modules`. If we don't add it, we miss
|
|
133
131
|
// fallback resolution for packages that failed to hoist
|
|
@@ -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, 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 // NOTE(@kitten): We need to add a fake filename here. Metro performs a `path.dirname` on this path\n // and then searches `${path.dirname(originModulePath)}/node_modules`. If we don't add it, we miss\n // fallback resolution for packages that failed to hoist\n originModulePath: path.join(moduleDescription.originModulePath, 'index.js'),\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;;;;;+BA4H/BA;;;eAAAA;;;;gEAzHC;;;;;;;;;;;AAKjB;;;;;;;;;CASC,GACD,MAAMC,yBAA2D;IAC/D,gBAAgB;IAChB,wBAAwB;IACxB,gBAAgB;IAChBC,QAAQ;AACV;AAsBA,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;QAC9B,oCAAoC;QACpCC,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;oBACtD,mGAAmG;oBACnG,kGAAkG;oBAClG,wDAAwD;oBACxDA,kBAAkBnB,eAAI,CAACR,IAAI,CAAC0C,kBAAkBf,gBAAgB,EAAE;gBAClE;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: [],\n // NOTE(@kitten): We need to add a fake filename here. Metro performs a `path.dirname` on this path\n // and then searches `${path.dirname(originModulePath)}/node_modules`. If we don't add it, we miss\n // fallback resolution for packages that failed to hoist\n originModulePath: path.join(moduleDescription.originModulePath, 'index.js'),\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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"}
|
|
@@ -343,11 +343,10 @@ function createServerComponentsMiddleware(projectRoot, { rscPath, instanceMetroO
|
|
|
343
343
|
let ensurePromise = null;
|
|
344
344
|
async function ensureSSRReady() {
|
|
345
345
|
// TODO: Extract CSS Modules / Assets from the bundler process
|
|
346
|
-
|
|
346
|
+
await ssrLoadModule(null, {
|
|
347
347
|
environment: 'react-server',
|
|
348
348
|
platform: 'web'
|
|
349
349
|
});
|
|
350
|
-
return runtime;
|
|
351
350
|
}
|
|
352
351
|
const ensureMemo = ()=>{
|
|
353
352
|
ensurePromise ??= ensureSSRReady();
|