metro 0.75.1 → 0.76.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 +23 -24
- package/src/Assets.js +2 -2
- package/src/Assets.js.flow +1 -1
- package/src/DeltaBundler/Graph.js +11 -28
- package/src/DeltaBundler/Graph.js.flow +7 -0
- package/src/DeltaBundler/Serializers/helpers/js.js +2 -7
- package/src/DeltaBundler/types.flow.js.flow +1 -7
- package/src/HmrServer.js +9 -32
- package/src/IncrementalBundler.js +5 -9
- package/src/ModuleGraph/worker/collectDependencies.js +53 -89
- package/src/ModuleGraph/worker/collectDependencies.js.flow +113 -141
- package/src/Server/symbolicate.js +1 -5
- package/src/Server.js +10 -53
- package/src/commands/dependencies.js +1 -5
- package/src/index.flow.js +1 -2
- package/src/integration_tests/basic_bundle/TestBigInt.js +0 -3
- package/src/integration_tests/basic_bundle/TestBigInt.js.flow +0 -3
- package/src/integration_tests/basic_bundle/require-resolveWeak/import-and-resolveWeak.js +28 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/import-and-resolveWeak.js.flow +33 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/multiple.js +20 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/multiple.js.flow +23 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/never-required.js +18 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/never-required.js.flow +21 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/require-and-resolveWeak.js +28 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/require-and-resolveWeak.js.flow +33 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/subdir/counter-module.js +19 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/subdir/counter-module.js.flow +18 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/subdir/throwing-module.js +13 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/subdir/throwing-module.js.flow +11 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/utils.js +1 -0
- package/src/integration_tests/basic_bundle/require-resolveWeak/utils.js.flow +14 -0
- package/src/lib/CountingSet.js +1 -5
- package/src/lib/RamBundleParser.js +0 -1
- package/src/lib/RamBundleParser.js.flow +0 -1
- package/src/lib/TerminalReporter.js +3 -17
- package/src/lib/contextModuleTemplates.js +1 -1
- package/src/lib/contextModuleTemplates.js.flow +1 -1
- package/src/lib/formatBundlingError.js +0 -3
- package/src/lib/formatBundlingError.js.flow +0 -3
- package/src/lib/getAppendScripts.js +0 -3
- package/src/lib/getAppendScripts.js.flow +0 -3
- package/src/lib/getGraphId.js +2 -11
- package/src/lib/getPrependedScripts.js +0 -1
- package/src/lib/getPrependedScripts.js.flow +0 -1
- package/src/lib/transformHelpers.js +14 -22
- package/src/lib/transformHelpers.js.flow +5 -8
- package/src/node-haste/DependencyGraph/ModuleResolution.js +4 -11
- package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +3 -5
- package/src/node-haste/DependencyGraph/createHasteMap.js +13 -38
- package/src/node-haste/DependencyGraph/createHasteMap.js.flow +2 -1
- package/src/node-haste/DependencyGraph.js +6 -17
- package/src/node-haste/DependencyGraph.js.flow +1 -5
- package/src/node-haste/Module.js +5 -3
- package/src/node-haste/Module.js.flow +2 -3
- package/src/node-haste/ModuleCache.js +1 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metro",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.76.0",
|
|
4
4
|
"description": "🚇 The JavaScript bundler for React Native.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": "src/cli.js",
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"@babel/template": "^7.0.0",
|
|
21
21
|
"@babel/traverse": "^7.20.0",
|
|
22
22
|
"@babel/types": "^7.20.0",
|
|
23
|
-
"absolute-path": "^0.0.0",
|
|
24
23
|
"accepts": "^1.3.7",
|
|
25
24
|
"async": "^3.2.2",
|
|
26
25
|
"chalk": "^4.0.0",
|
|
@@ -35,23 +34,23 @@
|
|
|
35
34
|
"invariant": "^2.2.4",
|
|
36
35
|
"jest-worker": "^27.2.0",
|
|
37
36
|
"lodash.throttle": "^4.1.1",
|
|
38
|
-
"metro-babel-transformer": "0.
|
|
39
|
-
"metro-cache": "0.
|
|
40
|
-
"metro-cache-key": "0.
|
|
41
|
-
"metro-config": "0.
|
|
42
|
-
"metro-core": "0.
|
|
43
|
-
"metro-file-map": "0.
|
|
44
|
-
"metro-hermes-compiler": "0.
|
|
45
|
-
"metro-inspector-proxy": "0.
|
|
46
|
-
"metro-minify-terser": "0.
|
|
47
|
-
"metro-minify-uglify": "0.
|
|
48
|
-
"metro-react-native-babel-preset": "0.
|
|
49
|
-
"metro-resolver": "0.
|
|
50
|
-
"metro-runtime": "0.
|
|
51
|
-
"metro-source-map": "0.
|
|
52
|
-
"metro-symbolicate": "0.
|
|
53
|
-
"metro-transform-plugins": "0.
|
|
54
|
-
"metro-transform-worker": "0.
|
|
37
|
+
"metro-babel-transformer": "0.76.0",
|
|
38
|
+
"metro-cache": "0.76.0",
|
|
39
|
+
"metro-cache-key": "0.76.0",
|
|
40
|
+
"metro-config": "0.76.0",
|
|
41
|
+
"metro-core": "0.76.0",
|
|
42
|
+
"metro-file-map": "0.76.0",
|
|
43
|
+
"metro-hermes-compiler": "0.76.0",
|
|
44
|
+
"metro-inspector-proxy": "0.76.0",
|
|
45
|
+
"metro-minify-terser": "0.76.0",
|
|
46
|
+
"metro-minify-uglify": "0.76.0",
|
|
47
|
+
"metro-react-native-babel-preset": "0.76.0",
|
|
48
|
+
"metro-resolver": "0.76.0",
|
|
49
|
+
"metro-runtime": "0.76.0",
|
|
50
|
+
"metro-source-map": "0.76.0",
|
|
51
|
+
"metro-symbolicate": "0.76.0",
|
|
52
|
+
"metro-transform-plugins": "0.76.0",
|
|
53
|
+
"metro-transform-worker": "0.76.0",
|
|
55
54
|
"mime-types": "^2.1.27",
|
|
56
55
|
"node-fetch": "^2.2.0",
|
|
57
56
|
"nullthrows": "^1.1.1",
|
|
@@ -70,16 +69,16 @@
|
|
|
70
69
|
"dedent": "^0.7.0",
|
|
71
70
|
"jest-snapshot": "^26.5.2",
|
|
72
71
|
"jest-snapshot-serializer-raw": "^1.2.0",
|
|
73
|
-
"metro-babel-register": "0.
|
|
74
|
-
"metro-memory-fs": "0.
|
|
75
|
-
"metro-react-native-babel-preset": "0.
|
|
76
|
-
"metro-react-native-babel-transformer": "0.
|
|
72
|
+
"metro-babel-register": "0.76.0",
|
|
73
|
+
"metro-memory-fs": "0.76.0",
|
|
74
|
+
"metro-react-native-babel-preset": "0.76.0",
|
|
75
|
+
"metro-react-native-babel-transformer": "0.76.0",
|
|
77
76
|
"mock-req": "^0.2.0",
|
|
78
77
|
"mock-res": "^0.6.0",
|
|
79
78
|
"stack-trace": "^0.0.10"
|
|
80
79
|
},
|
|
81
80
|
"license": "MIT",
|
|
82
81
|
"engines": {
|
|
83
|
-
"node": ">=
|
|
82
|
+
"node": ">=16"
|
|
84
83
|
}
|
|
85
84
|
}
|
package/src/Assets.js
CHANGED
|
@@ -93,7 +93,7 @@ async function getAbsoluteAssetRecord(assetPath, platform = null) {
|
|
|
93
93
|
if (!record) {
|
|
94
94
|
throw new Error(
|
|
95
95
|
`Asset not found: ${assetPath} for platform: ${
|
|
96
|
-
platform
|
|
96
|
+
platform ?? "(unspecified)"
|
|
97
97
|
}`
|
|
98
98
|
);
|
|
99
99
|
}
|
|
@@ -134,7 +134,7 @@ async function getAssetData(
|
|
|
134
134
|
|
|
135
135
|
// On Windows, change backslashes to slashes to get proper URL path from file path.
|
|
136
136
|
if (path.sep === "\\") {
|
|
137
|
-
assetUrlPath = assetUrlPath.
|
|
137
|
+
assetUrlPath = assetUrlPath.replaceAll("\\", "/");
|
|
138
138
|
}
|
|
139
139
|
const isImage = isAssetTypeAnImage(path.extname(assetPath).slice(1));
|
|
140
140
|
const assetInfo = await getAbsoluteAssetInfo(assetPath, platform);
|
package/src/Assets.js.flow
CHANGED
|
@@ -200,7 +200,7 @@ async function getAssetData(
|
|
|
200
200
|
|
|
201
201
|
// On Windows, change backslashes to slashes to get proper URL path from file path.
|
|
202
202
|
if (path.sep === '\\') {
|
|
203
|
-
assetUrlPath = assetUrlPath.
|
|
203
|
+
assetUrlPath = assetUrlPath.replaceAll('\\', '/');
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
const isImage = isAssetTypeAnImage(path.extname(assetPath).slice(1));
|
|
@@ -284,6 +284,8 @@ class Graph {
|
|
|
284
284
|
let module = this.dependencies.get(path);
|
|
285
285
|
if (options.shallow) {
|
|
286
286
|
// Don't add a node for the module if the graph is shallow (single-module).
|
|
287
|
+
} else if (dependency.data.data.asyncType === "weak") {
|
|
288
|
+
// Exclude weak dependencies from the bundle.
|
|
287
289
|
} else if (
|
|
288
290
|
options.experimentalImportBundleSupport &&
|
|
289
291
|
dependency.data.data.asyncType != null
|
|
@@ -332,6 +334,10 @@ class Graph {
|
|
|
332
334
|
_removeDependency(parentModule, key, dependency, delta, options) {
|
|
333
335
|
parentModule.dependencies.delete(key);
|
|
334
336
|
const { absolutePath } = dependency;
|
|
337
|
+
if (dependency.data.data.asyncType === "weak") {
|
|
338
|
+
// Weak dependencies are excluded from the bundle.
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
335
341
|
if (
|
|
336
342
|
options.experimentalImportBundleSupport &&
|
|
337
343
|
dependency.data.data.asyncType != null
|
|
@@ -376,26 +382,8 @@ class Graph {
|
|
|
376
382
|
* traverseDependencies. Note that the list may contain duplicates.
|
|
377
383
|
*/
|
|
378
384
|
*getModifiedModulesForDeletedPath(filePath) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
_this$importBundleNod,
|
|
382
|
-
_this$importBundleNod2;
|
|
383
|
-
yield* (_this$dependencies$ge =
|
|
384
|
-
(_this$dependencies$ge2 = this.dependencies.get(filePath)) === null ||
|
|
385
|
-
_this$dependencies$ge2 === void 0
|
|
386
|
-
? void 0
|
|
387
|
-
: _this$dependencies$ge2.inverseDependencies) !== null &&
|
|
388
|
-
_this$dependencies$ge !== void 0
|
|
389
|
-
? _this$dependencies$ge
|
|
390
|
-
: [];
|
|
391
|
-
yield* (_this$importBundleNod =
|
|
392
|
-
(_this$importBundleNod2 = this.#importBundleNodes.get(filePath)) ===
|
|
393
|
-
null || _this$importBundleNod2 === void 0
|
|
394
|
-
? void 0
|
|
395
|
-
: _this$importBundleNod2.inverseDependencies) !== null &&
|
|
396
|
-
_this$importBundleNod !== void 0
|
|
397
|
-
? _this$importBundleNod
|
|
398
|
-
: [];
|
|
385
|
+
yield* this.dependencies.get(filePath)?.inverseDependencies ?? [];
|
|
386
|
+
yield* this.#importBundleNodes.get(filePath)?.inverseDependencies ?? [];
|
|
399
387
|
}
|
|
400
388
|
_resolveDependencies(parentPath, dependencies, options) {
|
|
401
389
|
const maybeResolvedDeps = new Map();
|
|
@@ -511,15 +499,10 @@ class Graph {
|
|
|
511
499
|
|
|
512
500
|
// Add an entry to importBundleNodes (or record an inverse dependency of an existing one)
|
|
513
501
|
_incrementImportBundleReference(dependency, parentModule) {
|
|
514
|
-
var _this$importBundleNod3;
|
|
515
502
|
const { absolutePath } = dependency;
|
|
516
|
-
const importBundleNode =
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
? _this$importBundleNod3
|
|
520
|
-
: {
|
|
521
|
-
inverseDependencies: new _CountingSet.default(),
|
|
522
|
-
};
|
|
503
|
+
const importBundleNode = this.#importBundleNodes.get(absolutePath) ?? {
|
|
504
|
+
inverseDependencies: new _CountingSet.default(),
|
|
505
|
+
};
|
|
523
506
|
importBundleNode.inverseDependencies.add(parentModule.path);
|
|
524
507
|
this.#importBundleNodes.set(absolutePath, importBundleNode);
|
|
525
508
|
}
|
|
@@ -355,6 +355,8 @@ export class Graph<T = MixedOutput> {
|
|
|
355
355
|
|
|
356
356
|
if (options.shallow) {
|
|
357
357
|
// Don't add a node for the module if the graph is shallow (single-module).
|
|
358
|
+
} else if (dependency.data.data.asyncType === 'weak') {
|
|
359
|
+
// Exclude weak dependencies from the bundle.
|
|
358
360
|
} else if (
|
|
359
361
|
options.experimentalImportBundleSupport &&
|
|
360
362
|
dependency.data.data.asyncType != null
|
|
@@ -414,6 +416,11 @@ export class Graph<T = MixedOutput> {
|
|
|
414
416
|
|
|
415
417
|
const {absolutePath} = dependency;
|
|
416
418
|
|
|
419
|
+
if (dependency.data.data.asyncType === 'weak') {
|
|
420
|
+
// Weak dependencies are excluded from the bundle.
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
|
|
417
424
|
if (
|
|
418
425
|
options.experimentalImportBundleSupport &&
|
|
419
426
|
dependency.data.data.asyncType != null
|
|
@@ -63,23 +63,18 @@ function getModuleParams(module, options) {
|
|
|
63
63
|
return params;
|
|
64
64
|
}
|
|
65
65
|
function getJsOutput(module) {
|
|
66
|
-
var _module$path, _module$path2;
|
|
67
66
|
const jsModules = module.output.filter(({ type }) => type.startsWith("js/"));
|
|
68
67
|
invariant(
|
|
69
68
|
jsModules.length === 1,
|
|
70
69
|
`Modules must have exactly one JS output, but ${
|
|
71
|
-
|
|
72
|
-
? _module$path
|
|
73
|
-
: "unknown module"
|
|
70
|
+
module.path ?? "unknown module"
|
|
74
71
|
} has ${jsModules.length} JS outputs.`
|
|
75
72
|
);
|
|
76
73
|
const jsOutput = jsModules[0];
|
|
77
74
|
invariant(
|
|
78
75
|
Number.isFinite(jsOutput.data.lineCount),
|
|
79
76
|
`JS output must populate lineCount, but ${
|
|
80
|
-
|
|
81
|
-
? _module$path2
|
|
82
|
-
: "unknown module"
|
|
77
|
+
module.path ?? "unknown module"
|
|
83
78
|
} has ${jsOutput.type} output with lineCount '${jsOutput.data.lineCount}'`
|
|
84
79
|
);
|
|
85
80
|
return jsOutput;
|
|
@@ -23,7 +23,7 @@ export type MixedOutput = {
|
|
|
23
23
|
+type: string,
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
export type AsyncDependencyType = 'async' | 'prefetch';
|
|
26
|
+
export type AsyncDependencyType = 'async' | 'prefetch' | 'weak';
|
|
27
27
|
|
|
28
28
|
export type TransformResultDependency = {
|
|
29
29
|
/**
|
|
@@ -44,12 +44,6 @@ export type TransformResultDependency = {
|
|
|
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
|
-
* The condition for splitting on this dependency edge.
|
|
49
|
-
*/
|
|
50
|
-
+splitCondition?: {
|
|
51
|
-
+mobileConfigName: string,
|
|
52
|
-
},
|
|
53
47
|
/**
|
|
54
48
|
* The dependency is enclosed in a try/catch block.
|
|
55
49
|
*/
|
package/src/HmrServer.js
CHANGED
|
@@ -56,7 +56,6 @@ class HmrServer {
|
|
|
56
56
|
};
|
|
57
57
|
};
|
|
58
58
|
async _registerEntryPoint(client, requestUrl, sendFn) {
|
|
59
|
-
var _this$_config$server$;
|
|
60
59
|
requestUrl = this._config.server.rewriteRequestUrl(requestUrl);
|
|
61
60
|
const clientUrl = nullthrows(url.parse(requestUrl, true));
|
|
62
61
|
const options = parseOptionsFromUrl(
|
|
@@ -77,10 +76,8 @@ class HmrServer {
|
|
|
77
76
|
resolverOptions
|
|
78
77
|
);
|
|
79
78
|
const resolvedEntryFilePath = resolutionFn(
|
|
80
|
-
(
|
|
81
|
-
|
|
82
|
-
? _this$_config$server$
|
|
83
|
-
: this._config.projectRoot) + "/.",
|
|
79
|
+
(this._config.server.unstable_serverRoot ?? this._config.projectRoot) +
|
|
80
|
+
"/.",
|
|
84
81
|
entryFile
|
|
85
82
|
).filePath;
|
|
86
83
|
const graphId = getGraphId(resolvedEntryFilePath, transformOptions, {
|
|
@@ -212,11 +209,7 @@ class HmrServer {
|
|
|
212
209
|
});
|
|
213
210
|
};
|
|
214
211
|
async _handleFileChange(group, options, changeEvent) {
|
|
215
|
-
const logger = !options.isInitialUpdate
|
|
216
|
-
? changeEvent === null || changeEvent === void 0
|
|
217
|
-
? void 0
|
|
218
|
-
: changeEvent.logger
|
|
219
|
-
: null;
|
|
212
|
+
const logger = !options.isInitialUpdate ? changeEvent?.logger : null;
|
|
220
213
|
if (logger) {
|
|
221
214
|
logger.point("fileChange_end");
|
|
222
215
|
logger.point("hmrPrepareAndSendMessage_start");
|
|
@@ -260,13 +253,8 @@ class HmrServer {
|
|
|
260
253
|
}
|
|
261
254
|
}
|
|
262
255
|
async _prepareMessage(group, options, changeEvent) {
|
|
263
|
-
const logger = !options.isInitialUpdate
|
|
264
|
-
? changeEvent === null || changeEvent === void 0
|
|
265
|
-
? void 0
|
|
266
|
-
: changeEvent.logger
|
|
267
|
-
: null;
|
|
256
|
+
const logger = !options.isInitialUpdate ? changeEvent?.logger : null;
|
|
268
257
|
try {
|
|
269
|
-
var _this$_config$server$2;
|
|
270
258
|
const revPromise = this._bundler.getRevision(group.revisionId);
|
|
271
259
|
if (!revPromise) {
|
|
272
260
|
return {
|
|
@@ -276,16 +264,12 @@ class HmrServer {
|
|
|
276
264
|
),
|
|
277
265
|
};
|
|
278
266
|
}
|
|
279
|
-
logger
|
|
280
|
-
? void 0
|
|
281
|
-
: logger.point("updateGraph_start");
|
|
267
|
+
logger?.point("updateGraph_start");
|
|
282
268
|
const { revision, delta } = await this._bundler.updateGraph(
|
|
283
269
|
await revPromise,
|
|
284
270
|
false
|
|
285
271
|
);
|
|
286
|
-
logger
|
|
287
|
-
? void 0
|
|
288
|
-
: logger.point("updateGraph_end");
|
|
272
|
+
logger?.point("updateGraph_end");
|
|
289
273
|
this._clientGroups.delete(group.revisionId);
|
|
290
274
|
group.revisionId = revision.id;
|
|
291
275
|
for (const client of group.clients) {
|
|
@@ -295,23 +279,16 @@ class HmrServer {
|
|
|
295
279
|
client.revisionIds.push(revision.id);
|
|
296
280
|
}
|
|
297
281
|
this._clientGroups.set(group.revisionId, group);
|
|
298
|
-
logger
|
|
299
|
-
? void 0
|
|
300
|
-
: logger.point("serialize_start");
|
|
282
|
+
logger?.point("serialize_start");
|
|
301
283
|
const hmrUpdate = hmrJSBundle(delta, revision.graph, {
|
|
302
284
|
clientUrl: group.clientUrl,
|
|
303
285
|
createModuleId: this._createModuleId,
|
|
304
286
|
includeAsyncPaths: this._config.server.experimentalImportBundleSupport,
|
|
305
287
|
projectRoot: this._config.projectRoot,
|
|
306
288
|
serverRoot:
|
|
307
|
-
|
|
308
|
-
null && _this$_config$server$2 !== void 0
|
|
309
|
-
? _this$_config$server$2
|
|
310
|
-
: this._config.projectRoot,
|
|
289
|
+
this._config.server.unstable_serverRoot ?? this._config.projectRoot,
|
|
311
290
|
});
|
|
312
|
-
logger
|
|
313
|
-
? void 0
|
|
314
|
-
: logger.point("serialize_end");
|
|
291
|
+
logger?.point("serialize_end");
|
|
315
292
|
return {
|
|
316
293
|
type: "update",
|
|
317
294
|
body: {
|
|
@@ -257,16 +257,12 @@ class IncrementalBundler {
|
|
|
257
257
|
this._revisionsById.delete(revision.id);
|
|
258
258
|
}
|
|
259
259
|
async _getAbsoluteEntryFiles(entryFiles) {
|
|
260
|
-
const absoluteEntryFiles = entryFiles.map((entryFile) =>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
(_this$_config$server$ = this._config.server.unstable_serverRoot) !==
|
|
264
|
-
null && _this$_config$server$ !== void 0
|
|
265
|
-
? _this$_config$server$
|
|
266
|
-
: this._config.projectRoot,
|
|
260
|
+
const absoluteEntryFiles = entryFiles.map((entryFile) =>
|
|
261
|
+
path.resolve(
|
|
262
|
+
this._config.server.unstable_serverRoot ?? this._config.projectRoot,
|
|
267
263
|
entryFile
|
|
268
|
-
)
|
|
269
|
-
|
|
264
|
+
)
|
|
265
|
+
);
|
|
270
266
|
await Promise.all(
|
|
271
267
|
absoluteEntryFiles.map(
|
|
272
268
|
(entryFile) =>
|
|
@@ -15,7 +15,6 @@ const generate = require("@babel/generator").default;
|
|
|
15
15
|
const template = require("@babel/template").default;
|
|
16
16
|
const traverse = require("@babel/traverse").default;
|
|
17
17
|
const types = require("@babel/types");
|
|
18
|
-
const invariant = require("invariant");
|
|
19
18
|
const nullthrows = require("nullthrows");
|
|
20
19
|
const { isImport } = types;
|
|
21
20
|
/**
|
|
@@ -28,21 +27,14 @@ const { isImport } = types;
|
|
|
28
27
|
* The second argument is only provided for debugging purposes.
|
|
29
28
|
*/
|
|
30
29
|
function collectDependencies(ast, options) {
|
|
31
|
-
var _options$dependencyRe, _options$dependencyTr;
|
|
32
30
|
const visited = new WeakSet();
|
|
33
31
|
const state = {
|
|
34
32
|
asyncRequireModulePathStringLiteral: null,
|
|
35
33
|
dependencyCalls: new Set(),
|
|
36
34
|
dependencyRegistry:
|
|
37
|
-
|
|
38
|
-
_options$dependencyRe !== void 0
|
|
39
|
-
? _options$dependencyRe
|
|
40
|
-
: new DefaultModuleDependencyRegistry(),
|
|
35
|
+
options.dependencyRegistry ?? new DefaultModuleDependencyRegistry(),
|
|
41
36
|
dependencyTransformer:
|
|
42
|
-
|
|
43
|
-
_options$dependencyTr !== void 0
|
|
44
|
-
? _options$dependencyTr
|
|
45
|
-
: DefaultDependencyTransformer,
|
|
37
|
+
options.dependencyTransformer ?? DefaultDependencyTransformer,
|
|
46
38
|
dependencyMapIdentifier: null,
|
|
47
39
|
dynamicRequires: options.dynamicRequires,
|
|
48
40
|
keepRequireNames: options.keepRequireNames,
|
|
@@ -68,26 +60,6 @@ function collectDependencies(ast, options) {
|
|
|
68
60
|
});
|
|
69
61
|
return;
|
|
70
62
|
}
|
|
71
|
-
if (name === "__jsResource" && !path.scope.getBinding(name)) {
|
|
72
|
-
processImportCall(path, state, {
|
|
73
|
-
asyncType: "async",
|
|
74
|
-
jsResource: true,
|
|
75
|
-
});
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (
|
|
79
|
-
name === "__conditionallySplitJSResource" &&
|
|
80
|
-
!path.scope.getBinding(name)
|
|
81
|
-
) {
|
|
82
|
-
const args = path.get("arguments");
|
|
83
|
-
invariant(Array.isArray(args), "Expected arguments to be an array");
|
|
84
|
-
processImportCall(path, state, {
|
|
85
|
-
asyncType: "async",
|
|
86
|
-
jsResource: true,
|
|
87
|
-
splitCondition: args[1],
|
|
88
|
-
});
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
63
|
|
|
92
64
|
// Match `require.context`
|
|
93
65
|
if (
|
|
@@ -108,6 +80,24 @@ function collectDependencies(ast, options) {
|
|
|
108
80
|
visited.add(path.node);
|
|
109
81
|
return;
|
|
110
82
|
}
|
|
83
|
+
|
|
84
|
+
// Match `require.resolveWeak`
|
|
85
|
+
if (
|
|
86
|
+
callee.type === "MemberExpression" &&
|
|
87
|
+
// `require`
|
|
88
|
+
callee.object.type === "Identifier" &&
|
|
89
|
+
callee.object.name === "require" &&
|
|
90
|
+
// `resolveWeak`
|
|
91
|
+
callee.property.type === "Identifier" &&
|
|
92
|
+
callee.property.name === "resolveWeak" &&
|
|
93
|
+
!callee.computed &&
|
|
94
|
+
// Ensure `require` refers to the global and not something else.
|
|
95
|
+
!path.scope.getBinding("require")
|
|
96
|
+
) {
|
|
97
|
+
processResolveWeakCall(path, state);
|
|
98
|
+
visited.add(path.node);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
111
101
|
if (
|
|
112
102
|
name != null &&
|
|
113
103
|
state.dependencyCalls.has(name) &&
|
|
@@ -163,11 +153,8 @@ function getRequireContextArgs(path) {
|
|
|
163
153
|
if (result.confident && typeof result.value === "string") {
|
|
164
154
|
directory = result.value;
|
|
165
155
|
} else {
|
|
166
|
-
var _result$deopt;
|
|
167
156
|
throw new InvalidRequireCallError(
|
|
168
|
-
|
|
169
|
-
? _result$deopt
|
|
170
|
-
: args[0],
|
|
157
|
+
result.deopt ?? args[0],
|
|
171
158
|
"First argument of `require.context` should be a string denoting the directory to require."
|
|
172
159
|
);
|
|
173
160
|
}
|
|
@@ -180,11 +167,8 @@ function getRequireContextArgs(path) {
|
|
|
180
167
|
if (result.confident && typeof result.value === "boolean") {
|
|
181
168
|
recursive = result.value;
|
|
182
169
|
} else if (!(result.confident && typeof result.value === "undefined")) {
|
|
183
|
-
var _result$deopt2;
|
|
184
170
|
throw new InvalidRequireCallError(
|
|
185
|
-
|
|
186
|
-
? _result$deopt2
|
|
187
|
-
: args[1],
|
|
171
|
+
result.deopt ?? args[1],
|
|
188
172
|
"Second argument of `require.context` should be an optional boolean indicating if files should be imported recursively or not."
|
|
189
173
|
);
|
|
190
174
|
}
|
|
@@ -221,11 +205,8 @@ function getRequireContextArgs(path) {
|
|
|
221
205
|
if (result.confident && typeof result.value === "string") {
|
|
222
206
|
mode = getContextMode(args[3], result.value);
|
|
223
207
|
} else if (!(result.confident && typeof result.value === "undefined")) {
|
|
224
|
-
var _result$deopt3;
|
|
225
208
|
throw new InvalidRequireCallError(
|
|
226
|
-
|
|
227
|
-
? _result$deopt3
|
|
228
|
-
: args[3],
|
|
209
|
+
result.deopt ?? args[3],
|
|
229
210
|
'Fourth argument of `require.context` should be an optional string "mode" denoting how the modules will be resolved.'
|
|
230
211
|
);
|
|
231
212
|
}
|
|
@@ -279,6 +260,26 @@ function processRequireContextCall(path, state) {
|
|
|
279
260
|
path.get("callee").replaceWith(types.identifier("require"));
|
|
280
261
|
transformer.transformSyncRequire(path, dep, state);
|
|
281
262
|
}
|
|
263
|
+
function processResolveWeakCall(path, state) {
|
|
264
|
+
const name = getModuleNameFromCallArgs(path);
|
|
265
|
+
if (name == null) {
|
|
266
|
+
throw new InvalidRequireCallError(path);
|
|
267
|
+
}
|
|
268
|
+
const dependency = registerDependency(
|
|
269
|
+
state,
|
|
270
|
+
{
|
|
271
|
+
name,
|
|
272
|
+
asyncType: "weak",
|
|
273
|
+
optional: isOptionalDependency(name, path, state),
|
|
274
|
+
},
|
|
275
|
+
path
|
|
276
|
+
);
|
|
277
|
+
path.replaceWith(
|
|
278
|
+
makeResolveWeakTemplate({
|
|
279
|
+
MODULE_ID: createModuleIDExpression(dependency, state),
|
|
280
|
+
})
|
|
281
|
+
);
|
|
282
|
+
}
|
|
282
283
|
function collectImports(path, state) {
|
|
283
284
|
if (path.node.source) {
|
|
284
285
|
registerDependency(
|
|
@@ -302,15 +303,12 @@ function processImportCall(path, state, options) {
|
|
|
302
303
|
{
|
|
303
304
|
name,
|
|
304
305
|
asyncType: options.asyncType,
|
|
305
|
-
splitCondition: options.splitCondition,
|
|
306
306
|
optional: isOptionalDependency(name, path, state),
|
|
307
307
|
},
|
|
308
308
|
path
|
|
309
309
|
);
|
|
310
310
|
const transformer = state.dependencyTransformer;
|
|
311
|
-
if (options.
|
|
312
|
-
transformer.transformJSResource(path, dep, state);
|
|
313
|
-
} else if (options.asyncType === "async") {
|
|
311
|
+
if (options.asyncType === "async") {
|
|
314
312
|
transformer.transformImportCall(path, dep, state);
|
|
315
313
|
} else {
|
|
316
314
|
transformer.transformPrefetch(path, dep, state);
|
|
@@ -338,14 +336,11 @@ function processRequireCall(path, state) {
|
|
|
338
336
|
transformer.transformSyncRequire(path, dep, state);
|
|
339
337
|
}
|
|
340
338
|
function getNearestLocFromPath(path) {
|
|
341
|
-
var _current;
|
|
342
339
|
let current = path;
|
|
343
340
|
while (current && !current.node.loc) {
|
|
344
341
|
current = current.parentPath;
|
|
345
342
|
}
|
|
346
|
-
return
|
|
347
|
-
? void 0
|
|
348
|
-
: _current.node.loc;
|
|
343
|
+
return current?.node.loc;
|
|
349
344
|
}
|
|
350
345
|
function registerDependency(state, qualifier, path) {
|
|
351
346
|
const dependency = state.dependencyRegistry.registerDependency(qualifier);
|
|
@@ -356,17 +351,10 @@ function registerDependency(state, qualifier, path) {
|
|
|
356
351
|
return dependency;
|
|
357
352
|
}
|
|
358
353
|
function isOptionalDependency(name, path, state) {
|
|
359
|
-
var _state$asyncRequireMo;
|
|
360
354
|
const { allowOptionalDependencies } = state;
|
|
361
355
|
|
|
362
356
|
// The async require module is a 'built-in'. Resolving should never fail -> treat it as non-optional.
|
|
363
|
-
if (
|
|
364
|
-
name ===
|
|
365
|
-
((_state$asyncRequireMo = state.asyncRequireModulePathStringLiteral) ===
|
|
366
|
-
null || _state$asyncRequireMo === void 0
|
|
367
|
-
? void 0
|
|
368
|
-
: _state$asyncRequireMo.value)
|
|
369
|
-
) {
|
|
357
|
+
if (name === state.asyncRequireModulePathStringLiteral?.value) {
|
|
370
358
|
return false;
|
|
371
359
|
}
|
|
372
360
|
const isExcluded = () =>
|
|
@@ -397,10 +385,8 @@ function isOptionalDependency(name, path, state) {
|
|
|
397
385
|
return false;
|
|
398
386
|
}
|
|
399
387
|
function getModuleNameFromCallArgs(path) {
|
|
400
|
-
const expectedCount =
|
|
401
|
-
path.node.callee.name === "__conditionallySplitJSResource" ? 2 : 1;
|
|
402
388
|
const args = path.get("arguments");
|
|
403
|
-
if (!Array.isArray(args) || args.length !==
|
|
389
|
+
if (!Array.isArray(args) || args.length !== 1) {
|
|
404
390
|
throw new InvalidRequireCallError(path);
|
|
405
391
|
}
|
|
406
392
|
const result = args[0].evaluate();
|
|
@@ -430,7 +416,7 @@ collectDependencies.InvalidRequireCallError = InvalidRequireCallError;
|
|
|
430
416
|
* is reached. This makes dynamic require errors catchable by libraries that
|
|
431
417
|
* want to use them.
|
|
432
418
|
*/
|
|
433
|
-
const dynamicRequireErrorTemplate = template.
|
|
419
|
+
const dynamicRequireErrorTemplate = template.expression(`
|
|
434
420
|
(function(line) {
|
|
435
421
|
throw new Error(
|
|
436
422
|
'Dynamic require defined at line ' + line + '; not supported by Metro',
|
|
@@ -442,14 +428,14 @@ const dynamicRequireErrorTemplate = template.statement(`
|
|
|
442
428
|
* Produces a Babel template that transforms an "import(...)" call into a
|
|
443
429
|
* "require(...)" call to the asyncRequire specified.
|
|
444
430
|
*/
|
|
445
|
-
const makeAsyncRequireTemplate = template.
|
|
431
|
+
const makeAsyncRequireTemplate = template.expression(`
|
|
446
432
|
require(ASYNC_REQUIRE_MODULE_PATH)(MODULE_ID, MODULE_NAME, DEPENDENCY_MAP.paths)
|
|
447
433
|
`);
|
|
448
|
-
const makeAsyncPrefetchTemplate = template.
|
|
434
|
+
const makeAsyncPrefetchTemplate = template.expression(`
|
|
449
435
|
require(ASYNC_REQUIRE_MODULE_PATH).prefetch(MODULE_ID, MODULE_NAME, DEPENDENCY_MAP.paths)
|
|
450
436
|
`);
|
|
451
|
-
const
|
|
452
|
-
|
|
437
|
+
const makeResolveWeakTemplate = template.expression(`
|
|
438
|
+
MODULE_ID
|
|
453
439
|
`);
|
|
454
440
|
const DefaultDependencyTransformer = {
|
|
455
441
|
transformSyncRequire(path, dependency, state) {
|
|
@@ -472,18 +458,6 @@ const DefaultDependencyTransformer = {
|
|
|
472
458
|
})
|
|
473
459
|
);
|
|
474
460
|
},
|
|
475
|
-
transformJSResource(path, dependency, state) {
|
|
476
|
-
path.replaceWith(
|
|
477
|
-
makeJSResourceTemplate({
|
|
478
|
-
ASYNC_REQUIRE_MODULE_PATH: nullthrows(
|
|
479
|
-
state.asyncRequireModulePathStringLiteral
|
|
480
|
-
),
|
|
481
|
-
MODULE_ID: createModuleIDExpression(dependency, state),
|
|
482
|
-
MODULE_NAME: createModuleNameLiteral(dependency),
|
|
483
|
-
DEPENDENCY_MAP: nullthrows(state.dependencyMapIdentifier),
|
|
484
|
-
})
|
|
485
|
-
);
|
|
486
|
-
},
|
|
487
461
|
transformPrefetch(path, dependency, state) {
|
|
488
462
|
path.replaceWith(
|
|
489
463
|
makeAsyncPrefetchTemplate({
|
|
@@ -497,19 +471,9 @@ const DefaultDependencyTransformer = {
|
|
|
497
471
|
);
|
|
498
472
|
},
|
|
499
473
|
transformIllegalDynamicRequire(path, state) {
|
|
500
|
-
var _path$node$loc$start$, _path$node$loc;
|
|
501
474
|
path.replaceWith(
|
|
502
475
|
dynamicRequireErrorTemplate({
|
|
503
|
-
LINE: types.numericLiteral(
|
|
504
|
-
(_path$node$loc$start$ =
|
|
505
|
-
(_path$node$loc = path.node.loc) === null ||
|
|
506
|
-
_path$node$loc === void 0
|
|
507
|
-
? void 0
|
|
508
|
-
: _path$node$loc.start.line) !== null &&
|
|
509
|
-
_path$node$loc$start$ !== void 0
|
|
510
|
-
? _path$node$loc$start$
|
|
511
|
-
: 0
|
|
512
|
-
),
|
|
476
|
+
LINE: types.numericLiteral(path.node.loc?.start.line ?? 0),
|
|
513
477
|
})
|
|
514
478
|
);
|
|
515
479
|
},
|