metro 0.80.8 → 0.80.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/package.json +18 -18
  2. package/src/DeltaBundler/Serializers/baseJSBundle.js +1 -0
  3. package/src/DeltaBundler/Serializers/baseJSBundle.js.flow +1 -0
  4. package/src/DeltaBundler/Serializers/getRamBundleInfo.js +1 -0
  5. package/src/DeltaBundler/Serializers/getRamBundleInfo.js.flow +1 -0
  6. package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js +1 -1
  7. package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js.flow +2 -1
  8. package/src/DeltaBundler/Serializers/sourceMapGenerator.js +1 -0
  9. package/src/DeltaBundler/Serializers/sourceMapGenerator.js.flow +3 -0
  10. package/src/DeltaBundler/Serializers/sourceMapString.js +14 -2
  11. package/src/DeltaBundler/Serializers/sourceMapString.js.flow +18 -2
  12. package/src/DeltaBundler/Transformer.js +17 -3
  13. package/src/DeltaBundler/Transformer.js.flow +20 -4
  14. package/src/DeltaBundler/types.flow.js.flow +2 -1
  15. package/src/ModuleGraph/worker/JsFileWrapping.js +3 -2
  16. package/src/ModuleGraph/worker/JsFileWrapping.js.flow +4 -1
  17. package/src/ModuleGraph/worker/collectDependencies.js +54 -4
  18. package/src/ModuleGraph/worker/collectDependencies.js.flow +69 -4
  19. package/src/Server.js +113 -10
  20. package/src/Server.js.flow +131 -10
  21. package/src/cli/parseKeyValueParamArray.js +4 -5
  22. package/src/cli/parseKeyValueParamArray.js.flow +5 -3
  23. package/src/index.flow.js +7 -0
  24. package/src/index.flow.js.flow +8 -0
  25. package/src/integration_tests/basic_bundle/excluded_from_file_map.js +8 -0
  26. package/src/integration_tests/basic_bundle/excluded_from_file_map.js.flow +11 -0
  27. package/src/integration_tests/basic_bundle/import-export/export-7.js +5 -0
  28. package/src/integration_tests/basic_bundle/import-export/export-7.js.flow +15 -0
  29. package/src/integration_tests/basic_bundle/import-export/export-8.js +10 -0
  30. package/src/integration_tests/basic_bundle/import-export/export-8.js.flow +15 -0
  31. package/src/integration_tests/basic_bundle/import-export/index.js +9 -1
  32. package/src/integration_tests/basic_bundle/import-export/index.js.flow +9 -0
  33. package/src/integration_tests/basic_bundle/import-export/utils.js +1 -0
  34. package/src/integration_tests/basic_bundle/import-export/utils.js.flow +14 -0
  35. package/src/integration_tests/basic_bundle/not_a_source_file.xyz +1 -0
  36. package/src/integration_tests/metro.config.js +1 -0
  37. package/src/lib/BatchProcessor.js +3 -0
  38. package/src/lib/BatchProcessor.js.flow +4 -0
  39. package/src/lib/JsonReporter.js +30 -3
  40. package/src/lib/JsonReporter.js.flow +50 -5
  41. package/src/lib/TerminalReporter.js +4 -24
  42. package/src/lib/TerminalReporter.js.flow +13 -32
  43. package/src/lib/getAppendScripts.js +4 -1
  44. package/src/lib/getAppendScripts.js.flow +5 -1
  45. package/src/lib/logToConsole.js.flow +1 -0
  46. package/src/lib/parseOptionsFromUrl.js +4 -0
  47. package/src/lib/parseOptionsFromUrl.js.flow +4 -0
  48. package/src/lib/reporting.d.ts +9 -5
  49. package/src/lib/reporting.js.flow +9 -5
  50. package/src/lib/splitBundleOptions.js +1 -0
  51. package/src/lib/splitBundleOptions.js.flow +1 -0
  52. package/src/node-haste/DependencyGraph/ModuleResolution.js +10 -9
  53. package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +16 -14
  54. package/src/node-haste/DependencyGraph.js +8 -4
  55. package/src/node-haste/DependencyGraph.js.flow +12 -4
  56. package/src/node-haste/Module.js +1 -1
  57. package/src/node-haste/Module.js.flow +1 -1
  58. package/src/node-haste/ModuleCache.js +28 -14
  59. package/src/node-haste/ModuleCache.js.flow +43 -18
  60. package/src/node-haste/lib/AssetPaths.js +1 -1
  61. package/src/node-haste/lib/AssetPaths.js.flow +1 -1
  62. package/src/shared/output/bundle.flow.js +2 -2
  63. package/src/shared/output/bundle.flow.js.flow +2 -2
  64. package/src/shared/types.flow.js +10 -0
  65. package/src/shared/types.flow.js.flow +9 -0
@@ -62,5 +62,8 @@ class BatchProcessor {
62
62
  this._processQueueOnceReady();
63
63
  });
64
64
  }
65
+ getQueueLength() {
66
+ return this._queue.length;
67
+ }
65
68
  }
66
69
  module.exports = BatchProcessor;
@@ -125,6 +125,10 @@ class BatchProcessor<TItem, TResult> {
125
125
  },
126
126
  );
127
127
  }
128
+
129
+ getQueueLength(): number {
130
+ return this._queue.length;
131
+ }
128
132
  }
129
133
 
130
134
  module.exports = BatchProcessor;
@@ -5,13 +5,40 @@ class JsonReporter {
5
5
  this._stream = stream;
6
6
  }
7
7
  update(event) {
8
- if (Object.prototype.toString.call(event.error) === "[object Error]") {
8
+ if (event.error instanceof Error) {
9
+ const { message, stack } = event.error;
9
10
  event = Object.assign(event, {
10
- message: event.error.message,
11
- stack: event.error.stack,
11
+ error: serializeError(event.error),
12
+ message,
13
+ stack,
12
14
  });
13
15
  }
14
16
  this._stream.write(JSON.stringify(event) + "\n");
15
17
  }
16
18
  }
19
+ function serializeError(e, seen = new Set()) {
20
+ if (seen.has(e)) {
21
+ return {
22
+ message: "[circular]: " + e.message,
23
+ stack: e.stack,
24
+ };
25
+ }
26
+ seen.add(e);
27
+ const { message, stack, cause } = e;
28
+ const serialized = {
29
+ message,
30
+ stack,
31
+ };
32
+ if (e instanceof AggregateError) {
33
+ serialized.errors = [...e.errors]
34
+ .map((innerError) =>
35
+ innerError instanceof Error ? serializeError(innerError, seen) : null
36
+ )
37
+ .filter(Boolean);
38
+ }
39
+ if (cause instanceof Error) {
40
+ serialized.cause = serializeError(cause, seen);
41
+ }
42
+ return serialized;
43
+ }
17
44
  module.exports = JsonReporter;
@@ -13,6 +13,25 @@
13
13
 
14
14
  import type {Writable} from 'stream';
15
15
 
16
+ export type SerializedError = {
17
+ message: string,
18
+ stack: string,
19
+ errors?: $ReadOnlyArray<SerializedError>,
20
+ cause?: SerializedError,
21
+ ...
22
+ };
23
+
24
+ export type SerializedEvent<TEvent: {[string]: any, ...}> = TEvent extends {
25
+ error: Error,
26
+ ...
27
+ }
28
+ ? {
29
+ ...Omit<TEvent, 'error'>,
30
+ error: SerializedError,
31
+ ...
32
+ }
33
+ : TEvent;
34
+
16
35
  class JsonReporter<TEvent: {[string]: any, ...}> {
17
36
  _stream: Writable;
18
37
 
@@ -25,16 +44,42 @@ class JsonReporter<TEvent: {[string]: any, ...}> {
25
44
  * (Perhaps we should switch in favor of plain object?)
26
45
  */
27
46
  update(event: TEvent): void {
28
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
29
- if (Object.prototype.toString.call(event.error) === '[object Error]') {
47
+ if (event.error instanceof Error) {
48
+ const {message, stack} = event.error;
30
49
  event = Object.assign(event, {
31
- message: event.error.message,
32
- stack: event.error.stack,
50
+ error: serializeError(event.error),
51
+ // TODO: Preexisting issue - this writes message, stack, etc. as
52
+ // top-level siblings of event.error (which was serialized to {}), whereas it was presumably
53
+ // intended to nest them _under_ error. Fix this in a breaking change.
54
+ message,
55
+ stack,
33
56
  });
34
57
  }
35
-
36
58
  this._stream.write(JSON.stringify(event) + '\n');
37
59
  }
38
60
  }
39
61
 
62
+ function serializeError(
63
+ e: Error,
64
+ seen: Set<Error> = new Set(),
65
+ ): SerializedError {
66
+ if (seen.has(e)) {
67
+ return {message: '[circular]: ' + e.message, stack: e.stack};
68
+ }
69
+ seen.add(e);
70
+ const {message, stack, cause} = e;
71
+ const serialized: SerializedError = {message, stack};
72
+ if (e instanceof AggregateError) {
73
+ serialized.errors = [...e.errors]
74
+ .map(innerError =>
75
+ innerError instanceof Error ? serializeError(innerError, seen) : null,
76
+ )
77
+ .filter(Boolean);
78
+ }
79
+ if (cause instanceof Error) {
80
+ serialized.cause = serializeError(cause, seen);
81
+ }
82
+ return serialized;
83
+ }
84
+
40
85
  module.exports = JsonReporter;
@@ -6,8 +6,6 @@ const chalk = require("chalk");
6
6
  const throttle = require("lodash.throttle");
7
7
  const { AmbiguousModuleResolutionError } = require("metro-core");
8
8
  const path = require("path");
9
- const GLOBAL_CACHE_DISABLED_MESSAGE_FORMAT =
10
- "The global cache is now disabled because %s";
11
9
  const DARK_BLOCK_CHAR = "\u2593";
12
10
  const LIGHT_BLOCK_CHAR = "\u2591";
13
11
  const MAX_PROGRESS_BAR_CHAR_WIDTH = 16;
@@ -61,25 +59,6 @@ class TerminalReporter {
61
59
  "\n"
62
60
  );
63
61
  }
64
- _logCacheDisabled(reason) {
65
- const format = GLOBAL_CACHE_DISABLED_MESSAGE_FORMAT;
66
- switch (reason) {
67
- case "too_many_errors":
68
- reporting.logWarning(
69
- this.terminal,
70
- format,
71
- "it has been failing too many times."
72
- );
73
- break;
74
- case "too_many_misses":
75
- reporting.logWarning(
76
- this.terminal,
77
- format,
78
- "it has been missing too many consecutive keys."
79
- );
80
- break;
81
- }
82
- }
83
62
  _logBundleBuildDone(buildID) {
84
63
  const progress = this._activeBundles.get(buildID);
85
64
  if (progress != null) {
@@ -163,9 +142,6 @@ class TerminalReporter {
163
142
  case "bundling_error":
164
143
  this._logBundlingError(event.error);
165
144
  break;
166
- case "global_cache_disabled":
167
- this._logCacheDisabled(event.reason);
168
- break;
169
145
  case "resolver_warning":
170
146
  this._logWarning(event.message);
171
147
  break;
@@ -281,6 +257,9 @@ class TerminalReporter {
281
257
  case "bundle_transform_progressed_throttled":
282
258
  this._updateBundleProgress(event);
283
259
  break;
260
+ case "unstable_set_interaction_status":
261
+ this._interactionStatus = event.status;
262
+ break;
284
263
  }
285
264
  }
286
265
  _getStatusMessage() {
@@ -288,6 +267,7 @@ class TerminalReporter {
288
267
  .map(([_, progress]) =>
289
268
  this._getBundleStatusMessage(progress, "in_progress")
290
269
  )
270
+ .concat([this._interactionStatus])
291
271
  .filter((str) => str != null)
292
272
  .join("\n");
293
273
  }
@@ -11,11 +11,7 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- import type {
15
- BundleDetails,
16
- GlobalCacheDisabledReason,
17
- ReportableEvent,
18
- } from './reporting';
14
+ import type {BundleDetails, ReportableEvent} from './reporting';
19
15
  import type {Terminal} from 'metro-core';
20
16
  import type {HealthCheckResult, WatcherStatus} from 'metro-file-map';
21
17
 
@@ -43,6 +39,11 @@ export type TerminalReportableEvent =
43
39
  transformedFileCount: number,
44
40
  totalFileCount: number,
45
41
  ...
42
+ }
43
+ | {
44
+ type: 'unstable_set_interaction_status',
45
+ status: ?string,
46
+ ...
46
47
  };
47
48
 
48
49
  type BuildPhase = 'in_progress' | 'done' | 'failed';
@@ -53,9 +54,6 @@ type SnippetError = ErrnoError &
53
54
  snippet?: string,
54
55
  };
55
56
 
56
- const GLOBAL_CACHE_DISABLED_MESSAGE_FORMAT =
57
- 'The global cache is now disabled because %s';
58
-
59
57
  const DARK_BLOCK_CHAR = '\u2593';
60
58
  const LIGHT_BLOCK_CHAR = '\u2591';
61
59
  const MAX_PROGRESS_BAR_CHAR_WIDTH = 16;
@@ -72,6 +70,8 @@ class TerminalReporter {
72
70
  */
73
71
  _activeBundles: Map<string, BundleProgress>;
74
72
 
73
+ _interactionStatus: ?string;
74
+
75
75
  _scheduleUpdateBundleProgress: {
76
76
  (data: {
77
77
  buildID: string,
@@ -141,26 +141,6 @@ class TerminalReporter {
141
141
  );
142
142
  }
143
143
 
144
- _logCacheDisabled(reason: GlobalCacheDisabledReason): void {
145
- const format = GLOBAL_CACHE_DISABLED_MESSAGE_FORMAT;
146
- switch (reason) {
147
- case 'too_many_errors':
148
- reporting.logWarning(
149
- this.terminal,
150
- format,
151
- 'it has been failing too many times.',
152
- );
153
- break;
154
- case 'too_many_misses':
155
- reporting.logWarning(
156
- this.terminal,
157
- format,
158
- 'it has been missing too many consecutive keys.',
159
- );
160
- break;
161
- }
162
- }
163
-
164
144
  _logBundleBuildDone(buildID: string): void {
165
145
  const progress = this._activeBundles.get(buildID);
166
146
  if (progress != null) {
@@ -253,9 +233,6 @@ class TerminalReporter {
253
233
  case 'bundling_error':
254
234
  this._logBundlingError(event.error);
255
235
  break;
256
- case 'global_cache_disabled':
257
- this._logCacheDisabled(event.reason);
258
- break;
259
236
  case 'resolver_warning':
260
237
  this._logWarning(event.message);
261
238
  break;
@@ -408,6 +385,9 @@ class TerminalReporter {
408
385
  case 'bundle_transform_progressed_throttled':
409
386
  this._updateBundleProgress(event);
410
387
  break;
388
+ case 'unstable_set_interaction_status':
389
+ this._interactionStatus = event.status;
390
+ break;
411
391
  }
412
392
  }
413
393
 
@@ -421,7 +401,8 @@ class TerminalReporter {
421
401
  .map(([_, progress]: [string, BundleProgress]) =>
422
402
  this._getBundleStatusMessage(progress, 'in_progress'),
423
403
  )
424
- .filter((str: null | string) => str != null)
404
+ .concat([this._interactionStatus])
405
+ .filter((str: ?string) => str != null)
425
406
  .join('\n');
426
407
  }
427
408
 
@@ -5,7 +5,9 @@ function _interopRequireDefault(obj) {
5
5
  return obj && obj.__esModule ? obj : { default: obj };
6
6
  }
7
7
  const getInlineSourceMappingURL = require("../DeltaBundler/Serializers/helpers/getInlineSourceMappingURL");
8
- const sourceMapString = require("../DeltaBundler/Serializers/sourceMapString");
8
+ const {
9
+ sourceMapString,
10
+ } = require("../DeltaBundler/Serializers/sourceMapString");
9
11
  const countLines = require("./countLines");
10
12
  const nullthrows = require("nullthrows");
11
13
  function getAppendScripts(entryPoint, modules, options) {
@@ -43,6 +45,7 @@ function getAppendScripts(entryPoint, modules, options) {
43
45
  processModuleFilter: () => true,
44
46
  excludeSource: false,
45
47
  shouldAddToIgnoreList: options.shouldAddToIgnoreList,
48
+ getSourceUrl: options.getSourceUrl,
46
49
  })
47
50
  )
48
51
  : nullthrows(options.sourceMapUrl);
@@ -16,7 +16,9 @@ import type {Dependency} from '../DeltaBundler/types.flow';
16
16
  import CountingSet from './CountingSet';
17
17
 
18
18
  const getInlineSourceMappingURL = require('../DeltaBundler/Serializers/helpers/getInlineSourceMappingURL');
19
- const sourceMapString = require('../DeltaBundler/Serializers/sourceMapString');
19
+ const {
20
+ sourceMapString,
21
+ } = require('../DeltaBundler/Serializers/sourceMapString');
20
22
  const countLines = require('./countLines');
21
23
  const nullthrows = require('nullthrows');
22
24
 
@@ -30,6 +32,7 @@ type Options<T: number | string> = $ReadOnly<{
30
32
  shouldAddToIgnoreList: (Module<>) => boolean,
31
33
  sourceMapUrl: ?string,
32
34
  sourceUrl: ?string,
35
+ getSourceUrl: ?(Module<>) => string,
33
36
  ...
34
37
  }>;
35
38
 
@@ -75,6 +78,7 @@ function getAppendScripts<T: number | string>(
75
78
  processModuleFilter: (): boolean => true,
76
79
  excludeSource: false,
77
80
  shouldAddToIgnoreList: options.shouldAddToIgnoreList,
81
+ getSourceUrl: options.getSourceUrl,
78
82
  }),
79
83
  )
80
84
  : nullthrows(options.sourceMapUrl);
@@ -26,6 +26,7 @@ module.exports = (
26
26
  mode: 'BRIDGE' | 'NOBRIDGE',
27
27
  ...data: Array<mixed>
28
28
  ) => {
29
+ // $FlowFixMe[invalid-computed-prop]
29
30
  const logFunction = console[level] && level !== 'trace' ? level : 'log';
30
31
  const color =
31
32
  level === 'error'
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _types = require("../shared/types.flow");
3
4
  const parsePlatformFilePath = require("../node-haste/lib/parsePlatformFilePath");
4
5
  const parseCustomResolverOptions = require("./parseCustomResolverOptions");
5
6
  const parseCustomTransformOptions = require("./parseCustomTransformOptions");
@@ -50,6 +51,9 @@ module.exports = function parseOptionsFromUrl(normalizedRequestUrl, platforms) {
50
51
  : "",
51
52
  pathname: pathname.replace(/\.(bundle|delta)$/, ".map"),
52
53
  }),
54
+ sourcePaths:
55
+ _types.SourcePathsMode.cast(query.sourcePaths) ??
56
+ _types.SourcePathsMode.Absolute,
53
57
  sourceUrl: jscSafeUrl.toJscSafeUrl(normalizedRequestUrl),
54
58
  unstable_transformProfile: getTransformProfile(
55
59
  query.unstable_transformProfile
@@ -14,6 +14,8 @@
14
14
  import type {BundleOptions} from '../shared/types.flow';
15
15
  import type {TransformProfile} from 'metro-babel-transformer';
16
16
 
17
+ import {SourcePathsMode} from '../shared/types.flow';
18
+
17
19
  const parsePlatformFilePath = require('../node-haste/lib/parsePlatformFilePath');
18
20
  const parseCustomResolverOptions = require('./parseCustomResolverOptions');
19
21
  const parseCustomTransformOptions = require('./parseCustomTransformOptions');
@@ -81,6 +83,8 @@ module.exports = function parseOptionsFromUrl(
81
83
  : '',
82
84
  pathname: pathname.replace(/\.(bundle|delta)$/, '.map'),
83
85
  }),
86
+ sourcePaths:
87
+ SourcePathsMode.cast(query.sourcePaths) ?? SourcePathsMode.Absolute,
84
88
  sourceUrl: jscSafeUrl.toJscSafeUrl(normalizedRequestUrl),
85
89
  unstable_transformProfile: getTransformProfile(
86
90
  query.unstable_transformProfile,
@@ -10,8 +10,6 @@
10
10
 
11
11
  import type {HealthCheckResult, WatcherStatus} from 'metro-file-map';
12
12
 
13
- export type GlobalCacheDisabledReason = 'too_many_errors' | 'too_many_misses';
14
-
15
13
  export interface BundleDetails {
16
14
  bundleType: string;
17
15
  dev: boolean;
@@ -65,12 +63,12 @@ export type ReportableEvent =
65
63
  totalFileCount: number;
66
64
  }
67
65
  | {
68
- type: 'global_cache_error';
66
+ type: 'cache_read_error';
69
67
  error: Error;
70
68
  }
71
69
  | {
72
- type: 'global_cache_disabled';
73
- reason: GlobalCacheDisabledReason;
70
+ type: 'cache_write_error';
71
+ error: Error;
74
72
  }
75
73
  | {type: 'transform_cache_reset'}
76
74
  | {
@@ -98,6 +96,12 @@ export type ReportableEvent =
98
96
  | 'debug';
99
97
  data: unknown[];
100
98
  }
99
+ | {
100
+ type: 'server_listening';
101
+ port: number;
102
+ address: string;
103
+ family: string;
104
+ }
101
105
  | {
102
106
  type: 'transformer_load_started';
103
107
  }
@@ -20,8 +20,6 @@ const chalk = require('chalk');
20
20
  const stripAnsi = require('strip-ansi');
21
21
  const util = require('util');
22
22
 
23
- export type GlobalCacheDisabledReason = 'too_many_errors' | 'too_many_misses';
24
-
25
23
  export type BundleDetails = {
26
24
  bundleType: string,
27
25
  customResolverOptions: CustomResolverOptions,
@@ -90,13 +88,13 @@ export type ReportableEvent =
90
88
  ...
91
89
  }
92
90
  | {
93
- type: 'global_cache_error',
91
+ type: 'cache_read_error',
94
92
  error: Error,
95
93
  ...
96
94
  }
97
95
  | {
98
- type: 'global_cache_disabled',
99
- reason: GlobalCacheDisabledReason,
96
+ type: 'cache_write_error',
97
+ error: Error,
100
98
  ...
101
99
  }
102
100
  | {type: 'transform_cache_reset', ...}
@@ -134,6 +132,12 @@ export type ReportableEvent =
134
132
  type: 'resolver_warning',
135
133
  message: string,
136
134
  }
135
+ | {
136
+ type: 'server_listening',
137
+ port: number,
138
+ address: string,
139
+ family: string,
140
+ }
137
141
  | {
138
142
  type: 'transformer_load_started',
139
143
  }
@@ -23,6 +23,7 @@ function splitBundleOptions(options) {
23
23
  runModule: options.runModule,
24
24
  sourceMapUrl: options.sourceMapUrl,
25
25
  sourceUrl: options.sourceUrl,
26
+ sourcePaths: options.sourcePaths,
26
27
  },
27
28
  graphOptions: {
28
29
  shallow: options.shallow,
@@ -39,6 +39,7 @@ function splitBundleOptions(options: BundleOptions): SplitBundleOptions {
39
39
  runModule: options.runModule,
40
40
  sourceMapUrl: options.sourceMapUrl,
41
41
  sourceUrl: options.sourceUrl,
42
+ sourcePaths: options.sourcePaths,
42
43
  },
43
44
  graphOptions: {
44
45
  shallow: options.shallow,
@@ -14,7 +14,7 @@ class ModuleResolver {
14
14
  this._projectRootFakeModule = {
15
15
  path: path.join(projectRoot, "_"),
16
16
  getPackage: () =>
17
- moduleCache.getPackageOf(this._projectRootFakeModule.path),
17
+ moduleCache.getPackageOf(this._projectRootFakeModule.path)?.pkg,
18
18
  isHaste() {
19
19
  throw new Error("not implemented");
20
20
  },
@@ -97,8 +97,8 @@ class ModuleResolver {
97
97
  resolveHastePackage: (name) =>
98
98
  this._options.getHastePackagePath(name, platform),
99
99
  getPackage: this._getPackage,
100
- getPackageForModule: (modulePath) =>
101
- this._getPackageForModule(fromModule, modulePath),
100
+ getPackageForModule: (absoluteModulePath) =>
101
+ this._getPackageForModule(absoluteModulePath),
102
102
  },
103
103
  dependency
104
104
  ),
@@ -159,15 +159,16 @@ class ModuleResolver {
159
159
  } catch (e) {}
160
160
  return null;
161
161
  };
162
- _getPackageForModule = (fromModule, modulePath) => {
163
- let pkg;
162
+ _getPackageForModule = (absolutePath) => {
163
+ let result;
164
164
  try {
165
- pkg = this._options.moduleCache.getPackageOf(modulePath);
165
+ result = this._options.moduleCache.getPackageOf(absolutePath);
166
166
  } catch (e) {}
167
- return pkg != null
167
+ return result != null
168
168
  ? {
169
- rootPath: path.dirname(pkg.path),
170
- packageJson: pkg.read(),
169
+ rootPath: path.dirname(result.pkg.path),
170
+ packageJson: result.pkg.read(),
171
+ packageRelativePath: result.packageRelativePath,
171
172
  }
172
173
  : null;
173
174
  };
@@ -25,7 +25,7 @@ import type {
25
25
  Resolution,
26
26
  ResolveAsset,
27
27
  } from 'metro-resolver';
28
- import type {PackageInfo, PackageJson} from 'metro-resolver/src/types';
28
+ import type {PackageForModule, PackageJson} from 'metro-resolver/src/types';
29
29
 
30
30
  const {codeFrameColumns} = require('@babel/code-frame');
31
31
  const fs = require('fs');
@@ -53,7 +53,10 @@ export type ModuleishCache<TPackage> = interface {
53
53
  platform?: string,
54
54
  supportsNativePlatform?: boolean,
55
55
  ): TPackage,
56
- getPackageOf(modulePath: string): ?TPackage,
56
+ getPackageOf(absolutePath: string): ?{
57
+ pkg: TPackage,
58
+ packageRelativePath: string,
59
+ },
57
60
  };
58
61
 
59
62
  type Options<TPackage> = $ReadOnly<{
@@ -95,7 +98,7 @@ class ModuleResolver<TPackage: Packageish> {
95
98
  this._projectRootFakeModule = {
96
99
  path: path.join(projectRoot, '_'),
97
100
  getPackage: () =>
98
- moduleCache.getPackageOf(this._projectRootFakeModule.path),
101
+ moduleCache.getPackageOf(this._projectRootFakeModule.path)?.pkg,
99
102
  isHaste() {
100
103
  throw new Error('not implemented');
101
104
  },
@@ -179,8 +182,8 @@ class ModuleResolver<TPackage: Packageish> {
179
182
  resolveHastePackage: (name: string) =>
180
183
  this._options.getHastePackagePath(name, platform),
181
184
  getPackage: this._getPackage,
182
- getPackageForModule: (modulePath: string) =>
183
- this._getPackageForModule(fromModule, modulePath),
185
+ getPackageForModule: (absoluteModulePath: string) =>
186
+ this._getPackageForModule(absoluteModulePath),
184
187
  },
185
188
  dependency,
186
189
  ),
@@ -249,23 +252,21 @@ class ModuleResolver<TPackage: Packageish> {
249
252
  return null;
250
253
  };
251
254
 
252
- _getPackageForModule = (
253
- fromModule: Moduleish,
254
- modulePath: string,
255
- ): ?PackageInfo => {
256
- let pkg;
255
+ _getPackageForModule = (absolutePath: string): ?PackageForModule => {
256
+ let result;
257
257
 
258
258
  try {
259
- pkg = this._options.moduleCache.getPackageOf(modulePath);
259
+ result = this._options.moduleCache.getPackageOf(absolutePath);
260
260
  } catch (e) {
261
261
  // Do nothing. The standard module cache does not trigger any error, but
262
262
  // the ModuleGraph one does, if the module does not exist.
263
263
  }
264
264
 
265
- return pkg != null
265
+ return result != null
266
266
  ? {
267
- rootPath: path.dirname(pkg.path),
268
- packageJson: pkg.read(),
267
+ rootPath: path.dirname(result.pkg.path),
268
+ packageJson: result.pkg.read(),
269
+ packageRelativePath: result.packageRelativePath,
269
270
  }
270
271
  : null;
271
272
  };
@@ -322,6 +323,7 @@ function getArrayLowestItem(a: $ReadOnlyArray<string>): string | void {
322
323
  return lowest;
323
324
  }
324
325
 
326
+ // $FlowFixMe[incompatible-extend]
325
327
  class UnableToResolveError extends Error {
326
328
  /**
327
329
  * File path of the module that tried to require a module, ex. `/js/foo.js`.
@@ -80,8 +80,8 @@ class DependencyGraph extends EventEmitter {
80
80
  await self.ready();
81
81
  return self;
82
82
  }
83
- _getClosestPackage(filePath) {
84
- const parsedPath = path.parse(filePath);
83
+ _getClosestPackage(absoluteModulePath) {
84
+ const parsedPath = path.parse(absoluteModulePath);
85
85
  const root = parsedPath.root;
86
86
  let dir = path.join(parsedPath.dir, parsedPath.base);
87
87
  do {
@@ -90,7 +90,10 @@ class DependencyGraph extends EventEmitter {
90
90
  }
91
91
  const candidate = path.join(dir, "package.json");
92
92
  if (this._fileSystem.exists(candidate)) {
93
- return candidate;
93
+ return {
94
+ packageJsonPath: candidate,
95
+ packageRelativePath: path.relative(dir, absoluteModulePath),
96
+ };
94
97
  }
95
98
  dir = path.dirname(dir);
96
99
  } while (dir !== "." && dir !== root);
@@ -163,7 +166,8 @@ class DependencyGraph extends EventEmitter {
163
166
  }
164
167
  _createModuleCache() {
165
168
  return new ModuleCache({
166
- getClosestPackage: (filePath) => this._getClosestPackage(filePath),
169
+ getClosestPackage: (absoluteModulePath) =>
170
+ this._getClosestPackage(absoluteModulePath),
167
171
  });
168
172
  }
169
173
  getAllFiles() {
@@ -152,8 +152,10 @@ class DependencyGraph extends EventEmitter {
152
152
  return self;
153
153
  }
154
154
 
155
- _getClosestPackage(filePath: string): ?string {
156
- const parsedPath = path.parse(filePath);
155
+ _getClosestPackage(
156
+ absoluteModulePath: string,
157
+ ): ?{packageJsonPath: string, packageRelativePath: string} {
158
+ const parsedPath = path.parse(absoluteModulePath);
157
159
  const root = parsedPath.root;
158
160
  let dir = path.join(parsedPath.dir, parsedPath.base);
159
161
 
@@ -165,7 +167,12 @@ class DependencyGraph extends EventEmitter {
165
167
  }
166
168
  const candidate = path.join(dir, 'package.json');
167
169
  if (this._fileSystem.exists(candidate)) {
168
- return candidate;
170
+ return {
171
+ packageJsonPath: candidate,
172
+ // Note that by construction, dir is a prefix of absoluteModulePath,
173
+ // so this relative path has no indirections.
174
+ packageRelativePath: path.relative(dir, absoluteModulePath),
175
+ };
169
176
  }
170
177
  dir = path.dirname(dir);
171
178
  } while (dir !== '.' && dir !== root);
@@ -242,7 +249,8 @@ class DependencyGraph extends EventEmitter {
242
249
 
243
250
  _createModuleCache(): ModuleCache {
244
251
  return new ModuleCache({
245
- getClosestPackage: filePath => this._getClosestPackage(filePath),
252
+ getClosestPackage: absoluteModulePath =>
253
+ this._getClosestPackage(absoluteModulePath),
246
254
  });
247
255
  }
248
256