metro 0.71.3 → 0.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metro",
3
- "version": "0.71.3",
3
+ "version": "0.72.0",
4
4
  "description": "🚇 The JavaScript bundler for React Native.",
5
5
  "main": "src/index.js",
6
6
  "bin": "src/cli.js",
@@ -36,22 +36,22 @@
36
36
  "invariant": "^2.2.4",
37
37
  "jest-worker": "^27.2.0",
38
38
  "lodash.throttle": "^4.1.1",
39
- "metro-babel-transformer": "0.71.3",
40
- "metro-cache": "0.71.3",
41
- "metro-cache-key": "0.71.3",
42
- "metro-config": "0.71.3",
43
- "metro-core": "0.71.3",
44
- "metro-file-map": "0.71.3",
45
- "metro-hermes-compiler": "0.71.3",
46
- "metro-inspector-proxy": "0.71.3",
47
- "metro-minify-uglify": "0.71.3",
48
- "metro-react-native-babel-preset": "0.71.3",
49
- "metro-resolver": "0.71.3",
50
- "metro-runtime": "0.71.3",
51
- "metro-source-map": "0.71.3",
52
- "metro-symbolicate": "0.71.3",
53
- "metro-transform-plugins": "0.71.3",
54
- "metro-transform-worker": "0.71.3",
39
+ "metro-babel-transformer": "0.72.0",
40
+ "metro-cache": "0.72.0",
41
+ "metro-cache-key": "0.72.0",
42
+ "metro-config": "0.72.0",
43
+ "metro-core": "0.72.0",
44
+ "metro-file-map": "0.72.0",
45
+ "metro-hermes-compiler": "0.72.0",
46
+ "metro-inspector-proxy": "0.72.0",
47
+ "metro-minify-uglify": "0.72.0",
48
+ "metro-react-native-babel-preset": "0.72.0",
49
+ "metro-resolver": "0.72.0",
50
+ "metro-runtime": "0.72.0",
51
+ "metro-source-map": "0.72.0",
52
+ "metro-symbolicate": "0.72.0",
53
+ "metro-transform-plugins": "0.72.0",
54
+ "metro-transform-worker": "0.72.0",
55
55
  "mime-types": "^2.1.27",
56
56
  "node-fetch": "^2.2.0",
57
57
  "nullthrows": "^1.1.1",
@@ -70,10 +70,10 @@
70
70
  "babel-jest": "^26.6.3",
71
71
  "dedent": "^0.7.0",
72
72
  "jest-snapshot": "^26.5.2",
73
- "metro-babel-register": "0.71.3",
74
- "metro-memory-fs": "0.71.3",
75
- "metro-react-native-babel-preset": "0.71.3",
76
- "metro-react-native-babel-transformer": "0.71.3",
73
+ "metro-babel-register": "0.72.0",
74
+ "metro-memory-fs": "0.72.0",
75
+ "metro-react-native-babel-preset": "0.72.0",
76
+ "metro-react-native-babel-transformer": "0.72.0",
77
77
  "stack-trace": "^0.0.10"
78
78
  },
79
79
  "license": "MIT"
package/src/Assets.js CHANGED
@@ -108,8 +108,9 @@ async function getAbsoluteAssetRecord(assetPath, platform = null) {
108
108
 
109
109
  if (!record) {
110
110
  throw new Error(
111
- /* $FlowFixMe: platform can be null */
112
- `Asset not found: ${assetPath} for platform: ${platform}`
111
+ `Asset not found: ${assetPath} for platform: ${
112
+ platform !== null && platform !== void 0 ? platform : "(unspecified)"
113
+ }`
113
114
  );
114
115
  }
115
116
 
@@ -154,8 +154,9 @@ async function getAbsoluteAssetRecord(
154
154
 
155
155
  if (!record) {
156
156
  throw new Error(
157
- /* $FlowFixMe: platform can be null */
158
- `Asset not found: ${assetPath} for platform: ${platform}`,
157
+ `Asset not found: ${assetPath} for platform: ${
158
+ platform ?? '(unspecified)'
159
+ }`,
159
160
  );
160
161
  }
161
162
 
@@ -201,8 +201,8 @@ async function processModule(path, graph, delta, options) {
201
201
  };
202
202
  graph.dependencies.set(module.path, module); // Diff dependencies (1/2): remove dependencies that have changed or been removed.
203
203
 
204
- for (const [relativePath, prevDependency] of previousDependencies) {
205
- const curDependency = currentDependencies.get(relativePath);
204
+ for (const [key, prevDependency] of previousDependencies) {
205
+ const curDependency = currentDependencies.get(key);
206
206
 
207
207
  if (
208
208
  !curDependency ||
@@ -211,21 +211,14 @@ async function processModule(path, graph, delta, options) {
211
211
  curDependency.data.data.asyncType !==
212
212
  prevDependency.data.data.asyncType)
213
213
  ) {
214
- removeDependency(
215
- module,
216
- relativePath,
217
- prevDependency,
218
- graph,
219
- delta,
220
- options
221
- );
214
+ removeDependency(module, key, prevDependency, graph, delta, options);
222
215
  }
223
216
  } // Diff dependencies (2/2): add dependencies that have changed or been added.
224
217
 
225
218
  const promises = [];
226
219
 
227
- for (const [relativePath, curDependency] of currentDependencies) {
228
- const prevDependency = previousDependencies.get(relativePath);
220
+ for (const [key, curDependency] of currentDependencies) {
221
+ const prevDependency = previousDependencies.get(key);
229
222
 
230
223
  if (
231
224
  !prevDependency ||
@@ -235,14 +228,7 @@ async function processModule(path, graph, delta, options) {
235
228
  curDependency.data.data.asyncType)
236
229
  ) {
237
230
  promises.push(
238
- addDependency(
239
- module,
240
- relativePath,
241
- curDependency,
242
- graph,
243
- delta,
244
- options
245
- )
231
+ addDependency(module, key, curDependency, graph, delta, options)
246
232
  );
247
233
  }
248
234
  }
@@ -265,7 +251,7 @@ async function processModule(path, graph, delta, options) {
265
251
 
266
252
  async function addDependency(
267
253
  parentModule,
268
- relativePath,
254
+ key,
269
255
  dependency,
270
256
  graph,
271
257
  delta,
@@ -323,18 +309,18 @@ async function addDependency(
323
309
  // inverseDependencies and the other fields in the case of lazy edges.
324
310
  // Not an optimal representation :(
325
311
 
326
- parentModule.dependencies.set(relativePath, dependency);
312
+ parentModule.dependencies.set(key, dependency);
327
313
  }
328
314
 
329
315
  function removeDependency(
330
316
  parentModule,
331
- relativePath,
317
+ key,
332
318
  dependency,
333
319
  graph,
334
320
  delta,
335
321
  options
336
322
  ) {
337
- parentModule.dependencies.delete(relativePath);
323
+ parentModule.dependencies.delete(key);
338
324
  const { absolutePath } = dependency;
339
325
 
340
326
  if (
@@ -366,38 +352,48 @@ function removeDependency(
366
352
  }
367
353
 
368
354
  function resolveDependencies(parentPath, dependencies, options) {
369
- const resolve = (parentPath, result) => {
370
- const relativePath = result.name;
355
+ const maybeResolvedDeps = new Map();
356
+
357
+ for (const dep of dependencies) {
358
+ let resolvedDep;
371
359
 
372
360
  try {
373
- return [
374
- relativePath,
375
- {
376
- absolutePath: options.resolve(parentPath, relativePath),
377
- data: result,
378
- },
379
- ];
361
+ resolvedDep = {
362
+ absolutePath: options.resolve(parentPath, dep.name),
363
+ data: dep,
364
+ };
380
365
  } catch (error) {
381
366
  // Ignore unavailable optional dependencies. They are guarded
382
367
  // with a try-catch block and will be handled during runtime.
383
- if (result.data.isOptional !== true) {
368
+ if (dep.data.isOptional !== true) {
384
369
  throw error;
385
370
  }
386
371
  }
387
372
 
388
- return undefined;
389
- };
373
+ const key = dep.data.key;
390
374
 
391
- const resolved = dependencies.reduce((list, result) => {
392
- const resolvedPath = resolve(parentPath, result);
375
+ if (maybeResolvedDeps.has(key)) {
376
+ throw new Error(
377
+ `resolveDependencies: Found duplicate dependency key '${key}' in ${parentPath}`
378
+ );
379
+ }
380
+
381
+ maybeResolvedDeps.set(key, resolvedDep);
382
+ }
393
383
 
394
- if (resolvedPath) {
395
- list.push(resolvedPath);
384
+ const resolvedDeps = new Map(); // Return just the dependencies we successfully resolved.
385
+ // FIXME: This has a bad bug affecting all dependencies *after* an unresolved
386
+ // optional dependency. We'll need to propagate the nulls all the way to the
387
+ // serializer and the require() runtime to keep the dependency map from being
388
+ // desynced from the contents of the module.
389
+
390
+ for (const [key, resolvedDep] of maybeResolvedDeps) {
391
+ if (resolvedDep) {
392
+ resolvedDeps.set(key, resolvedDep);
396
393
  }
394
+ }
397
395
 
398
- return list;
399
- }, []);
400
- return new Map(resolved);
396
+ return resolvedDeps;
401
397
  }
402
398
  /**
403
399
  * Re-traverse the dependency graph in DFS order to reorder the modules and
@@ -485,8 +481,8 @@ function markModuleInUse(module, graph) {
485
481
  // Called when the reference count of a module has reached 0.
486
482
 
487
483
  function releaseModule(module, graph, delta, options) {
488
- for (const [relativePath, dependency] of module.dependencies) {
489
- removeDependency(module, relativePath, dependency, graph, delta, options);
484
+ for (const [key, dependency] of module.dependencies) {
485
+ removeDependency(module, key, dependency, graph, delta, options);
490
486
  }
491
487
 
492
488
  graph.privateState.gc.color.set(module.path, "black");
@@ -295,8 +295,8 @@ async function processModule<T>(
295
295
  graph.dependencies.set(module.path, module);
296
296
 
297
297
  // Diff dependencies (1/2): remove dependencies that have changed or been removed.
298
- for (const [relativePath, prevDependency] of previousDependencies) {
299
- const curDependency = currentDependencies.get(relativePath);
298
+ for (const [key, prevDependency] of previousDependencies) {
299
+ const curDependency = currentDependencies.get(key);
300
300
  if (
301
301
  !curDependency ||
302
302
  curDependency.absolutePath !== prevDependency.absolutePath ||
@@ -304,21 +304,14 @@ async function processModule<T>(
304
304
  curDependency.data.data.asyncType !==
305
305
  prevDependency.data.data.asyncType)
306
306
  ) {
307
- removeDependency(
308
- module,
309
- relativePath,
310
- prevDependency,
311
- graph,
312
- delta,
313
- options,
314
- );
307
+ removeDependency(module, key, prevDependency, graph, delta, options);
315
308
  }
316
309
  }
317
310
 
318
311
  // Diff dependencies (2/2): add dependencies that have changed or been added.
319
312
  const promises = [];
320
- for (const [relativePath, curDependency] of currentDependencies) {
321
- const prevDependency = previousDependencies.get(relativePath);
313
+ for (const [key, curDependency] of currentDependencies) {
314
+ const prevDependency = previousDependencies.get(key);
322
315
  if (
323
316
  !prevDependency ||
324
317
  prevDependency.absolutePath !== curDependency.absolutePath ||
@@ -327,14 +320,7 @@ async function processModule<T>(
327
320
  curDependency.data.data.asyncType)
328
321
  ) {
329
322
  promises.push(
330
- addDependency(
331
- module,
332
- relativePath,
333
- curDependency,
334
- graph,
335
- delta,
336
- options,
337
- ),
323
+ addDependency(module, key, curDependency, graph, delta, options),
338
324
  );
339
325
  }
340
326
  }
@@ -361,7 +347,7 @@ async function processModule<T>(
361
347
 
362
348
  async function addDependency<T>(
363
349
  parentModule: Module<T>,
364
- relativePath: string,
350
+ key: string,
365
351
  dependency: Dependency,
366
352
  graph: Graph<T>,
367
353
  delta: Delta,
@@ -420,18 +406,18 @@ async function addDependency<T>(
420
406
  // This means the parent's dependencies can get desynced from
421
407
  // inverseDependencies and the other fields in the case of lazy edges.
422
408
  // Not an optimal representation :(
423
- parentModule.dependencies.set(relativePath, dependency);
409
+ parentModule.dependencies.set(key, dependency);
424
410
  }
425
411
 
426
412
  function removeDependency<T>(
427
413
  parentModule: Module<T>,
428
- relativePath: string,
414
+ key: string,
429
415
  dependency: Dependency,
430
416
  graph: Graph<T>,
431
417
  delta: Delta,
432
418
  options: InternalOptions<T>,
433
419
  ): void {
434
- parentModule.dependencies.delete(relativePath);
420
+ parentModule.dependencies.delete(key);
435
421
 
436
422
  const {absolutePath} = dependency;
437
423
 
@@ -466,37 +452,42 @@ function resolveDependencies<T>(
466
452
  dependencies: $ReadOnlyArray<TransformResultDependency>,
467
453
  options: InternalOptions<T>,
468
454
  ): Map<string, Dependency> {
469
- const resolve = (parentPath: string, result: TransformResultDependency) => {
470
- const relativePath = result.name;
455
+ const maybeResolvedDeps = new Map();
456
+ for (const dep of dependencies) {
457
+ let resolvedDep;
471
458
  try {
472
- return [
473
- relativePath,
474
- {
475
- absolutePath: options.resolve(parentPath, relativePath),
476
- data: result,
477
- },
478
- ];
459
+ resolvedDep = {
460
+ absolutePath: options.resolve(parentPath, dep.name),
461
+ data: dep,
462
+ };
479
463
  } catch (error) {
480
464
  // Ignore unavailable optional dependencies. They are guarded
481
465
  // with a try-catch block and will be handled during runtime.
482
- if (result.data.isOptional !== true) {
466
+ if (dep.data.isOptional !== true) {
483
467
  throw error;
484
468
  }
485
469
  }
486
- return undefined;
487
- };
470
+ const key = dep.data.key;
471
+ if (maybeResolvedDeps.has(key)) {
472
+ throw new Error(
473
+ `resolveDependencies: Found duplicate dependency key '${key}' in ${parentPath}`,
474
+ );
475
+ }
476
+ maybeResolvedDeps.set(key, resolvedDep);
477
+ }
488
478
 
489
- const resolved = dependencies.reduce(
490
- (list: Array<[string, Dependency]>, result: TransformResultDependency) => {
491
- const resolvedPath = resolve(parentPath, result);
492
- if (resolvedPath) {
493
- list.push(resolvedPath);
494
- }
495
- return list;
496
- },
497
- [],
498
- );
499
- return new Map(resolved);
479
+ const resolvedDeps = new Map();
480
+ // Return just the dependencies we successfully resolved.
481
+ // FIXME: This has a bad bug affecting all dependencies *after* an unresolved
482
+ // optional dependency. We'll need to propagate the nulls all the way to the
483
+ // serializer and the require() runtime to keep the dependency map from being
484
+ // desynced from the contents of the module.
485
+ for (const [key, resolvedDep] of maybeResolvedDeps) {
486
+ if (resolvedDep) {
487
+ resolvedDeps.set(key, resolvedDep);
488
+ }
489
+ }
490
+ return resolvedDeps;
500
491
  }
501
492
 
502
493
  /**
@@ -604,8 +595,8 @@ function releaseModule<T>(
604
595
  delta: Delta,
605
596
  options: InternalOptions<T>,
606
597
  ) {
607
- for (const [relativePath, dependency] of module.dependencies) {
608
- removeDependency(module, relativePath, dependency, graph, delta, options);
598
+ for (const [key, dependency] of module.dependencies) {
599
+ removeDependency(module, key, dependency, graph, delta, options);
609
600
  }
610
601
  graph.privateState.gc.color.set(module.path, 'black');
611
602
  if (!graph.privateState.gc.possibleCycleRoots.has(module.path)) {
@@ -31,10 +31,13 @@ export type TransformResultDependency = {
31
31
  +name: string,
32
32
 
33
33
  /**
34
- * Extra data returned by the dependency extractor. Whatever is added here is
35
- * blindly piped by Metro to the serializers.
34
+ * Extra data returned by the dependency extractor.
36
35
  */
37
36
  +data: {
37
+ /**
38
+ * A locally unique key for this dependency within the current module.
39
+ */
40
+ +key: string,
38
41
  /**
39
42
  * If not null, this dependency is due to a dynamic `import()` or `__prefetchImport()` call.
40
43
  */
@@ -47,7 +47,13 @@ const NODE_MODULES = path.sep + "node_modules" + path.sep;
47
47
 
48
48
  const isNodeModules = (file) => file.includes(NODE_MODULES); // This function maps the ModuleGraph data structure to metro-file-map's ModuleMap
49
49
 
50
- const createModuleMap = ({ files, moduleCache, sourceExts, platforms }) => {
50
+ const createModuleMap = ({
51
+ files,
52
+ moduleCache,
53
+ sourceExts,
54
+ additionalExts,
55
+ platforms,
56
+ }) => {
51
57
  const platformSet = new Set(
52
58
  (platforms !== null && platforms !== void 0
53
59
  ? platforms
@@ -62,11 +68,12 @@ const createModuleMap = ({ files, moduleCache, sourceExts, platforms }) => {
62
68
 
63
69
  let id;
64
70
  let module;
71
+ const fileExt = path.extname(filePath).substr(1);
65
72
 
66
73
  if (filePath.endsWith(PACKAGE_JSON)) {
67
74
  module = moduleCache.getPackage(filePath);
68
75
  id = module.data.name;
69
- } else if (sourceExts.indexOf(path.extname(filePath).substr(1)) !== -1) {
76
+ } else if (sourceExts.has(fileExt) || additionalExts.has(fileExt)) {
70
77
  module = moduleCache.getModule(filePath);
71
78
  id = module.name;
72
79
  }
@@ -107,6 +114,7 @@ exports.createResolveFn = function (options) {
107
114
  extraNodeModules,
108
115
  transformedFiles,
109
116
  sourceExts,
117
+ additionalExts,
110
118
  platform,
111
119
  platforms,
112
120
  } = options;
@@ -146,7 +154,8 @@ exports.createResolveFn = function (options) {
146
154
  map: createModuleMap({
147
155
  files,
148
156
  moduleCache,
149
- sourceExts,
157
+ sourceExts: new Set(sourceExts),
158
+ additionalExts: new Set(additionalExts),
150
159
  platforms,
151
160
  }),
152
161
  mocks: new Map(),
@@ -10,7 +10,7 @@
10
10
 
11
11
  import type {Moduleish} from '../../node-haste/DependencyGraph/ModuleResolution';
12
12
  import type {ResolveFn, TransformedCodeFile} from '../types.flow';
13
- import type {Extensions, Path} from './node-haste.flow';
13
+ import type {Path} from './node-haste.flow';
14
14
  import type {ModuleMapData, ModuleMapItem} from 'metro-file-map';
15
15
  import type {CustomResolver} from 'metro-resolver';
16
16
 
@@ -27,7 +27,19 @@ const defaults = require('metro-config/src/defaults/defaults');
27
27
  const path = require('path');
28
28
 
29
29
  type ResolveOptions = {
30
- assetExts: Extensions,
30
+ /**
31
+ * (Used by the resolver) The extensions tried (in order) to implicitly
32
+ * locate a source file.
33
+ */
34
+ sourceExts: $ReadOnlyArray<string>,
35
+
36
+ /**
37
+ * The additional extensions to include in the file map as source files that
38
+ * can be explicitly imported.
39
+ */
40
+ additionalExts: $ReadOnlyArray<string>,
41
+
42
+ assetExts: $ReadOnlyArray<string>,
31
43
  assetResolutions: $ReadOnlyArray<string>,
32
44
  +disableHierarchicalLookup: boolean,
33
45
  +emptyModulePath: string,
@@ -37,7 +49,6 @@ type ResolveOptions = {
37
49
  +platform: string,
38
50
  platforms?: $ReadOnlyArray<string>,
39
51
  resolveRequest?: ?CustomResolver,
40
- +sourceExts: Extensions,
41
52
  transformedFiles: {[path: Path]: TransformedCodeFile, ...},
42
53
  };
43
54
 
@@ -63,12 +74,14 @@ const createModuleMap = ({
63
74
  files,
64
75
  moduleCache,
65
76
  sourceExts,
77
+ additionalExts,
66
78
  platforms,
67
79
  }: {
68
80
  files: Array<string>,
69
81
  moduleCache: ModuleCache,
82
+ sourceExts: $ReadOnlySet<string>,
83
+ additionalExts: $ReadOnlySet<string>,
70
84
  platforms: void | $ReadOnlyArray<string>,
71
- sourceExts: Extensions,
72
85
  }): ModuleMapData => {
73
86
  const platformSet = new Set(
74
87
  (platforms ?? defaults.platforms).concat([NATIVE_PLATFORM]),
@@ -82,10 +95,12 @@ const createModuleMap = ({
82
95
  }
83
96
  let id;
84
97
  let module;
98
+ const fileExt = path.extname(filePath).substr(1);
99
+
85
100
  if (filePath.endsWith(PACKAGE_JSON)) {
86
101
  module = moduleCache.getPackage(filePath);
87
102
  id = module.data.name;
88
- } else if (sourceExts.indexOf(path.extname(filePath).substr(1)) !== -1) {
103
+ } else if (sourceExts.has(fileExt) || additionalExts.has(fileExt)) {
89
104
  module = moduleCache.getModule(filePath);
90
105
  id = module.name;
91
106
  }
@@ -128,6 +143,7 @@ exports.createResolveFn = function (options: ResolveOptions): ResolveFn {
128
143
  extraNodeModules,
129
144
  transformedFiles,
130
145
  sourceExts,
146
+ additionalExts,
131
147
  platform,
132
148
  platforms,
133
149
  } = options;
@@ -161,7 +177,13 @@ exports.createResolveFn = function (options: ResolveOptions): ResolveFn {
161
177
  moduleCache,
162
178
  moduleMap: new ModuleMap({
163
179
  duplicates: new Map(),
164
- map: createModuleMap({files, moduleCache, sourceExts, platforms}),
180
+ map: createModuleMap({
181
+ files,
182
+ moduleCache,
183
+ sourceExts: new Set(sourceExts),
184
+ additionalExts: new Set(additionalExts),
185
+ platforms,
186
+ }),
165
187
  mocks: new Map(),
166
188
  rootDir: '',
167
189
  }),
@@ -181,6 +181,7 @@ function inlineModuleIds(
181
181
  ? parseSync(code, babelConfig)
182
182
  : HermesParser.parse(code, {
183
183
  babel: true,
184
+ // $FlowFixMe[prop-missing]
184
185
  sourceType: babelConfig.sourceType,
185
186
  });
186
187
  const ast = nullthrows(
@@ -181,6 +181,7 @@ function inlineModuleIds(
181
181
  ? parseSync(code, babelConfig)
182
182
  : HermesParser.parse(code, {
183
183
  babel: true,
184
+ // $FlowFixMe[prop-missing]
184
185
  sourceType: babelConfig.sourceType,
185
186
  });
186
187
 
@@ -9,6 +9,8 @@
9
9
  */
10
10
  "use strict";
11
11
 
12
+ const crypto = require("crypto");
13
+
12
14
  const generate = require("@babel/generator").default;
13
15
 
14
16
  const template = require("@babel/template").default;
@@ -586,8 +588,9 @@ function createModuleNameLiteral(dependency) {
586
588
  }
587
589
  /**
588
590
  * Given an import qualifier, return a key used to register the dependency.
589
- * Generally this return the `ImportQualifier.name` property, but in the case
590
- * of `require.context` more attributes can be appended to distinguish various combinations that would otherwise conflict.
591
+ * Generally this return the `ImportQualifier.name` property, but more
592
+ * attributes can be appended to distinguish various combinations that would
593
+ * otherwise conflict.
591
594
  *
592
595
  * For example, the following case would have collision issues if they all utilized the `name` property:
593
596
  * ```
@@ -603,6 +606,12 @@ function createModuleNameLiteral(dependency) {
603
606
 
604
607
  function getKeyForDependency(qualifier) {
605
608
  let key = qualifier.name;
609
+ const { asyncType } = qualifier;
610
+
611
+ if (asyncType) {
612
+ key += ["", asyncType].join("\0");
613
+ }
614
+
606
615
  const { contextParams } = qualifier; // Add extra qualifiers when using `require.context` to prevent collisions.
607
616
 
608
617
  if (contextParams) {
@@ -616,7 +625,7 @@ function getKeyForDependency(qualifier) {
616
625
  String(contextParams.filter.pattern),
617
626
  String(contextParams.filter.flags),
618
627
  contextParams.mode, // Join together and append to the name:
619
- ].join("__");
628
+ ].join("\0");
620
629
  }
621
630
 
622
631
  return key;
@@ -636,6 +645,7 @@ class DefaultModuleDependencyRegistry {
636
645
  asyncType: qualifier.asyncType,
637
646
  locs: [],
638
647
  index: this._dependencies.size,
648
+ key: crypto.createHash("sha1").update(key).digest("base64"),
639
649
  };
640
650
 
641
651
  if (qualifier.optional) {
@@ -647,17 +657,16 @@ class DefaultModuleDependencyRegistry {
647
657
  }
648
658
 
649
659
  dependency = newDependency;
650
-
651
- this._dependencies.set(key, dependency);
652
660
  } else {
653
- const original = dependency;
654
- dependency = collapseDependencies(original, qualifier);
655
-
656
- if (original !== dependency) {
657
- this._dependencies.set(key, dependency);
661
+ if (dependency.isOptional && !qualifier.optional) {
662
+ // A previously optionally required dependency was required non-optionally.
663
+ // Mark it non optional for the whole module
664
+ dependency = { ...dependency, isOptional: false };
658
665
  }
659
666
  }
660
667
 
668
+ this._dependencies.set(key, dependency);
669
+
661
670
  return dependency;
662
671
  }
663
672
 
@@ -666,24 +675,4 @@ class DefaultModuleDependencyRegistry {
666
675
  }
667
676
  }
668
677
 
669
- function collapseDependencies(dependency, qualifier) {
670
- let collapsed = dependency; // A previously optionally required dependency was required non-optionaly.
671
- // Mark it non optional for the whole module
672
-
673
- if (collapsed.isOptional && !qualifier.optional) {
674
- collapsed = { ...dependency, isOptional: false };
675
- } // A previously asynchronously (or prefetch) required module was required synchronously.
676
- // Make the dependency sync.
677
-
678
- if (collapsed.asyncType != null && qualifier.asyncType == null) {
679
- collapsed = { ...dependency, asyncType: null };
680
- } // A prefetched dependency was required async in the module. Mark it as async.
681
-
682
- if (collapsed.asyncType === "prefetch" && qualifier.asyncType === "async") {
683
- collapsed = { ...dependency, asyncType: "async" };
684
- }
685
-
686
- return collapsed;
687
- }
688
-
689
678
  module.exports = collectDependencies;