metro 0.70.3 → 0.71.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.
- package/package.json +23 -22
- package/src/Assets.js.flow +4 -4
- package/src/Bundler/util.js +1 -1
- package/src/Bundler/util.js.flow +2 -2
- package/src/Bundler.js +15 -10
- package/src/Bundler.js.flow +19 -14
- package/src/DeltaBundler/DeltaCalculator.js +13 -17
- package/src/DeltaBundler/DeltaCalculator.js.flow +15 -20
- package/src/DeltaBundler/Serializers/getAllFiles.js.flow +2 -2
- package/src/DeltaBundler/Serializers/getAssets.js.flow +2 -2
- package/src/DeltaBundler/Serializers/getExplodedSourceMap.js.flow +4 -4
- package/src/DeltaBundler/Serializers/getRamBundleInfo.js.flow +6 -6
- package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js.flow +4 -4
- package/src/DeltaBundler/Serializers/helpers/processBytecodeModules.js.flow +2 -2
- package/src/DeltaBundler/Serializers/helpers/processModules.js.flow +2 -2
- package/src/DeltaBundler/Serializers/hmrJSBundle.js.flow +2 -2
- package/src/DeltaBundler/Serializers/sourceMapGenerator.js.flow +6 -6
- package/src/DeltaBundler/Serializers/sourceMapObject.js.flow +4 -4
- package/src/DeltaBundler/Serializers/sourceMapString.js.flow +2 -2
- package/src/DeltaBundler/Worker.flow.js +78 -0
- package/src/DeltaBundler/Worker.flow.js.flow +121 -0
- package/src/DeltaBundler/Worker.js +8 -66
- package/src/DeltaBundler/Worker.js.flow +8 -107
- package/src/DeltaBundler/WorkerFarm.js.flow +4 -4
- package/src/DeltaBundler/__fixtures__/hasteImpl.js +4 -0
- package/src/DeltaBundler/getTransformCacheKey.js.flow +2 -2
- package/src/DeltaBundler/graphOperations.js +641 -0
- package/src/DeltaBundler/graphOperations.js.flow +752 -0
- package/src/DeltaBundler/types.flow.js +6 -0
- package/src/DeltaBundler/types.flow.js.flow +43 -31
- package/src/DeltaBundler.js +12 -6
- package/src/DeltaBundler.js.flow +14 -10
- package/src/HmrServer.js +0 -2
- package/src/HmrServer.js.flow +7 -8
- package/src/IncrementalBundler.js +1 -1
- package/src/IncrementalBundler.js.flow +8 -8
- package/src/ModuleGraph/node-haste/ModuleCache.js +1 -1
- package/src/ModuleGraph/node-haste/ModuleCache.js.flow +1 -1
- package/src/ModuleGraph/node-haste/node-haste.flow.js +0 -1
- package/src/ModuleGraph/node-haste/node-haste.flow.js.flow +3 -4
- package/src/ModuleGraph/node-haste/node-haste.js +4 -4
- package/src/ModuleGraph/node-haste/node-haste.js.flow +13 -7
- package/src/ModuleGraph/output/indexed-ram-bundle.js.flow +2 -2
- package/src/ModuleGraph/output/plain-bundle.js.flow +2 -2
- package/src/ModuleGraph/output/reverse-dependency-map-references.js.flow +8 -8
- package/src/ModuleGraph/output/util.js.flow +2 -2
- package/src/ModuleGraph/types.flow.js.flow +37 -37
- package/src/ModuleGraph/worker/collectDependencies.js +215 -8
- package/src/ModuleGraph/worker/collectDependencies.js.flow +230 -13
- package/src/Server/symbolicate.js.flow +1 -1
- package/src/Server.js.flow +18 -18
- package/src/cli.js +5 -0
- package/src/cli.js.flow +5 -0
- package/src/commands/build.js +4 -3
- package/src/commands/build.js.flow +5 -3
- package/src/commands/serve.js +3 -3
- package/src/commands/serve.js.flow +5 -3
- package/src/index.flow.js +392 -0
- package/src/index.flow.js.flow +480 -0
- package/src/index.js +8 -366
- package/src/index.js.flow +8 -456
- package/src/lib/CountingSet.js +116 -0
- package/src/lib/CountingSet.js.flow +126 -0
- package/src/lib/JsonReporter.js +0 -2
- package/src/lib/JsonReporter.js.flow +1 -1
- package/src/lib/bundleToBytecode.js.flow +2 -2
- package/src/lib/bundleToString.js.flow +2 -2
- package/src/lib/getAppendScripts.js +10 -4
- package/src/lib/getAppendScripts.js.flow +6 -4
- package/src/lib/getPreludeCode.js +19 -1
- package/src/lib/getPreludeCode.js.flow +17 -2
- package/src/lib/getPrependedScripts.js +10 -2
- package/src/lib/getPrependedScripts.js.flow +11 -2
- package/src/lib/reporting.js +0 -2
- package/src/lib/reporting.js.flow +2 -1
- package/src/lib/transformHelpers.js.flow +2 -2
- package/src/node-haste/DependencyGraph/ModuleResolution.js +17 -4
- package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +20 -12
- package/src/node-haste/DependencyGraph/createHasteMap.js +80 -19
- package/src/node-haste/DependencyGraph/createHasteMap.js.flow +16 -14
- package/src/node-haste/DependencyGraph.js +31 -29
- package/src/node-haste/DependencyGraph.js.flow +44 -38
- package/src/node-haste/ModuleCache.js.flow +1 -1
- package/src/node-haste/lib/AssetPaths.js.flow +2 -2
- package/src/node-haste/lib/parsePlatformFilePath.js.flow +2 -2
- package/src/shared/output/RamBundle/as-indexed-file.js.flow +1 -1
- package/src/shared/output/RamBundle/buildSourcemapWithMetadata.js.flow +2 -2
- package/src/shared/types.flow.js.flow +14 -14
- package/src/DeltaBundler/computeDelta.js +0 -42
- package/src/DeltaBundler/computeDelta.js.flow +0 -47
- package/src/DeltaBundler/traverseDependencies.js +0 -470
- package/src/DeltaBundler/traverseDependencies.js.flow +0 -565
- package/src/node-haste/DependencyGraph/types.js +0 -10
- package/src/node-haste/DependencyGraph/types.js.flow +0 -88
|
@@ -37,6 +37,20 @@ export type Dependency<TSplitCondition> = $ReadOnly<{
|
|
|
37
37
|
name: string,
|
|
38
38
|
}>;
|
|
39
39
|
|
|
40
|
+
// TODO: Convert to a Flow enum
|
|
41
|
+
type ContextMode = 'sync' | 'eager' | 'lazy' | 'lazy-once';
|
|
42
|
+
|
|
43
|
+
type ContextFilter = {pattern: string, flags: string};
|
|
44
|
+
|
|
45
|
+
export type RequireContextParams = $ReadOnly<{
|
|
46
|
+
/* Should search for files recursively. Optional, default `true` when `require.context` is used */
|
|
47
|
+
recursive: boolean,
|
|
48
|
+
/* Filename filter pattern for use in `require.context`. Optional, default `.*` (any file) when `require.context` is used */
|
|
49
|
+
filter: $ReadOnly<ContextFilter>,
|
|
50
|
+
/** Mode for resolving dynamic dependencies. Defaults to `sync` */
|
|
51
|
+
mode: ContextMode,
|
|
52
|
+
}>;
|
|
53
|
+
|
|
40
54
|
type DependencyData<TSplitCondition> = $ReadOnly<{
|
|
41
55
|
// If null, then the dependency is synchronous.
|
|
42
56
|
// (ex. `require('foo')`)
|
|
@@ -45,6 +59,8 @@ type DependencyData<TSplitCondition> = $ReadOnly<{
|
|
|
45
59
|
// If left unspecified, then the dependency is unconditionally split.
|
|
46
60
|
splitCondition?: TSplitCondition,
|
|
47
61
|
locs: Array<BabelSourceLocation>,
|
|
62
|
+
/** Context for requiring a collection of modules. */
|
|
63
|
+
contextParams?: RequireContextParams,
|
|
48
64
|
}>;
|
|
49
65
|
|
|
50
66
|
export type MutableInternalDependency<TSplitCondition> = {
|
|
@@ -66,6 +82,8 @@ export type State<TSplitCondition> = {
|
|
|
66
82
|
dependencyMapIdentifier: ?Identifier,
|
|
67
83
|
keepRequireNames: boolean,
|
|
68
84
|
allowOptionalDependencies: AllowOptionalDependencies,
|
|
85
|
+
/** Enable `require.context` statements which can be used to import multiple files in a directory. */
|
|
86
|
+
unstable_allowRequireContext: boolean,
|
|
69
87
|
};
|
|
70
88
|
|
|
71
89
|
export type Options<TSplitCondition = void> = $ReadOnly<{
|
|
@@ -77,6 +95,8 @@ export type Options<TSplitCondition = void> = $ReadOnly<{
|
|
|
77
95
|
allowOptionalDependencies: AllowOptionalDependencies,
|
|
78
96
|
dependencyRegistry?: ModuleDependencyRegistry<TSplitCondition>,
|
|
79
97
|
dependencyTransformer?: DependencyTransformer<TSplitCondition>,
|
|
98
|
+
/** Enable `require.context` statements which can be used to import multiple files in a directory. */
|
|
99
|
+
unstable_allowRequireContext: boolean,
|
|
80
100
|
}>;
|
|
81
101
|
|
|
82
102
|
export type CollectedDependencies<+TSplitCondition> = $ReadOnly<{
|
|
@@ -87,8 +107,8 @@ export type CollectedDependencies<+TSplitCondition> = $ReadOnly<{
|
|
|
87
107
|
|
|
88
108
|
// Registry for the dependency of a module.
|
|
89
109
|
// Defines when dependencies should be collapsed.
|
|
90
|
-
// E.g. should a module that's once required
|
|
91
|
-
// be
|
|
110
|
+
// E.g. should a module that's once required optionally and once not
|
|
111
|
+
// be treated as the same or different dependencies.
|
|
92
112
|
export interface ModuleDependencyRegistry<+TSplitCondition> {
|
|
93
113
|
registerDependency(
|
|
94
114
|
qualifier: ImportQualifier,
|
|
@@ -151,6 +171,7 @@ function collectDependencies<TSplitCondition = void>(
|
|
|
151
171
|
dynamicRequires: options.dynamicRequires,
|
|
152
172
|
keepRequireNames: options.keepRequireNames,
|
|
153
173
|
allowOptionalDependencies: options.allowOptionalDependencies,
|
|
174
|
+
unstable_allowRequireContext: options.unstable_allowRequireContext,
|
|
154
175
|
};
|
|
155
176
|
|
|
156
177
|
const visitor = {
|
|
@@ -199,6 +220,26 @@ function collectDependencies<TSplitCondition = void>(
|
|
|
199
220
|
return;
|
|
200
221
|
}
|
|
201
222
|
|
|
223
|
+
// Match `require.context`
|
|
224
|
+
if (
|
|
225
|
+
// Feature gate, defaults to `false`.
|
|
226
|
+
state.unstable_allowRequireContext &&
|
|
227
|
+
callee.type === 'MemberExpression' &&
|
|
228
|
+
// `require`
|
|
229
|
+
callee.object.type === 'Identifier' &&
|
|
230
|
+
callee.object.name === 'require' &&
|
|
231
|
+
// `context`
|
|
232
|
+
callee.property.type === 'Identifier' &&
|
|
233
|
+
callee.property.name === 'context' &&
|
|
234
|
+
!callee.computed &&
|
|
235
|
+
// Ensure `require` refers to the global and not something else.
|
|
236
|
+
!path.scope.getBinding('require')
|
|
237
|
+
) {
|
|
238
|
+
processRequireContextCall(path, state);
|
|
239
|
+
visited.add(path.node);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
202
243
|
if (
|
|
203
244
|
name != null &&
|
|
204
245
|
state.dependencyCalls.has(name) &&
|
|
@@ -251,6 +292,132 @@ function collectDependencies<TSplitCondition = void>(
|
|
|
251
292
|
};
|
|
252
293
|
}
|
|
253
294
|
|
|
295
|
+
/** Extract args passed to the `require.context` method. */
|
|
296
|
+
function getRequireContextArgs(
|
|
297
|
+
path: NodePath<CallExpression>,
|
|
298
|
+
): [string, RequireContextParams] {
|
|
299
|
+
const args = path.get('arguments');
|
|
300
|
+
|
|
301
|
+
let directory: string;
|
|
302
|
+
if (!Array.isArray(args) || args.length < 1) {
|
|
303
|
+
throw new InvalidRequireCallError(path);
|
|
304
|
+
} else {
|
|
305
|
+
const result = args[0].evaluate();
|
|
306
|
+
if (result.confident && typeof result.value === 'string') {
|
|
307
|
+
directory = result.value;
|
|
308
|
+
} else {
|
|
309
|
+
throw new InvalidRequireCallError(
|
|
310
|
+
result.deopt ?? args[0],
|
|
311
|
+
'First argument of `require.context` should be a string denoting the directory to require.',
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Default to requiring through all directories.
|
|
317
|
+
let recursive: boolean = true;
|
|
318
|
+
if (args.length > 1) {
|
|
319
|
+
const result = args[1].evaluate();
|
|
320
|
+
if (result.confident && typeof result.value === 'boolean') {
|
|
321
|
+
recursive = result.value;
|
|
322
|
+
} else if (!(result.confident && typeof result.value === 'undefined')) {
|
|
323
|
+
throw new InvalidRequireCallError(
|
|
324
|
+
result.deopt ?? args[1],
|
|
325
|
+
'Second argument of `require.context` should be an optional boolean indicating if files should be imported recursively or not.',
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Default to all files.
|
|
331
|
+
let filter: ContextFilter = {pattern: '.*', flags: ''};
|
|
332
|
+
if (args.length > 2) {
|
|
333
|
+
// evaluate() to check for undefined (because it's technically a scope lookup)
|
|
334
|
+
// but check the AST for the regex literal, since evaluate() doesn't do regex.
|
|
335
|
+
const result = args[2].evaluate();
|
|
336
|
+
const argNode = args[2].node;
|
|
337
|
+
if (argNode.type === 'RegExpLiteral') {
|
|
338
|
+
// TODO: Handle `new RegExp(...)` -- `argNode.type === 'NewExpression'`
|
|
339
|
+
filter = {
|
|
340
|
+
pattern: argNode.pattern,
|
|
341
|
+
flags: argNode.flags || '',
|
|
342
|
+
};
|
|
343
|
+
} else if (!(result.confident && typeof result.value === 'undefined')) {
|
|
344
|
+
throw new InvalidRequireCallError(
|
|
345
|
+
args[2],
|
|
346
|
+
`Third argument of \`require.context\` should be an optional RegExp pattern matching all of the files to import, instead found node of type: ${argNode.type}.`,
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Default to `sync`.
|
|
352
|
+
let mode: ContextMode = 'sync';
|
|
353
|
+
if (args.length > 3) {
|
|
354
|
+
const result = args[3].evaluate();
|
|
355
|
+
if (result.confident && typeof result.value === 'string') {
|
|
356
|
+
mode = getContextMode(args[3], result.value);
|
|
357
|
+
} else if (!(result.confident && typeof result.value === 'undefined')) {
|
|
358
|
+
throw new InvalidRequireCallError(
|
|
359
|
+
result.deopt ?? args[3],
|
|
360
|
+
'Fourth argument of `require.context` should be an optional string "mode" denoting how the modules will be resolved.',
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (args.length > 4) {
|
|
366
|
+
throw new InvalidRequireCallError(
|
|
367
|
+
path,
|
|
368
|
+
`Too many arguments provided to \`require.context\` call. Expected 4, got: ${args.length}`,
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return [
|
|
373
|
+
directory,
|
|
374
|
+
{
|
|
375
|
+
recursive,
|
|
376
|
+
filter,
|
|
377
|
+
mode,
|
|
378
|
+
},
|
|
379
|
+
];
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function getContextMode(path: NodePath<>, mode: string): ContextMode {
|
|
383
|
+
if (
|
|
384
|
+
mode === 'sync' ||
|
|
385
|
+
mode === 'eager' ||
|
|
386
|
+
mode === 'lazy' ||
|
|
387
|
+
mode === 'lazy-once'
|
|
388
|
+
) {
|
|
389
|
+
return mode;
|
|
390
|
+
}
|
|
391
|
+
throw new InvalidRequireCallError(
|
|
392
|
+
path,
|
|
393
|
+
`require.context "${mode}" mode is not supported. Expected one of: sync, eager, lazy, lazy-once`,
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function processRequireContextCall<TSplitCondition>(
|
|
398
|
+
path: NodePath<CallExpression>,
|
|
399
|
+
state: State<TSplitCondition>,
|
|
400
|
+
): void {
|
|
401
|
+
const [directory, contextParams] = getRequireContextArgs(path);
|
|
402
|
+
const transformer = state.dependencyTransformer;
|
|
403
|
+
const dep = registerDependency(
|
|
404
|
+
state,
|
|
405
|
+
{
|
|
406
|
+
// We basically want to "import" every file in a folder and then filter them out with the given `filter` RegExp.
|
|
407
|
+
name: directory,
|
|
408
|
+
// Capture the matching context
|
|
409
|
+
contextParams,
|
|
410
|
+
asyncType: null,
|
|
411
|
+
optional: isOptionalDependency(directory, path, state),
|
|
412
|
+
},
|
|
413
|
+
path,
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
// require() the generated module representing this context
|
|
417
|
+
path.get('callee').replaceWith(types.identifier('require'));
|
|
418
|
+
transformer.transformSyncRequire(path, dep, state);
|
|
419
|
+
}
|
|
420
|
+
|
|
254
421
|
function collectImports<TSplitCondition>(
|
|
255
422
|
path: NodePath<>,
|
|
256
423
|
state: State<TSplitCondition>,
|
|
@@ -332,7 +499,7 @@ function processRequireCall<TSplitCondition>(
|
|
|
332
499
|
}
|
|
333
500
|
|
|
334
501
|
function getNearestLocFromPath(path: NodePath<>): ?BabelSourceLocation {
|
|
335
|
-
let current = path;
|
|
502
|
+
let current: ?(NodePath<> | NodePath<BabelNode>) = path;
|
|
336
503
|
while (current && !current.node.loc) {
|
|
337
504
|
current = current.parentPath;
|
|
338
505
|
}
|
|
@@ -344,6 +511,7 @@ export type ImportQualifier = $ReadOnly<{
|
|
|
344
511
|
asyncType: AsyncDependencyType | null,
|
|
345
512
|
splitCondition?: NodePath<>,
|
|
346
513
|
optional: boolean,
|
|
514
|
+
contextParams?: RequireContextParams,
|
|
347
515
|
}>;
|
|
348
516
|
|
|
349
517
|
function registerDependency<TSplitCondition>(
|
|
@@ -352,7 +520,6 @@ function registerDependency<TSplitCondition>(
|
|
|
352
520
|
path: NodePath<>,
|
|
353
521
|
): InternalDependency<TSplitCondition> {
|
|
354
522
|
const dependency = state.dependencyRegistry.registerDependency(qualifier);
|
|
355
|
-
|
|
356
523
|
const loc = getNearestLocFromPath(path);
|
|
357
524
|
if (loc != null) {
|
|
358
525
|
dependency.locs.push(loc);
|
|
@@ -383,7 +550,7 @@ function isOptionalDependency<TSplitCondition>(
|
|
|
383
550
|
|
|
384
551
|
// Valid statement stack for single-level try-block: expressionStatement -> blockStatement -> tryStatement
|
|
385
552
|
let sCount = 0;
|
|
386
|
-
let p = path;
|
|
553
|
+
let p: ?(NodePath<> | NodePath<BabelNode>) = path;
|
|
387
554
|
while (p && sCount < 3) {
|
|
388
555
|
if (p.isStatement()) {
|
|
389
556
|
if (p.node.type === 'BlockStatement') {
|
|
@@ -419,14 +586,20 @@ function getModuleNameFromCallArgs(path: NodePath<CallExpression>): ?string {
|
|
|
419
586
|
|
|
420
587
|
return null;
|
|
421
588
|
}
|
|
589
|
+
|
|
422
590
|
collectDependencies.getModuleNameFromCallArgs = getModuleNameFromCallArgs;
|
|
423
591
|
|
|
424
592
|
class InvalidRequireCallError extends Error {
|
|
425
|
-
constructor({node}:
|
|
593
|
+
constructor({node}: NodePath<>, message?: string) {
|
|
426
594
|
const line = node.loc && node.loc.start && node.loc.start.line;
|
|
427
595
|
|
|
428
596
|
super(
|
|
429
|
-
|
|
597
|
+
[
|
|
598
|
+
`Invalid call at line ${line || '<unknown>'}: ${generate(node).code}`,
|
|
599
|
+
message,
|
|
600
|
+
]
|
|
601
|
+
.filter(Boolean)
|
|
602
|
+
.join('\n'),
|
|
430
603
|
);
|
|
431
604
|
}
|
|
432
605
|
}
|
|
@@ -469,9 +642,11 @@ const DefaultDependencyTransformer: DependencyTransformer<mixed> = {
|
|
|
469
642
|
state: State<mixed>,
|
|
470
643
|
): void {
|
|
471
644
|
const moduleIDExpression = createModuleIDExpression(dependency, state);
|
|
472
|
-
path.node.arguments =
|
|
473
|
-
|
|
474
|
-
|
|
645
|
+
path.node.arguments = [moduleIDExpression];
|
|
646
|
+
// Always add the debug name argument last
|
|
647
|
+
if (state.keepRequireNames) {
|
|
648
|
+
path.node.arguments.push(types.stringLiteral(dependency.name));
|
|
649
|
+
}
|
|
475
650
|
},
|
|
476
651
|
|
|
477
652
|
transformImportCall(
|
|
@@ -546,6 +721,44 @@ function createModuleNameLiteral(dependency: InternalDependency<mixed>) {
|
|
|
546
721
|
return types.stringLiteral(dependency.name);
|
|
547
722
|
}
|
|
548
723
|
|
|
724
|
+
/**
|
|
725
|
+
* Given an import qualifier, return a key used to register the dependency.
|
|
726
|
+
* Generally this return the `ImportQualifier.name` property, but in the case
|
|
727
|
+
* of `require.context` more attributes can be appended to distinguish various combinations that would otherwise conflict.
|
|
728
|
+
*
|
|
729
|
+
* For example, the following case would have collision issues if they all utilized the `name` property:
|
|
730
|
+
* ```
|
|
731
|
+
* require('./foo');
|
|
732
|
+
* require.context('./foo');
|
|
733
|
+
* require.context('./foo', true, /something/);
|
|
734
|
+
* require.context('./foo', false, /something/);
|
|
735
|
+
* require.context('./foo', false, /something/, 'lazy');
|
|
736
|
+
* ```
|
|
737
|
+
*
|
|
738
|
+
* This method should be utilized by `registerDependency`.
|
|
739
|
+
*/
|
|
740
|
+
function getKeyForDependency(qualifier: ImportQualifier): string {
|
|
741
|
+
let key = qualifier.name;
|
|
742
|
+
|
|
743
|
+
const {contextParams} = qualifier;
|
|
744
|
+
// Add extra qualifiers when using `require.context` to prevent collisions.
|
|
745
|
+
if (contextParams) {
|
|
746
|
+
// NOTE(EvanBacon): Keep this synchronized with `RequireContextParams`, if any other properties are added
|
|
747
|
+
// then this key algorithm should be updated to account for those properties.
|
|
748
|
+
// Example: `./directory__true__/foobar/m__lazy`
|
|
749
|
+
key += [
|
|
750
|
+
'',
|
|
751
|
+
'context',
|
|
752
|
+
String(contextParams.recursive),
|
|
753
|
+
String(contextParams.filter.pattern),
|
|
754
|
+
String(contextParams.filter.flags),
|
|
755
|
+
contextParams.mode,
|
|
756
|
+
// Join together and append to the name:
|
|
757
|
+
].join('__');
|
|
758
|
+
}
|
|
759
|
+
return key;
|
|
760
|
+
}
|
|
761
|
+
|
|
549
762
|
class DefaultModuleDependencyRegistry<TSplitCondition = void>
|
|
550
763
|
implements ModuleDependencyRegistry<TSplitCondition>
|
|
551
764
|
{
|
|
@@ -554,8 +767,9 @@ class DefaultModuleDependencyRegistry<TSplitCondition = void>
|
|
|
554
767
|
registerDependency(
|
|
555
768
|
qualifier: ImportQualifier,
|
|
556
769
|
): InternalDependency<TSplitCondition> {
|
|
770
|
+
const key = getKeyForDependency(qualifier);
|
|
557
771
|
let dependency: ?InternalDependency<TSplitCondition> =
|
|
558
|
-
this._dependencies.get(
|
|
772
|
+
this._dependencies.get(key);
|
|
559
773
|
|
|
560
774
|
if (dependency == null) {
|
|
561
775
|
const newDependency: MutableInternalDependency<TSplitCondition> = {
|
|
@@ -568,14 +782,17 @@ class DefaultModuleDependencyRegistry<TSplitCondition = void>
|
|
|
568
782
|
if (qualifier.optional) {
|
|
569
783
|
newDependency.isOptional = true;
|
|
570
784
|
}
|
|
785
|
+
if (qualifier.contextParams) {
|
|
786
|
+
newDependency.contextParams = qualifier.contextParams;
|
|
787
|
+
}
|
|
571
788
|
|
|
572
789
|
dependency = newDependency;
|
|
573
|
-
this._dependencies.set(
|
|
790
|
+
this._dependencies.set(key, dependency);
|
|
574
791
|
} else {
|
|
575
792
|
const original = dependency;
|
|
576
793
|
dependency = collapseDependencies(original, qualifier);
|
|
577
794
|
if (original !== dependency) {
|
|
578
|
-
this._dependencies.set(
|
|
795
|
+
this._dependencies.set(key, dependency);
|
|
579
796
|
}
|
|
580
797
|
}
|
|
581
798
|
|
|
@@ -35,7 +35,7 @@ export type StackFrameOutput = $ReadOnly<{
|
|
|
35
35
|
...
|
|
36
36
|
}>;
|
|
37
37
|
type ExplodedSourceMapModule = $ElementType<ExplodedSourceMap, number>;
|
|
38
|
-
type Position = {
|
|
38
|
+
type Position = {+line1Based: number, column0Based: number};
|
|
39
39
|
|
|
40
40
|
function createFunctionNameGetter(
|
|
41
41
|
module: ExplodedSourceMapModule,
|
package/src/Server.js.flow
CHANGED
|
@@ -81,7 +81,7 @@ export type BundleMetadata = {
|
|
|
81
81
|
...
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
type ProcessStartContext = {
|
|
84
|
+
type ProcessStartContext = {
|
|
85
85
|
+buildID: string,
|
|
86
86
|
+bundleOptions: BundleOptions,
|
|
87
87
|
+graphId: GraphId,
|
|
@@ -91,24 +91,24 @@ type ProcessStartContext = {|
|
|
|
91
91
|
+req: IncomingMessage,
|
|
92
92
|
+revisionId?: ?RevisionId,
|
|
93
93
|
...SplitBundleOptions,
|
|
94
|
-
|
|
94
|
+
};
|
|
95
95
|
|
|
96
|
-
type ProcessDeleteContext = {
|
|
96
|
+
type ProcessDeleteContext = {
|
|
97
97
|
+graphId: GraphId,
|
|
98
98
|
+req: IncomingMessage,
|
|
99
99
|
+res: ServerResponse,
|
|
100
|
-
|
|
100
|
+
};
|
|
101
101
|
|
|
102
|
-
type ProcessEndContext<T> = {
|
|
102
|
+
type ProcessEndContext<T> = {
|
|
103
103
|
...ProcessStartContext,
|
|
104
104
|
+result: T,
|
|
105
|
-
|
|
105
|
+
};
|
|
106
106
|
|
|
107
|
-
export type ServerOptions = $ReadOnly<{
|
|
107
|
+
export type ServerOptions = $ReadOnly<{
|
|
108
108
|
hasReducedPerformance?: boolean,
|
|
109
109
|
onBundleBuilt?: (bundlePath: string) => void,
|
|
110
110
|
watch?: boolean,
|
|
111
|
-
|
|
111
|
+
}>;
|
|
112
112
|
|
|
113
113
|
const DELTA_ID_HEADER = 'X-Metro-Delta-ID';
|
|
114
114
|
const FILES_CHANGED_COUNT_HEADER = 'X-Metro-Files-Changed-Count';
|
|
@@ -504,7 +504,7 @@ class Server {
|
|
|
504
504
|
build,
|
|
505
505
|
delete: deleteFn,
|
|
506
506
|
finish,
|
|
507
|
-
}: {
|
|
507
|
+
}: {
|
|
508
508
|
+createStartEntry: (context: ProcessStartContext) => ActionLogEntryData,
|
|
509
509
|
+createEndEntry: (
|
|
510
510
|
context: ProcessEndContext<T>,
|
|
@@ -512,7 +512,7 @@ class Server {
|
|
|
512
512
|
+build: (context: ProcessStartContext) => Promise<T>,
|
|
513
513
|
+delete?: (context: ProcessDeleteContext) => Promise<void>,
|
|
514
514
|
+finish: (context: ProcessEndContext<T>) => void,
|
|
515
|
-
|
|
515
|
+
}) {
|
|
516
516
|
return async function requestProcessor(
|
|
517
517
|
req: IncomingMessage,
|
|
518
518
|
res: ServerResponse,
|
|
@@ -703,12 +703,12 @@ class Server {
|
|
|
703
703
|
};
|
|
704
704
|
},
|
|
705
705
|
createEndEntry(
|
|
706
|
-
context: ProcessEndContext<{
|
|
706
|
+
context: ProcessEndContext<{
|
|
707
707
|
bundle: string,
|
|
708
708
|
lastModifiedDate: Date,
|
|
709
709
|
nextRevId: RevisionId,
|
|
710
710
|
numModifiedFiles: number,
|
|
711
|
-
|
|
711
|
+
}>,
|
|
712
712
|
) {
|
|
713
713
|
return {
|
|
714
714
|
outdated_modules: context.result.numModifiedFiles,
|
|
@@ -820,12 +820,12 @@ class Server {
|
|
|
820
820
|
};
|
|
821
821
|
},
|
|
822
822
|
createEndEntry(
|
|
823
|
-
context: ProcessEndContext<{
|
|
823
|
+
context: ProcessEndContext<{
|
|
824
824
|
bytecode: Buffer,
|
|
825
825
|
lastModifiedDate: Date,
|
|
826
826
|
nextRevId: RevisionId,
|
|
827
827
|
numModifiedFiles: number,
|
|
828
|
-
|
|
828
|
+
}>,
|
|
829
829
|
) {
|
|
830
830
|
return {
|
|
831
831
|
outdated_modules: context.result.numModifiedFiles,
|
|
@@ -1193,14 +1193,14 @@ class Server {
|
|
|
1193
1193
|
return this._config.watchFolders;
|
|
1194
1194
|
}
|
|
1195
1195
|
|
|
1196
|
-
static DEFAULT_GRAPH_OPTIONS: {
|
|
1196
|
+
static DEFAULT_GRAPH_OPTIONS: {
|
|
1197
1197
|
customTransformOptions: any,
|
|
1198
1198
|
dev: boolean,
|
|
1199
1199
|
hot: boolean,
|
|
1200
1200
|
minify: boolean,
|
|
1201
1201
|
runtimeBytecodeVersion: ?number,
|
|
1202
1202
|
unstable_transformProfile: 'default',
|
|
1203
|
-
|
|
1203
|
+
} = {
|
|
1204
1204
|
customTransformOptions: Object.create(null),
|
|
1205
1205
|
dev: true,
|
|
1206
1206
|
hot: false,
|
|
@@ -1209,7 +1209,7 @@ class Server {
|
|
|
1209
1209
|
unstable_transformProfile: 'default',
|
|
1210
1210
|
};
|
|
1211
1211
|
|
|
1212
|
-
static DEFAULT_BUNDLE_OPTIONS: {
|
|
1212
|
+
static DEFAULT_BUNDLE_OPTIONS: {
|
|
1213
1213
|
...typeof Server.DEFAULT_GRAPH_OPTIONS,
|
|
1214
1214
|
excludeSource: false,
|
|
1215
1215
|
inlineSourceMap: false,
|
|
@@ -1219,7 +1219,7 @@ class Server {
|
|
|
1219
1219
|
shallow: false,
|
|
1220
1220
|
sourceMapUrl: null,
|
|
1221
1221
|
sourceUrl: null,
|
|
1222
|
-
|
|
1222
|
+
} = {
|
|
1223
1223
|
...Server.DEFAULT_GRAPH_OPTIONS,
|
|
1224
1224
|
excludeSource: false,
|
|
1225
1225
|
inlineSourceMap: false,
|
package/src/cli.js
CHANGED
package/src/cli.js.flow
CHANGED
package/src/commands/build.js
CHANGED
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
|
|
12
12
|
const { makeAsyncCommand } = require("../cli-utils");
|
|
13
13
|
|
|
14
|
-
const MetroApi = require("../index");
|
|
15
|
-
|
|
16
14
|
const TerminalReporter = require("../lib/TerminalReporter");
|
|
17
15
|
|
|
18
16
|
const { loadConfig } = require("metro-config");
|
|
@@ -78,7 +76,10 @@ module.exports = () => ({
|
|
|
78
76
|
handler: makeAsyncCommand(async (argv) => {
|
|
79
77
|
const config = await loadConfig(argv); // $FlowExpectedError YargArguments and RunBuildOptions are used interchangeable but their types are not yet compatible
|
|
80
78
|
|
|
81
|
-
const options = argv;
|
|
79
|
+
const options = argv; // Inline require() to avoid circular dependency with ../index
|
|
80
|
+
|
|
81
|
+
const MetroApi = require("../index");
|
|
82
|
+
|
|
82
83
|
await MetroApi.runBuild(config, {
|
|
83
84
|
...options,
|
|
84
85
|
onBegin: () => {
|
|
@@ -15,7 +15,6 @@ import type {YargArguments} from 'metro-config/src/configTypes.flow';
|
|
|
15
15
|
import typeof Yargs from 'yargs';
|
|
16
16
|
|
|
17
17
|
const {makeAsyncCommand} = require('../cli-utils');
|
|
18
|
-
const MetroApi = require('../index');
|
|
19
18
|
const TerminalReporter = require('../lib/TerminalReporter');
|
|
20
19
|
const {loadConfig} = require('metro-config');
|
|
21
20
|
const {Terminal} = require('metro-core');
|
|
@@ -23,12 +22,12 @@ const {Terminal} = require('metro-core');
|
|
|
23
22
|
const term = new Terminal(process.stdout);
|
|
24
23
|
const updateReporter = new TerminalReporter(term);
|
|
25
24
|
|
|
26
|
-
module.exports = (): ({
|
|
25
|
+
module.exports = (): ({
|
|
27
26
|
builder: (yargs: Yargs) => void,
|
|
28
27
|
command: string,
|
|
29
28
|
description: string,
|
|
30
29
|
handler: (argv: YargArguments) => void,
|
|
31
|
-
|
|
30
|
+
}) => ({
|
|
32
31
|
command: 'build <entry>',
|
|
33
32
|
|
|
34
33
|
description:
|
|
@@ -66,6 +65,9 @@ module.exports = (): ({|
|
|
|
66
65
|
// $FlowExpectedError YargArguments and RunBuildOptions are used interchangeable but their types are not yet compatible
|
|
67
66
|
const options = (argv: RunBuildOptions);
|
|
68
67
|
|
|
68
|
+
// Inline require() to avoid circular dependency with ../index
|
|
69
|
+
const MetroApi = require('../index');
|
|
70
|
+
|
|
69
71
|
await MetroApi.runBuild(config, {
|
|
70
72
|
...options,
|
|
71
73
|
onBegin: (): void => {
|
package/src/commands/serve.js
CHANGED
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
|
|
12
12
|
const { makeAsyncCommand, watchFile } = require("../cli-utils");
|
|
13
13
|
|
|
14
|
-
const MetroApi = require("../index");
|
|
15
|
-
|
|
16
14
|
const { loadConfig, resolveConfig } = require("metro-config");
|
|
17
15
|
|
|
18
16
|
const { promisify } = require("util");
|
|
@@ -93,7 +91,9 @@ module.exports = () => ({
|
|
|
93
91
|
await promisify(server.close).call(server);
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
const config = await loadConfig(argv); //
|
|
94
|
+
const config = await loadConfig(argv); // Inline require() to avoid circular dependency with ../index
|
|
95
|
+
|
|
96
|
+
const MetroApi = require("../index"); // $FlowExpectedError YargArguments and RunBuildOptions are used interchangeable but their types are not yet compatible
|
|
97
97
|
|
|
98
98
|
server = await MetroApi.runServer(config, argv);
|
|
99
99
|
restarting = false;
|
|
@@ -15,16 +15,15 @@ import type {YargArguments} from 'metro-config/src/configTypes.flow';
|
|
|
15
15
|
import typeof Yargs from 'yargs';
|
|
16
16
|
|
|
17
17
|
const {makeAsyncCommand, watchFile} = require('../cli-utils');
|
|
18
|
-
const MetroApi = require('../index');
|
|
19
18
|
const {loadConfig, resolveConfig} = require('metro-config');
|
|
20
19
|
const {promisify} = require('util');
|
|
21
20
|
|
|
22
|
-
module.exports = (): ({
|
|
21
|
+
module.exports = (): ({
|
|
23
22
|
builder: (yargs: Yargs) => void,
|
|
24
23
|
command: $TEMPORARY$string<'serve'>,
|
|
25
24
|
description: string,
|
|
26
25
|
handler: (argv: YargArguments) => void,
|
|
27
|
-
|
|
26
|
+
}) => ({
|
|
28
27
|
command: 'serve',
|
|
29
28
|
|
|
30
29
|
description: 'Starts Metro on the given port, building bundles on the fly',
|
|
@@ -84,6 +83,9 @@ module.exports = (): ({|
|
|
|
84
83
|
|
|
85
84
|
const config = await loadConfig(argv);
|
|
86
85
|
|
|
86
|
+
// Inline require() to avoid circular dependency with ../index
|
|
87
|
+
const MetroApi = require('../index');
|
|
88
|
+
|
|
87
89
|
// $FlowExpectedError YargArguments and RunBuildOptions are used interchangeable but their types are not yet compatible
|
|
88
90
|
server = await MetroApi.runServer(config, (argv: RunServerOptions));
|
|
89
91
|
|