metro 0.81.2 → 0.81.3
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/package.json +15 -15
- package/src/DeltaBundler/types.flow.js.flow +5 -0
- package/src/HmrServer.js +1 -0
- package/src/HmrServer.js.flow +1 -0
- package/src/ModuleGraph/worker/collectDependencies.js +22 -5
- package/src/ModuleGraph/worker/collectDependencies.js.flow +42 -9
- package/src/ModuleGraph/worker/importLocationsPlugin.js +51 -0
- package/src/ModuleGraph/worker/importLocationsPlugin.js.flow +82 -0
- package/src/Server.js +1 -0
- package/src/Server.js.flow +1 -1
- package/src/node-haste/DependencyGraph/ModuleResolution.js +2 -0
- package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +2 -0
- package/src/node-haste/DependencyGraph.js +2 -1
- package/src/node-haste/DependencyGraph.js.flow +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metro",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.3",
|
|
4
4
|
"description": "🚇 The JavaScript bundler for React Native.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": "src/cli.js",
|
|
@@ -42,18 +42,18 @@
|
|
|
42
42
|
"jest-worker": "^29.7.0",
|
|
43
43
|
"jsc-safe-url": "^0.2.2",
|
|
44
44
|
"lodash.throttle": "^4.1.1",
|
|
45
|
-
"metro-babel-transformer": "0.81.
|
|
46
|
-
"metro-cache": "0.81.
|
|
47
|
-
"metro-cache-key": "0.81.
|
|
48
|
-
"metro-config": "0.81.
|
|
49
|
-
"metro-core": "0.81.
|
|
50
|
-
"metro-file-map": "0.81.
|
|
51
|
-
"metro-resolver": "0.81.
|
|
52
|
-
"metro-runtime": "0.81.
|
|
53
|
-
"metro-source-map": "0.81.
|
|
54
|
-
"metro-symbolicate": "0.81.
|
|
55
|
-
"metro-transform-plugins": "0.81.
|
|
56
|
-
"metro-transform-worker": "0.81.
|
|
45
|
+
"metro-babel-transformer": "0.81.3",
|
|
46
|
+
"metro-cache": "0.81.3",
|
|
47
|
+
"metro-cache-key": "0.81.3",
|
|
48
|
+
"metro-config": "0.81.3",
|
|
49
|
+
"metro-core": "0.81.3",
|
|
50
|
+
"metro-file-map": "0.81.3",
|
|
51
|
+
"metro-resolver": "0.81.3",
|
|
52
|
+
"metro-runtime": "0.81.3",
|
|
53
|
+
"metro-source-map": "0.81.3",
|
|
54
|
+
"metro-symbolicate": "0.81.3",
|
|
55
|
+
"metro-transform-plugins": "0.81.3",
|
|
56
|
+
"metro-transform-worker": "0.81.3",
|
|
57
57
|
"mime-types": "^2.1.27",
|
|
58
58
|
"nullthrows": "^1.1.1",
|
|
59
59
|
"serialize-error": "^2.1.0",
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
"dedent": "^0.7.0",
|
|
72
72
|
"jest-snapshot": "^29.7.0",
|
|
73
73
|
"jest-snapshot-serializer-raw": "^1.2.0",
|
|
74
|
-
"metro-babel-register": "0.81.
|
|
75
|
-
"metro-memory-fs": "0.81.
|
|
74
|
+
"metro-babel-register": "0.81.3",
|
|
75
|
+
"metro-memory-fs": "0.81.3",
|
|
76
76
|
"mock-req": "^0.2.0",
|
|
77
77
|
"mock-res": "^0.6.0",
|
|
78
78
|
"stack-trace": "^0.0.10"
|
|
@@ -44,6 +44,11 @@ export type TransformResultDependency = $ReadOnly<{
|
|
|
44
44
|
* If not null, this dependency is due to a dynamic `import()` or `__prefetchImport()` call.
|
|
45
45
|
*/
|
|
46
46
|
asyncType: AsyncDependencyType | null,
|
|
47
|
+
/**
|
|
48
|
+
* True if the dependency is declared with a static "import x from 'y'" or
|
|
49
|
+
* an import() call.
|
|
50
|
+
*/
|
|
51
|
+
isESMImport: boolean,
|
|
47
52
|
/**
|
|
48
53
|
* The dependency is enclosed in a try/catch block.
|
|
49
54
|
*/
|
package/src/HmrServer.js
CHANGED
package/src/HmrServer.js.flow
CHANGED
|
@@ -21,6 +21,7 @@ function collectDependencies(ast, options) {
|
|
|
21
21
|
keepRequireNames: options.keepRequireNames,
|
|
22
22
|
allowOptionalDependencies: options.allowOptionalDependencies,
|
|
23
23
|
unstable_allowRequireContext: options.unstable_allowRequireContext,
|
|
24
|
+
unstable_isESMImportAtSource: options.unstable_isESMImportAtSource ?? null,
|
|
24
25
|
};
|
|
25
26
|
const visitor = {
|
|
26
27
|
CallExpression(path, state) {
|
|
@@ -32,12 +33,14 @@ function collectDependencies(ast, options) {
|
|
|
32
33
|
if (isImport(callee)) {
|
|
33
34
|
processImportCall(path, state, {
|
|
34
35
|
asyncType: "async",
|
|
36
|
+
isESMImport: true,
|
|
35
37
|
});
|
|
36
38
|
return;
|
|
37
39
|
}
|
|
38
40
|
if (name === "__prefetchImport" && !path.scope.getBinding(name)) {
|
|
39
41
|
processImportCall(path, state, {
|
|
40
42
|
asyncType: "prefetch",
|
|
43
|
+
isESMImport: true,
|
|
41
44
|
});
|
|
42
45
|
return;
|
|
43
46
|
}
|
|
@@ -79,6 +82,7 @@ function collectDependencies(ast, options) {
|
|
|
79
82
|
) {
|
|
80
83
|
processImportCall(path, state, {
|
|
81
84
|
asyncType: "maybeSync",
|
|
85
|
+
isESMImport: true,
|
|
82
86
|
});
|
|
83
87
|
visited.add(path.node);
|
|
84
88
|
return;
|
|
@@ -222,6 +226,7 @@ function processRequireContextCall(path, state) {
|
|
|
222
226
|
name: directory,
|
|
223
227
|
contextParams,
|
|
224
228
|
asyncType: null,
|
|
229
|
+
isESMImport: false,
|
|
225
230
|
optional: isOptionalDependency(directory, path, state),
|
|
226
231
|
},
|
|
227
232
|
path
|
|
@@ -239,6 +244,7 @@ function processResolveWeakCall(path, state) {
|
|
|
239
244
|
{
|
|
240
245
|
name,
|
|
241
246
|
asyncType: "weak",
|
|
247
|
+
isESMImport: false,
|
|
242
248
|
optional: isOptionalDependency(name, path, state),
|
|
243
249
|
},
|
|
244
250
|
path
|
|
@@ -261,6 +267,7 @@ See: https://github.com/facebook/metro/pull/1343`
|
|
|
261
267
|
{
|
|
262
268
|
name: path.node.source.value,
|
|
263
269
|
asyncType: null,
|
|
270
|
+
isESMImport: true,
|
|
264
271
|
optional: false,
|
|
265
272
|
},
|
|
266
273
|
path
|
|
@@ -277,6 +284,7 @@ function processImportCall(path, state, options) {
|
|
|
277
284
|
{
|
|
278
285
|
name,
|
|
279
286
|
asyncType: options.asyncType,
|
|
287
|
+
isESMImport: options.isESMImport,
|
|
280
288
|
optional: isOptionalDependency(name, path, state),
|
|
281
289
|
},
|
|
282
290
|
path
|
|
@@ -309,11 +317,20 @@ function processRequireCall(path, state) {
|
|
|
309
317
|
transformer.transformIllegalDynamicRequire(path, state);
|
|
310
318
|
return;
|
|
311
319
|
}
|
|
320
|
+
let isESMImport = false;
|
|
321
|
+
if (state.unstable_isESMImportAtSource) {
|
|
322
|
+
const isImport = state.unstable_isESMImportAtSource;
|
|
323
|
+
const loc = getNearestLocFromPath(path);
|
|
324
|
+
if (loc) {
|
|
325
|
+
isESMImport = isImport(loc);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
312
328
|
const dep = registerDependency(
|
|
313
329
|
state,
|
|
314
330
|
{
|
|
315
331
|
name,
|
|
316
332
|
asyncType: null,
|
|
333
|
+
isESMImport,
|
|
317
334
|
optional: isOptionalDependency(name, path, state),
|
|
318
335
|
},
|
|
319
336
|
path
|
|
@@ -502,12 +519,11 @@ function createModuleNameLiteral(dependency) {
|
|
|
502
519
|
return types.stringLiteral(dependency.name);
|
|
503
520
|
}
|
|
504
521
|
function getKeyForDependency(qualifier) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
if (asyncType) {
|
|
508
|
-
key +=
|
|
522
|
+
const { asyncType, contextParams, isESMImport, name } = qualifier;
|
|
523
|
+
let key = [name, isESMImport ? "import" : "require"].join("\0");
|
|
524
|
+
if (asyncType != null) {
|
|
525
|
+
key += "\0" + asyncType;
|
|
509
526
|
}
|
|
510
|
-
const { contextParams } = qualifier;
|
|
511
527
|
if (contextParams) {
|
|
512
528
|
key += [
|
|
513
529
|
"",
|
|
@@ -529,6 +545,7 @@ class DependencyRegistry {
|
|
|
529
545
|
const newDependency = {
|
|
530
546
|
name: qualifier.name,
|
|
531
547
|
asyncType: qualifier.asyncType,
|
|
548
|
+
isESMImport: qualifier.isESMImport,
|
|
532
549
|
locs: [],
|
|
533
550
|
index: this._dependencies.size,
|
|
534
551
|
key: crypto.createHash("sha1").update(key).digest("base64"),
|
|
@@ -29,6 +29,7 @@ const {isImport} = types;
|
|
|
29
29
|
|
|
30
30
|
type ImportDependencyOptions = $ReadOnly<{
|
|
31
31
|
asyncType: AsyncDependencyType,
|
|
32
|
+
isESMImport: boolean,
|
|
32
33
|
}>;
|
|
33
34
|
|
|
34
35
|
export type Dependency = $ReadOnly<{
|
|
@@ -56,6 +57,11 @@ type DependencyData = $ReadOnly<{
|
|
|
56
57
|
// If null, then the dependency is synchronous.
|
|
57
58
|
// (ex. `require('foo')`)
|
|
58
59
|
asyncType: AsyncDependencyType | null,
|
|
60
|
+
// If true, the dependency is declared using an ESM import, e.g.
|
|
61
|
+
// "import x from 'y'" or "await import('z')". A resolver should typically
|
|
62
|
+
// use this to assert either "import" or "require" for conditional exports
|
|
63
|
+
// and subpath imports.
|
|
64
|
+
isESMImport: boolean,
|
|
59
65
|
isOptional?: boolean,
|
|
60
66
|
locs: $ReadOnlyArray<BabelSourceLocation>,
|
|
61
67
|
/** Context for requiring a collection of modules. */
|
|
@@ -82,6 +88,7 @@ export type State = {
|
|
|
82
88
|
allowOptionalDependencies: AllowOptionalDependencies,
|
|
83
89
|
/** Enable `require.context` statements which can be used to import multiple files in a directory. */
|
|
84
90
|
unstable_allowRequireContext: boolean,
|
|
91
|
+
unstable_isESMImportAtSource: ?(BabelSourceLocation) => boolean,
|
|
85
92
|
};
|
|
86
93
|
|
|
87
94
|
export type Options = $ReadOnly<{
|
|
@@ -94,6 +101,7 @@ export type Options = $ReadOnly<{
|
|
|
94
101
|
dependencyTransformer?: DependencyTransformer,
|
|
95
102
|
/** Enable `require.context` statements which can be used to import multiple files in a directory. */
|
|
96
103
|
unstable_allowRequireContext: boolean,
|
|
104
|
+
unstable_isESMImportAtSource?: ?(BabelSourceLocation) => boolean,
|
|
97
105
|
}>;
|
|
98
106
|
|
|
99
107
|
export type CollectedDependencies = $ReadOnly<{
|
|
@@ -154,6 +162,7 @@ function collectDependencies(
|
|
|
154
162
|
keepRequireNames: options.keepRequireNames,
|
|
155
163
|
allowOptionalDependencies: options.allowOptionalDependencies,
|
|
156
164
|
unstable_allowRequireContext: options.unstable_allowRequireContext,
|
|
165
|
+
unstable_isESMImportAtSource: options.unstable_isESMImportAtSource ?? null,
|
|
157
166
|
};
|
|
158
167
|
|
|
159
168
|
const visitor = {
|
|
@@ -171,6 +180,7 @@ function collectDependencies(
|
|
|
171
180
|
if (isImport(callee)) {
|
|
172
181
|
processImportCall(path, state, {
|
|
173
182
|
asyncType: 'async',
|
|
183
|
+
isESMImport: true,
|
|
174
184
|
});
|
|
175
185
|
return;
|
|
176
186
|
}
|
|
@@ -178,6 +188,7 @@ function collectDependencies(
|
|
|
178
188
|
if (name === '__prefetchImport' && !path.scope.getBinding(name)) {
|
|
179
189
|
processImportCall(path, state, {
|
|
180
190
|
asyncType: 'prefetch',
|
|
191
|
+
isESMImport: true,
|
|
181
192
|
});
|
|
182
193
|
return;
|
|
183
194
|
}
|
|
@@ -235,6 +246,10 @@ function collectDependencies(
|
|
|
235
246
|
) {
|
|
236
247
|
processImportCall(path, state, {
|
|
237
248
|
asyncType: 'maybeSync',
|
|
249
|
+
// Treat require.unstable_importMaybeSync as an ESM import, like its
|
|
250
|
+
// async "await import()" counterpart. Subject to change while
|
|
251
|
+
// unstable_.
|
|
252
|
+
isESMImport: true,
|
|
238
253
|
});
|
|
239
254
|
visited.add(path.node);
|
|
240
255
|
return;
|
|
@@ -408,6 +423,7 @@ function processRequireContextCall(
|
|
|
408
423
|
// Capture the matching context
|
|
409
424
|
contextParams,
|
|
410
425
|
asyncType: null,
|
|
426
|
+
isESMImport: false,
|
|
411
427
|
optional: isOptionalDependency(directory, path, state),
|
|
412
428
|
},
|
|
413
429
|
path,
|
|
@@ -433,6 +449,7 @@ function processResolveWeakCall(
|
|
|
433
449
|
{
|
|
434
450
|
name,
|
|
435
451
|
asyncType: 'weak',
|
|
452
|
+
isESMImport: false,
|
|
436
453
|
optional: isOptionalDependency(name, path, state),
|
|
437
454
|
},
|
|
438
455
|
path,
|
|
@@ -458,6 +475,7 @@ See: https://github.com/facebook/metro/pull/1343`,
|
|
|
458
475
|
{
|
|
459
476
|
name: path.node.source.value,
|
|
460
477
|
asyncType: null,
|
|
478
|
+
isESMImport: true,
|
|
461
479
|
optional: false,
|
|
462
480
|
},
|
|
463
481
|
path,
|
|
@@ -481,6 +499,7 @@ function processImportCall(
|
|
|
481
499
|
{
|
|
482
500
|
name,
|
|
483
501
|
asyncType: options.asyncType,
|
|
502
|
+
isESMImport: options.isESMImport,
|
|
484
503
|
optional: isOptionalDependency(name, path, state),
|
|
485
504
|
},
|
|
486
505
|
path,
|
|
@@ -523,11 +542,21 @@ function processRequireCall(
|
|
|
523
542
|
return;
|
|
524
543
|
}
|
|
525
544
|
|
|
545
|
+
let isESMImport = false;
|
|
546
|
+
if (state.unstable_isESMImportAtSource) {
|
|
547
|
+
const isImport = state.unstable_isESMImportAtSource;
|
|
548
|
+
const loc = getNearestLocFromPath(path);
|
|
549
|
+
if (loc) {
|
|
550
|
+
isESMImport = isImport(loc);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
526
554
|
const dep = registerDependency(
|
|
527
555
|
state,
|
|
528
556
|
{
|
|
529
557
|
name,
|
|
530
558
|
asyncType: null,
|
|
559
|
+
isESMImport,
|
|
531
560
|
optional: isOptionalDependency(name, path, state),
|
|
532
561
|
},
|
|
533
562
|
path,
|
|
@@ -555,6 +584,7 @@ function getNearestLocFromPath(path: NodePath<>): ?BabelSourceLocation {
|
|
|
555
584
|
export type ImportQualifier = $ReadOnly<{
|
|
556
585
|
name: string,
|
|
557
586
|
asyncType: AsyncDependencyType | null,
|
|
587
|
+
isESMImport: boolean,
|
|
558
588
|
optional: boolean,
|
|
559
589
|
contextParams?: RequireContextParams,
|
|
560
590
|
}>;
|
|
@@ -801,13 +831,16 @@ function createModuleNameLiteral(dependency: InternalDependency) {
|
|
|
801
831
|
|
|
802
832
|
/**
|
|
803
833
|
* Given an import qualifier, return a key used to register the dependency.
|
|
804
|
-
*
|
|
805
|
-
*
|
|
806
|
-
*
|
|
834
|
+
* Attributes can be appended to distinguish various combinations that would
|
|
835
|
+
* otherwise be considered the same dependency edge.
|
|
836
|
+
*
|
|
837
|
+
* For example, the following dependencies would collapse into a single edge
|
|
838
|
+
* if they simply utilized the `name` property:
|
|
807
839
|
*
|
|
808
|
-
* For example, the following case would have collision issues if they all utilized the `name` property:
|
|
809
840
|
* ```
|
|
810
841
|
* require('./foo');
|
|
842
|
+
* import foo from './foo'
|
|
843
|
+
* await import('./foo')
|
|
811
844
|
* require.context('./foo');
|
|
812
845
|
* require.context('./foo', true, /something/);
|
|
813
846
|
* require.context('./foo', false, /something/);
|
|
@@ -817,14 +850,13 @@ function createModuleNameLiteral(dependency: InternalDependency) {
|
|
|
817
850
|
* This method should be utilized by `registerDependency`.
|
|
818
851
|
*/
|
|
819
852
|
function getKeyForDependency(qualifier: ImportQualifier): string {
|
|
820
|
-
|
|
853
|
+
const {asyncType, contextParams, isESMImport, name} = qualifier;
|
|
821
854
|
|
|
822
|
-
|
|
823
|
-
if (asyncType) {
|
|
824
|
-
key +=
|
|
855
|
+
let key = [name, isESMImport ? 'import' : 'require'].join('\0');
|
|
856
|
+
if (asyncType != null) {
|
|
857
|
+
key += '\0' + asyncType;
|
|
825
858
|
}
|
|
826
859
|
|
|
827
|
-
const {contextParams} = qualifier;
|
|
828
860
|
// Add extra qualifiers when using `require.context` to prevent collisions.
|
|
829
861
|
if (contextParams) {
|
|
830
862
|
// NOTE(EvanBacon): Keep this synchronized with `RequireContextParams`, if any other properties are added
|
|
@@ -854,6 +886,7 @@ class DependencyRegistry {
|
|
|
854
886
|
const newDependency: MutableInternalDependency = {
|
|
855
887
|
name: qualifier.name,
|
|
856
888
|
asyncType: qualifier.asyncType,
|
|
889
|
+
isESMImport: qualifier.isESMImport,
|
|
857
890
|
locs: [],
|
|
858
891
|
index: this._dependencies.size,
|
|
859
892
|
key: crypto.createHash('sha1').update(key).digest('base64'),
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const invariant = require("invariant");
|
|
4
|
+
function importLocationsPlugin({ types: t }) {
|
|
5
|
+
const importDeclarationLocs = new Set();
|
|
6
|
+
return {
|
|
7
|
+
visitor: {
|
|
8
|
+
ImportDeclaration(path) {
|
|
9
|
+
if (path.node.importKind !== "type" && path.node.loc != null) {
|
|
10
|
+
importDeclarationLocs.add(locToKey(path.node.loc));
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
ExportDeclaration(path) {
|
|
14
|
+
if (
|
|
15
|
+
path.node.source != null &&
|
|
16
|
+
path.node.exportKind !== "type" &&
|
|
17
|
+
path.node.loc != null
|
|
18
|
+
) {
|
|
19
|
+
importDeclarationLocs.add(locToKey(path.node.loc));
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
pre: ({ path, metadata }) => {
|
|
24
|
+
invariant(
|
|
25
|
+
path && t.isProgram(path.node),
|
|
26
|
+
"path missing or not a program node"
|
|
27
|
+
);
|
|
28
|
+
const metroMetadata = metadata;
|
|
29
|
+
if (!metroMetadata.metro) {
|
|
30
|
+
metroMetadata.metro = {
|
|
31
|
+
unstable_importDeclarationLocs: importDeclarationLocs,
|
|
32
|
+
};
|
|
33
|
+
} else {
|
|
34
|
+
metroMetadata.metro.unstable_importDeclarationLocs =
|
|
35
|
+
importDeclarationLocs;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const MISSING_LOC = {
|
|
41
|
+
line: -1,
|
|
42
|
+
column: -1,
|
|
43
|
+
};
|
|
44
|
+
function locToKey(loc) {
|
|
45
|
+
const { start = MISSING_LOC, end = MISSING_LOC } = loc;
|
|
46
|
+
return `${start.line},${start.column}:${end.line},${end.column}`;
|
|
47
|
+
}
|
|
48
|
+
module.exports = {
|
|
49
|
+
importLocationsPlugin,
|
|
50
|
+
locToKey,
|
|
51
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
import type {PluginObj} from '@babel/core';
|
|
15
|
+
import typeof * as Types from '@babel/types';
|
|
16
|
+
import type {MetroBabelFileMetadata} from 'metro-babel-transformer';
|
|
17
|
+
|
|
18
|
+
const invariant = require('invariant');
|
|
19
|
+
|
|
20
|
+
type ImportDeclarationLocs = Set<string>;
|
|
21
|
+
|
|
22
|
+
function importLocationsPlugin({types: t}: {types: Types, ...}): PluginObj<> {
|
|
23
|
+
const importDeclarationLocs: ImportDeclarationLocs = new Set();
|
|
24
|
+
return {
|
|
25
|
+
visitor: {
|
|
26
|
+
ImportDeclaration(path) {
|
|
27
|
+
if (
|
|
28
|
+
// Ignore type imports
|
|
29
|
+
path.node.importKind !== 'type' &&
|
|
30
|
+
// loc may not be set if this plugin runs alongside others which
|
|
31
|
+
// inject imports - eg Babel runtime helpers. We don't regard these
|
|
32
|
+
// as source import declarations.
|
|
33
|
+
path.node.loc != null
|
|
34
|
+
) {
|
|
35
|
+
importDeclarationLocs.add(locToKey(path.node.loc));
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
ExportDeclaration(path) {
|
|
39
|
+
if (
|
|
40
|
+
// If `source` is set, this is a re-export, so it declares an ESM
|
|
41
|
+
// dependency.
|
|
42
|
+
path.node.source != null &&
|
|
43
|
+
// Ignore type exports
|
|
44
|
+
path.node.exportKind !== 'type' &&
|
|
45
|
+
// As above, ignore injected imports.
|
|
46
|
+
path.node.loc != null
|
|
47
|
+
) {
|
|
48
|
+
importDeclarationLocs.add(locToKey(path.node.loc));
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
pre: ({path, metadata}) => {
|
|
53
|
+
invariant(
|
|
54
|
+
path && t.isProgram(path.node),
|
|
55
|
+
'path missing or not a program node',
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// $FlowFixMe[prop-missing] Babel `File` is not generically typed
|
|
59
|
+
const metroMetadata: MetroBabelFileMetadata = metadata;
|
|
60
|
+
|
|
61
|
+
// Set the result on a metadata property
|
|
62
|
+
if (!metroMetadata.metro) {
|
|
63
|
+
metroMetadata.metro = {
|
|
64
|
+
unstable_importDeclarationLocs: importDeclarationLocs,
|
|
65
|
+
};
|
|
66
|
+
} else {
|
|
67
|
+
metroMetadata.metro.unstable_importDeclarationLocs =
|
|
68
|
+
importDeclarationLocs;
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Very simple serialisation of a source location. This should remain opaque to
|
|
75
|
+
// the caller.
|
|
76
|
+
const MISSING_LOC = {line: -1, column: -1};
|
|
77
|
+
function locToKey(loc: BabelSourceLocation): string {
|
|
78
|
+
const {start = MISSING_LOC, end = MISSING_LOC} = loc;
|
|
79
|
+
return `${start.line},${start.column}:${end.line},${end.column}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = {importLocationsPlugin, locToKey};
|
package/src/Server.js
CHANGED
package/src/Server.js.flow
CHANGED
|
@@ -1420,7 +1420,7 @@ class Server {
|
|
|
1420
1420
|
: this._config.projectRoot;
|
|
1421
1421
|
return resolutionFn(`${rootDir}/.`, {
|
|
1422
1422
|
name: filePath,
|
|
1423
|
-
data: {key: filePath, locs: [], asyncType: null},
|
|
1423
|
+
data: {key: filePath, locs: [], asyncType: null, isESMImport: false},
|
|
1424
1424
|
}).filePath;
|
|
1425
1425
|
}
|
|
1426
1426
|
|
|
@@ -33,6 +33,7 @@ class ModuleResolver {
|
|
|
33
33
|
data: {
|
|
34
34
|
key: this._options.emptyModulePath,
|
|
35
35
|
asyncType: null,
|
|
36
|
+
isESMImport: false,
|
|
36
37
|
locs: [],
|
|
37
38
|
},
|
|
38
39
|
},
|
|
@@ -80,6 +81,7 @@ class ModuleResolver {
|
|
|
80
81
|
doesFileExist,
|
|
81
82
|
extraNodeModules,
|
|
82
83
|
fileSystemLookup,
|
|
84
|
+
isESMImport: dependency.data.isESMImport,
|
|
83
85
|
mainFields,
|
|
84
86
|
nodeModulesPaths,
|
|
85
87
|
preferNativePlatform,
|
|
@@ -118,6 +118,7 @@ class ModuleResolver<TPackage: Packageish> {
|
|
|
118
118
|
data: {
|
|
119
119
|
key: this._options.emptyModulePath,
|
|
120
120
|
asyncType: null,
|
|
121
|
+
isESMImport: false,
|
|
121
122
|
locs: [],
|
|
122
123
|
},
|
|
123
124
|
},
|
|
@@ -165,6 +166,7 @@ class ModuleResolver<TPackage: Packageish> {
|
|
|
165
166
|
doesFileExist,
|
|
166
167
|
extraNodeModules,
|
|
167
168
|
fileSystemLookup,
|
|
169
|
+
isESMImport: dependency.data.isESMImport,
|
|
168
170
|
mainFields,
|
|
169
171
|
nodeModulesPaths,
|
|
170
172
|
preferNativePlatform,
|
|
@@ -232,7 +232,8 @@ class DependencyGraph extends EventEmitter {
|
|
|
232
232
|
const resolverOptionsKey =
|
|
233
233
|
JSON.stringify(resolverOptions ?? {}, canonicalize) ?? "";
|
|
234
234
|
const originKey = isSensitiveToOriginFolder ? path.dirname(from) : "";
|
|
235
|
-
const targetKey =
|
|
235
|
+
const targetKey =
|
|
236
|
+
to + (dependency.data.isESMImport === true ? "\0esm" : "\0cjs");
|
|
236
237
|
const platformKey = platform ?? NULL_PLATFORM;
|
|
237
238
|
const mapByResolverOptions = this._resolutionCache;
|
|
238
239
|
const mapByOrigin = getOrCreateMap(
|
|
@@ -339,7 +339,8 @@ class DependencyGraph extends EventEmitter {
|
|
|
339
339
|
const resolverOptionsKey =
|
|
340
340
|
JSON.stringify(resolverOptions ?? {}, canonicalize) ?? '';
|
|
341
341
|
const originKey = isSensitiveToOriginFolder ? path.dirname(from) : '';
|
|
342
|
-
const targetKey =
|
|
342
|
+
const targetKey =
|
|
343
|
+
to + (dependency.data.isESMImport === true ? '\0esm' : '\0cjs');
|
|
343
344
|
const platformKey = platform ?? NULL_PLATFORM;
|
|
344
345
|
|
|
345
346
|
// Traverse the resolver cache, which is a tree of maps
|