metro 0.71.3 → 0.72.2

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 (108) hide show
  1. package/package.json +23 -21
  2. package/src/Assets.js +3 -2
  3. package/src/Assets.js.flow +3 -2
  4. package/src/Bundler.js +11 -2
  5. package/src/Bundler.js.flow +7 -1
  6. package/src/DeltaBundler/DeltaCalculator.js +83 -21
  7. package/src/DeltaBundler/DeltaCalculator.js.flow +61 -8
  8. package/src/DeltaBundler/Serializers/baseBytecodeBundle.js +3 -2
  9. package/src/DeltaBundler/Serializers/baseBytecodeBundle.js.flow +2 -1
  10. package/src/DeltaBundler/Serializers/helpers/bytecode.js +2 -2
  11. package/src/DeltaBundler/Serializers/helpers/bytecode.js.flow +2 -1
  12. package/src/DeltaBundler/Serializers/hmrJSBundle.js.flow +1 -3
  13. package/src/DeltaBundler/Transformer.js +27 -4
  14. package/src/DeltaBundler/Transformer.js.flow +18 -2
  15. package/src/DeltaBundler/Worker.flow.js +45 -1
  16. package/src/DeltaBundler/Worker.flow.js.flow +42 -1
  17. package/src/DeltaBundler/WorkerFarm.js +3 -2
  18. package/src/DeltaBundler/WorkerFarm.js.flow +3 -1
  19. package/src/DeltaBundler/graphOperations.js +170 -63
  20. package/src/DeltaBundler/graphOperations.js.flow +144 -64
  21. package/src/DeltaBundler/types.flow.js.flow +11 -5
  22. package/src/DeltaBundler.js.flow +1 -1
  23. package/src/HmrServer.js +11 -5
  24. package/src/HmrServer.js.flow +11 -4
  25. package/src/IncrementalBundler.js +22 -4
  26. package/src/IncrementalBundler.js.flow +23 -4
  27. package/src/ModuleGraph/node-haste/HasteFS.js.flow +1 -1
  28. package/src/ModuleGraph/node-haste/Package.js.flow +5 -5
  29. package/src/ModuleGraph/node-haste/node-haste.js +19 -8
  30. package/src/ModuleGraph/node-haste/node-haste.js.flow +43 -16
  31. package/src/ModuleGraph/output/indexed-ram-bundle.js.flow +5 -13
  32. package/src/ModuleGraph/output/multiple-files-ram-bundle.js.flow +4 -14
  33. package/src/ModuleGraph/output/util.js +3 -4
  34. package/src/ModuleGraph/output/util.js.flow +3 -3
  35. package/src/ModuleGraph/types.flow.js.flow +28 -5
  36. package/src/ModuleGraph/worker/collectDependencies.js +19 -30
  37. package/src/ModuleGraph/worker/collectDependencies.js.flow +23 -41
  38. package/src/Server.js +90 -32
  39. package/src/Server.js.flow +143 -44
  40. package/src/cli-utils.js.flow +1 -1
  41. package/src/commands/build.js +1 -2
  42. package/src/commands/build.js.flow +6 -9
  43. package/src/commands/dependencies.js +1 -1
  44. package/src/commands/serve.js +2 -1
  45. package/src/commands/serve.js.flow +7 -8
  46. package/src/index.flow.js +27 -16
  47. package/src/index.flow.js.flow +24 -15
  48. package/src/integration_tests/basic_bundle/require-context/conflict.js +25 -0
  49. package/src/integration_tests/basic_bundle/require-context/conflict.js.flow +27 -0
  50. package/src/integration_tests/basic_bundle/require-context/empty.js +29 -0
  51. package/src/integration_tests/basic_bundle/require-context/empty.js.flow +26 -0
  52. package/src/integration_tests/basic_bundle/require-context/matching.js +26 -0
  53. package/src/integration_tests/basic_bundle/require-context/matching.js.flow +27 -0
  54. package/src/integration_tests/basic_bundle/require-context/mode-eager.js +22 -0
  55. package/src/integration_tests/basic_bundle/require-context/mode-eager.js.flow +24 -0
  56. package/src/integration_tests/basic_bundle/require-context/mode-lazy-once.js +22 -0
  57. package/src/integration_tests/basic_bundle/require-context/mode-lazy-once.js.flow +24 -0
  58. package/src/integration_tests/basic_bundle/require-context/mode-lazy.js +22 -0
  59. package/src/integration_tests/basic_bundle/require-context/mode-lazy.js.flow +24 -0
  60. package/src/integration_tests/basic_bundle/require-context/mode-sync.js +20 -0
  61. package/src/integration_tests/basic_bundle/require-context/mode-sync.js.flow +22 -0
  62. package/src/integration_tests/basic_bundle/require-context/subdir/a.js +12 -0
  63. package/src/integration_tests/basic_bundle/require-context/subdir/a.js.flow +11 -0
  64. package/src/integration_tests/basic_bundle/require-context/subdir/b.js +18 -0
  65. package/src/integration_tests/basic_bundle/require-context/subdir/b.js.flow +11 -0
  66. package/src/integration_tests/basic_bundle/require-context/subdir/c.js +12 -0
  67. package/src/integration_tests/basic_bundle/require-context/subdir/c.js.flow +11 -0
  68. package/src/integration_tests/basic_bundle/require-context/subdir/nested/d.js +12 -0
  69. package/src/integration_tests/basic_bundle/require-context/subdir/nested/d.js.flow +11 -0
  70. package/src/integration_tests/basic_bundle/require-context/subdir-conflict/index.js +12 -0
  71. package/src/integration_tests/basic_bundle/require-context/subdir-conflict/index.js.flow +11 -0
  72. package/src/integration_tests/basic_bundle/require-context/utils.js +29 -0
  73. package/src/integration_tests/basic_bundle/require-context/utils.js.flow +44 -0
  74. package/src/lib/CountingSet.js +1 -0
  75. package/src/lib/CountingSet.js.flow +1 -0
  76. package/src/lib/RamBundleParser.js +1 -0
  77. package/src/lib/RamBundleParser.js.flow +1 -0
  78. package/src/lib/bundleToBytecode.js +3 -2
  79. package/src/lib/bundleToBytecode.js.flow +2 -2
  80. package/src/lib/contextModule.js +80 -0
  81. package/src/lib/contextModule.js.flow +86 -0
  82. package/src/lib/contextModuleTemplates.js +186 -0
  83. package/src/lib/contextModuleTemplates.js.flow +148 -0
  84. package/src/lib/getGraphId.js +17 -3
  85. package/src/lib/getGraphId.js.flow +12 -9
  86. package/src/lib/getPrependedScripts.js +15 -5
  87. package/src/lib/getPrependedScripts.js.flow +8 -1
  88. package/src/lib/parseCustomResolverOptions.js +26 -0
  89. package/src/lib/parseCustomResolverOptions.js.flow +38 -0
  90. package/src/lib/parseOptionsFromUrl.js +3 -0
  91. package/src/lib/parseOptionsFromUrl.js.flow +9 -18
  92. package/src/lib/splitBundleOptions.js +3 -0
  93. package/src/lib/splitBundleOptions.js.flow +3 -0
  94. package/src/lib/transformHelpers.js +68 -22
  95. package/src/lib/transformHelpers.js.flow +73 -16
  96. package/src/node-haste/DependencyGraph/ModuleResolution.js +19 -2
  97. package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +8 -2
  98. package/src/node-haste/DependencyGraph/createHasteMap.js +7 -1
  99. package/src/node-haste/DependencyGraph/createHasteMap.js.flow +7 -1
  100. package/src/node-haste/DependencyGraph.js +39 -9
  101. package/src/node-haste/DependencyGraph.js.flow +63 -12
  102. package/src/node-haste/Module.js +1 -0
  103. package/src/node-haste/Module.js.flow +1 -0
  104. package/src/shared/output/bundle.flow.js +67 -0
  105. package/src/shared/output/bundle.flow.js.flow +89 -0
  106. package/src/shared/output/bundle.js +8 -55
  107. package/src/shared/output/bundle.js.flow +8 -75
  108. package/src/shared/types.flow.js.flow +7 -0
@@ -17,6 +17,7 @@ import type {
17
17
  TransformInputOptions,
18
18
  } from './DeltaBundler/types.flow';
19
19
  import type {GraphId} from './lib/getGraphId';
20
+ import type {ResolverInputOptions} from './shared/types.flow';
20
21
  import type {ConfigT} from 'metro-config/src/configTypes.flow';
21
22
 
22
23
  const Bundler = require('./Bundler');
@@ -33,10 +34,10 @@ export opaque type RevisionId: string = string;
33
34
 
34
35
  export type OutputGraph = Graph<>;
35
36
 
36
- type OtherOptions = {
37
- +onProgress: $PropertyType<DeltaBundlerOptions<>, 'onProgress'>,
38
- +shallow: boolean,
39
- };
37
+ type OtherOptions = $ReadOnly<{
38
+ onProgress: $PropertyType<DeltaBundlerOptions<>, 'onProgress'>,
39
+ shallow: boolean,
40
+ }>;
40
41
 
41
42
  export type GraphRevision = {
42
43
  // Identifies the last computed revision.
@@ -100,6 +101,7 @@ class IncrementalBundler {
100
101
  async buildGraphForEntries(
101
102
  entryFiles: $ReadOnlyArray<string>,
102
103
  transformOptions: TransformInputOptions,
104
+ resolverOptions: ResolverInputOptions,
103
105
  otherOptions?: OtherOptions = {
104
106
  onProgress: null,
105
107
  shallow: false,
@@ -111,6 +113,7 @@ class IncrementalBundler {
111
113
  resolve: await transformHelpers.getResolveDependencyFn(
112
114
  this._bundler,
113
115
  transformOptions.platform,
116
+ resolverOptions,
114
117
  ),
115
118
  transform: await transformHelpers.getTransformFn(
116
119
  absoluteEntryFiles,
@@ -118,11 +121,14 @@ class IncrementalBundler {
118
121
  this._deltaBundler,
119
122
  this._config,
120
123
  transformOptions,
124
+ resolverOptions,
121
125
  ),
122
126
  transformOptions,
123
127
  onProgress: otherOptions.onProgress,
124
128
  experimentalImportBundleSupport:
125
129
  this._config.transformer.experimentalImportBundleSupport,
130
+ unstable_allowRequireContext:
131
+ this._config.transformer.unstable_allowRequireContext,
126
132
  shallow: otherOptions.shallow,
127
133
  });
128
134
 
@@ -139,6 +145,7 @@ class IncrementalBundler {
139
145
  async getDependencies(
140
146
  entryFiles: $ReadOnlyArray<string>,
141
147
  transformOptions: TransformInputOptions,
148
+ resolverOptions: ResolverInputOptions,
142
149
  otherOptions?: OtherOptions = {
143
150
  onProgress: null,
144
151
  shallow: false,
@@ -152,6 +159,7 @@ class IncrementalBundler {
152
159
  resolve: await transformHelpers.getResolveDependencyFn(
153
160
  this._bundler,
154
161
  transformOptions.platform,
162
+ resolverOptions,
155
163
  ),
156
164
  transform: await transformHelpers.getTransformFn(
157
165
  absoluteEntryFiles,
@@ -159,11 +167,14 @@ class IncrementalBundler {
159
167
  this._deltaBundler,
160
168
  this._config,
161
169
  transformOptions,
170
+ resolverOptions,
162
171
  ),
163
172
  transformOptions,
164
173
  onProgress: otherOptions.onProgress,
165
174
  experimentalImportBundleSupport:
166
175
  this._config.transformer.experimentalImportBundleSupport,
176
+ unstable_allowRequireContext:
177
+ this._config.transformer.unstable_allowRequireContext,
167
178
  shallow: otherOptions.shallow,
168
179
  },
169
180
  );
@@ -174,6 +185,7 @@ class IncrementalBundler {
174
185
  async buildGraph(
175
186
  entryFile: string,
176
187
  transformOptions: TransformInputOptions,
188
+ resolverOptions: ResolverInputOptions,
177
189
  otherOptions?: OtherOptions = {
178
190
  onProgress: null,
179
191
  shallow: false,
@@ -182,6 +194,7 @@ class IncrementalBundler {
182
194
  const graph = await this.buildGraphForEntries(
183
195
  [entryFile],
184
196
  transformOptions,
197
+ resolverOptions,
185
198
  otherOptions,
186
199
  );
187
200
 
@@ -190,6 +203,7 @@ class IncrementalBundler {
190
203
  const prepend = await getPrependedScripts(
191
204
  this._config,
192
205
  transformOptionsWithoutType,
206
+ resolverOptions,
193
207
  this._bundler,
194
208
  this._deltaBundler,
195
209
  );
@@ -205,6 +219,7 @@ class IncrementalBundler {
205
219
  async initializeGraph(
206
220
  entryFile: string,
207
221
  transformOptions: TransformInputOptions,
222
+ resolverOptions: ResolverInputOptions,
208
223
  otherOptions?: OtherOptions = {
209
224
  onProgress: null,
210
225
  shallow: false,
@@ -215,15 +230,19 @@ class IncrementalBundler {
215
230
  ...
216
231
  }> {
217
232
  const graphId = getGraphId(entryFile, transformOptions, {
233
+ resolverOptions,
218
234
  shallow: otherOptions.shallow,
219
235
  experimentalImportBundleSupport:
220
236
  this._config.transformer.experimentalImportBundleSupport,
237
+ unstable_allowRequireContext:
238
+ this._config.transformer.unstable_allowRequireContext,
221
239
  });
222
240
  const revisionId = createRevisionId();
223
241
  const revisionPromise = (async () => {
224
242
  const {graph, prepend} = await this.buildGraph(
225
243
  entryFile,
226
244
  transformOptions,
245
+ resolverOptions,
227
246
  otherOptions,
228
247
  );
229
248
  return {
@@ -58,7 +58,7 @@ module.exports = class HasteFS {
58
58
  return Array.from<string>(this.files.keys());
59
59
  }
60
60
 
61
- matchFiles() {
61
+ matchFiles(): $FlowFixMeEmpty {
62
62
  throw new Error('HasteFS.matchFiles is not implemented yet.');
63
63
  }
64
64
 
@@ -10,7 +10,7 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- import type {PackageData} from '../types.flow';
13
+ import type {PackageData, Replacements} from '../types.flow';
14
14
 
15
15
  const nullthrows = require('nullthrows');
16
16
  const path = require('path');
@@ -57,7 +57,7 @@ module.exports = class Package {
57
57
  return !!this.data.name;
58
58
  }
59
59
 
60
- redirectRequire(name: string): any | boolean | string {
60
+ redirectRequire(name: string): string | false {
61
61
  // Copied from node-haste/Package.js
62
62
  const replacements = getReplacements(this.data);
63
63
 
@@ -104,7 +104,7 @@ function getMain(pkg: PackageData): string {
104
104
  }
105
105
 
106
106
  // Copied from node-haste/Package.js
107
- function getReplacements(pkg: PackageData) {
107
+ function getReplacements(pkg: PackageData): ?(string | Replacements) {
108
108
  let rn = pkg['react-native'];
109
109
  let browser = pkg.browser;
110
110
  if (rn == null) {
@@ -117,11 +117,11 @@ function getReplacements(pkg: PackageData) {
117
117
 
118
118
  const main = getMain(pkg);
119
119
  if (typeof rn !== 'object') {
120
- rn = {[main]: rn};
120
+ rn = ({[main]: rn}: Replacements);
121
121
  }
122
122
 
123
123
  if (typeof browser !== 'object') {
124
- browser = {[main]: browser};
124
+ browser = ({[main]: browser}: Replacements);
125
125
  }
126
126
 
127
127
  // merge with "browser" as default,
@@ -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;
@@ -139,14 +147,14 @@ exports.createResolveFn = function (options) {
139
147
  extraNodeModules,
140
148
  isAssetFile,
141
149
  mainFields: options.mainFields,
142
- // $FlowFixMe -- error revealed by types-first codemod
143
150
  moduleCache,
144
151
  moduleMap: new _metroFileMap.ModuleMap({
145
152
  duplicates: new Map(),
146
153
  map: createModuleMap({
147
154
  files,
148
155
  moduleCache,
149
- sourceExts,
156
+ sourceExts: new Set(sourceExts),
157
+ additionalExts: new Set(additionalExts),
150
158
  platforms,
151
159
  }),
152
160
  mocks: new Map(),
@@ -173,9 +181,12 @@ exports.createResolveFn = function (options) {
173
181
  sourcePath != null
174
182
  ? new Module(sourcePath, moduleCache, getTransformedFile(sourcePath))
175
183
  : NULL_MODULE;
176
- const allowHaste = !isNodeModules(from.path); // $FlowFixMe -- error revealed by types-first codemod
177
-
178
- return moduleResolver.resolveDependency(from, id, allowHaste, platform)
179
- .path;
184
+ return moduleResolver.resolveDependency(
185
+ from,
186
+ id,
187
+ true,
188
+ platform,
189
+ options.resolverOptions
190
+ ).path;
180
191
  };
181
192
  };
@@ -9,8 +9,9 @@
9
9
  */
10
10
 
11
11
  import type {Moduleish} from '../../node-haste/DependencyGraph/ModuleResolution';
12
+ import type {ResolverInputOptions} from '../../shared/types.flow';
12
13
  import type {ResolveFn, TransformedCodeFile} from '../types.flow';
13
- import type {Extensions, Path} from './node-haste.flow';
14
+ import type {Path} from './node-haste.flow';
14
15
  import type {ModuleMapData, ModuleMapItem} from 'metro-file-map';
15
16
  import type {CustomResolver} from 'metro-resolver';
16
17
 
@@ -26,20 +27,33 @@ const ModuleCache = require('./ModuleCache');
26
27
  const defaults = require('metro-config/src/defaults/defaults');
27
28
  const path = require('path');
28
29
 
29
- type ResolveOptions = {
30
- assetExts: Extensions,
30
+ type ResolveOptions = $ReadOnly<{
31
+ /**
32
+ * The additional extensions to include in the file map as source files that
33
+ * can be explicitly imported.
34
+ */
35
+ additionalExts: $ReadOnlyArray<string>,
36
+
37
+ assetExts: $ReadOnlyArray<string>,
31
38
  assetResolutions: $ReadOnlyArray<string>,
32
- +disableHierarchicalLookup: boolean,
33
- +emptyModulePath: string,
39
+ disableHierarchicalLookup: boolean,
40
+ emptyModulePath: string,
34
41
  extraNodeModules: {[id: string]: string, ...},
35
42
  mainFields: $ReadOnlyArray<string>,
36
43
  nodeModulesPaths: $ReadOnlyArray<string>,
37
- +platform: string,
44
+ platform: string,
38
45
  platforms?: $ReadOnlyArray<string>,
39
46
  resolveRequest?: ?CustomResolver,
40
- +sourceExts: Extensions,
47
+ resolverOptions: ResolverInputOptions,
48
+
49
+ /**
50
+ * (Used by the resolver) The extensions tried (in order) to implicitly
51
+ * locate a source file.
52
+ */
53
+ sourceExts: $ReadOnlyArray<string>,
54
+
41
55
  transformedFiles: {[path: Path]: TransformedCodeFile, ...},
42
- };
56
+ }>;
43
57
 
44
58
  const NATIVE_PLATFORM = 'native';
45
59
  const GENERIC_PLATFORM = 'g';
@@ -63,12 +77,14 @@ const createModuleMap = ({
63
77
  files,
64
78
  moduleCache,
65
79
  sourceExts,
80
+ additionalExts,
66
81
  platforms,
67
82
  }: {
68
83
  files: Array<string>,
69
84
  moduleCache: ModuleCache,
85
+ sourceExts: $ReadOnlySet<string>,
86
+ additionalExts: $ReadOnlySet<string>,
70
87
  platforms: void | $ReadOnlyArray<string>,
71
- sourceExts: Extensions,
72
88
  }): ModuleMapData => {
73
89
  const platformSet = new Set(
74
90
  (platforms ?? defaults.platforms).concat([NATIVE_PLATFORM]),
@@ -82,10 +98,12 @@ const createModuleMap = ({
82
98
  }
83
99
  let id;
84
100
  let module;
101
+ const fileExt = path.extname(filePath).substr(1);
102
+
85
103
  if (filePath.endsWith(PACKAGE_JSON)) {
86
104
  module = moduleCache.getPackage(filePath);
87
105
  id = module.data.name;
88
- } else if (sourceExts.indexOf(path.extname(filePath).substr(1)) !== -1) {
106
+ } else if (sourceExts.has(fileExt) || additionalExts.has(fileExt)) {
89
107
  module = moduleCache.getModule(filePath);
90
108
  id = module.name;
91
109
  }
@@ -128,6 +146,7 @@ exports.createResolveFn = function (options: ResolveOptions): ResolveFn {
128
146
  extraNodeModules,
129
147
  transformedFiles,
130
148
  sourceExts,
149
+ additionalExts,
131
150
  platform,
132
151
  platforms,
133
152
  } = options;
@@ -157,11 +176,16 @@ exports.createResolveFn = function (options: ResolveOptions): ResolveFn {
157
176
  extraNodeModules,
158
177
  isAssetFile,
159
178
  mainFields: options.mainFields,
160
- // $FlowFixMe -- error revealed by types-first codemod
161
179
  moduleCache,
162
180
  moduleMap: new ModuleMap({
163
181
  duplicates: new Map(),
164
- map: createModuleMap({files, moduleCache, sourceExts, platforms}),
182
+ map: createModuleMap({
183
+ files,
184
+ moduleCache,
185
+ sourceExts: new Set(sourceExts),
186
+ additionalExts: new Set(additionalExts),
187
+ platforms,
188
+ }),
165
189
  mocks: new Map(),
166
190
  rootDir: '',
167
191
  }),
@@ -191,9 +215,12 @@ exports.createResolveFn = function (options: ResolveOptions): ResolveFn {
191
215
  sourcePath != null
192
216
  ? new Module(sourcePath, moduleCache, getTransformedFile(sourcePath))
193
217
  : NULL_MODULE;
194
- const allowHaste = !isNodeModules(from.path);
195
- // $FlowFixMe -- error revealed by types-first codemod
196
- return moduleResolver.resolveDependency(from, id, allowHaste, platform)
197
- .path;
218
+ return moduleResolver.resolveDependency(
219
+ from,
220
+ id,
221
+ true,
222
+ platform,
223
+ options.resolverOptions,
224
+ ).path;
198
225
  };
199
226
  };
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  'use strict';
12
- import type {IdsForPathFn, Dependency} from '../types.flow';
12
+ import type {Dependency} from '../types.flow';
13
13
  import type {BasicSourceMap} from '../../../../metro-source-map/src/source-map';
14
14
 
15
15
  import type {Module, OutputFn, OutputFnArg} from '../types.flow';
@@ -33,18 +33,10 @@ function asIndexedRamBundle({
33
33
  preloadedModules,
34
34
  ramGroupHeads,
35
35
  requireCalls,
36
- }: $TEMPORARY$object<{
37
- dependencyMapReservedName?: ?string,
38
- enableIDInlining: boolean,
39
- filename: string,
40
- globalPrefix: string,
41
- idsForPath: IdsForPathFn,
42
- modules: Iterable<Module>,
43
- preloadedModules: Set<string>,
36
+ }: $ReadOnly<{
37
+ ...OutputFnArg,
38
+ preloadedModules: $ReadOnlySet<string>,
44
39
  ramGroupHeads: ?$ReadOnlyArray<string>,
45
- requireCalls: Iterable<Module>,
46
- segmentID: number,
47
- sourceMapPath?: ?string,
48
40
  }>): {
49
41
  code: string | Buffer,
50
42
  extraFiles?: Iterable<[string, string | Buffer]>,
@@ -137,7 +129,7 @@ function* subtree(
137
129
  }
138
130
 
139
131
  function createBuilder(
140
- preloadedModules: Set<string>,
132
+ preloadedModules: $ReadOnlySet<string>,
141
133
  ramGroupHeads: ?$ReadOnlyArray<string>,
142
134
  ): OutputFn<IndexMap> {
143
135
  return (x: OutputFnArg) =>
@@ -9,8 +9,6 @@
9
9
  */
10
10
 
11
11
  'use strict';
12
- import type {IdsForPathFn} from '../types.flow';
13
-
14
12
  import type {Module, OutputFn, OutputFnArg, OutputResult} from '../types.flow';
15
13
  import type {IndexMap} from 'metro-source-map';
16
14
 
@@ -30,18 +28,10 @@ function asMultipleFilesRamBundle({
30
28
  modules,
31
29
  requireCalls,
32
30
  preloadedModules,
33
- }: $TEMPORARY$object<{
34
- dependencyMapReservedName?: ?string,
35
- enableIDInlining: boolean,
36
- filename: string,
37
- globalPrefix: string,
38
- idsForPath: IdsForPathFn,
39
- modules: Iterable<Module>,
40
- preloadedModules: Set<string>,
31
+ }: $ReadOnly<{
32
+ ...OutputFnArg,
33
+ preloadedModules: $ReadOnlySet<string>,
41
34
  ramGroupHeads: ?$ReadOnlyArray<string>,
42
- requireCalls: Iterable<Module>,
43
- segmentID: number,
44
- sourceMapPath?: ?string,
45
35
  }>): OutputResult<IndexMap> {
46
36
  const idForPath = (x: {path: string, ...}) => idsForPath(x).moduleId;
47
37
  const [startup, deferred] = partition(modules, preloadedModules);
@@ -96,7 +86,7 @@ function asMultipleFilesRamBundle({
96
86
  }
97
87
 
98
88
  function createBuilder(
99
- preloadedModules: Set<string>,
89
+ preloadedModules: $ReadOnlySet<string>,
100
90
  ramGroupHeads: ?$ReadOnlyArray<string>,
101
91
  ): OutputFn<IndexMap> {
102
92
  return (x: OutputFnArg) =>
@@ -17,9 +17,7 @@ const mergeSourceMaps = require("../worker/mergeSourceMaps");
17
17
 
18
18
  const reverseDependencyMapReferences = require("./reverse-dependency-map-references");
19
19
 
20
- const { parseSync, transformFromAstSync } = require("@babel/core");
21
-
22
- const HermesParser = require("hermes-parser"); // flowlint-next-line untyped-import:off
20
+ const { parseSync, transformFromAstSync } = require("@babel/core"); // flowlint-next-line untyped-import:off
23
21
 
24
22
  const { passthroughSyntaxPlugins } = require("metro-react-native-babel-preset");
25
23
 
@@ -179,8 +177,9 @@ function inlineModuleIds(
179
177
  const sourceAst =
180
178
  isTypeScriptSource(path) || isTSXSource(path) || !hermesParser
181
179
  ? parseSync(code, babelConfig)
182
- : HermesParser.parse(code, {
180
+ : require("hermes-parser").parse(code, {
183
181
  babel: true,
182
+ // $FlowFixMe[prop-missing]
184
183
  sourceType: babelConfig.sourceType,
185
184
  });
186
185
  const ast = nullthrows(
@@ -18,7 +18,6 @@ const generate = require('../worker/generate');
18
18
  const mergeSourceMaps = require('../worker/mergeSourceMaps');
19
19
  const reverseDependencyMapReferences = require('./reverse-dependency-map-references');
20
20
  const {parseSync, transformFromAstSync} = require('@babel/core');
21
- const HermesParser = require('hermes-parser');
22
21
  // flowlint-next-line untyped-import:off
23
22
  const {passthroughSyntaxPlugins} = require('metro-react-native-babel-preset');
24
23
  const {addParamsToDefineCall} = require('metro-transform-plugins');
@@ -179,8 +178,9 @@ function inlineModuleIds(
179
178
  const sourceAst =
180
179
  isTypeScriptSource(path) || isTSXSource(path) || !hermesParser
181
180
  ? parseSync(code, babelConfig)
182
- : HermesParser.parse(code, {
181
+ : require('hermes-parser').parse(code, {
183
182
  babel: true,
183
+ // $FlowFixMe[prop-missing]
184
184
  sourceType: babelConfig.sourceType,
185
185
  });
186
186
 
@@ -317,7 +317,7 @@ exports.requireCallsTo = function* (
317
317
  // the ones loaded deferredly (lazy loaded).
318
318
  exports.partition = (
319
319
  modules: Iterable<Module>,
320
- preloadedModules: Set<string>,
320
+ preloadedModules: $ReadOnlySet<string>,
321
321
  ): Array<Array<Module>> => {
322
322
  const startup = [];
323
323
  const deferred = [];
@@ -117,11 +117,15 @@ export type OutputResult<M: MixedSourceMap> = {
117
117
  map: M,
118
118
  };
119
119
 
120
+ export type Replacements = $ReadOnly<{
121
+ [filename: string]: string | false,
122
+ }>;
123
+
120
124
  export type PackageData = {
121
- browser?: Object | string,
125
+ browser?: Replacements | string,
122
126
  main?: string,
123
127
  name?: string,
124
- 'react-native'?: Object | string,
128
+ 'react-native'?: Replacements | string,
125
129
  };
126
130
 
127
131
  export type ResolveFn = (id: string, source: ?string) => string;
@@ -259,14 +263,27 @@ export type AssetContentsByPath = {
259
263
  };
260
264
 
261
265
  export type ResolvedCodeFile = {
262
- +codeFile: TransformedCodeFile,
266
+ codeFile: TransformedCodeFile,
263
267
  /**
264
268
  * Imagine we have a source file that contains a `require('foo')`. The library
265
269
  * will resolve the path of the module `foo` and store it in this field along
266
270
  * all the other dependencies. For example, it could be
267
271
  * `{'foo': 'bar/foo.js', 'bar': 'node_modules/bar/index.js'}`.
268
272
  */
269
- +filePathsByDependencyName: {[dependencyName: string]: string, ...},
273
+ filePathsByDependencyName: {
274
+ [dependencyName: string]:
275
+ | string
276
+
277
+ // requireCond
278
+ | {
279
+ type: string,
280
+ condition: string,
281
+ modules: {
282
+ [string]: string | null,
283
+ },
284
+ },
285
+ ...
286
+ },
270
287
  };
271
288
 
272
289
  export type LibraryBoundCodeFile = {
@@ -294,8 +311,14 @@ export type Library = {
294
311
  * path it resolves to, ex. `beep/glo/foo.js`.
295
312
  */
296
313
  export type ResolvedLibrary = {
297
- +files: $ReadOnlyArray<ResolvedCodeFile>,
314
+ +files: $ReadOnlyArray<$DeepReadOnly<ResolvedCodeFile>>,
298
315
  /* cannot be a Map because it's JSONified later on */
299
316
  +assets: AssetContentsByPath,
300
317
  +isPartiallyResolved?: boolean,
301
318
  };
319
+
320
+ type DeepReadOnlyFn = (<T>(Array<T>) => $ReadOnlyArray<$DeepReadOnly<T>>) &
321
+ (<T: {}>(T) => $ReadOnly<$ObjMap<T, DeepReadOnlyFn>>) &
322
+ (<T>(T) => T);
323
+
324
+ type $DeepReadOnly<T> = $Call<DeepReadOnlyFn, T>;
@@ -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;