metro 0.71.0 → 0.71.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -22
- package/src/Bundler.js +0 -2
- package/src/Bundler.js.flow +1 -1
- package/src/DeltaBundler/DeltaCalculator.js +2 -0
- package/src/DeltaBundler/DeltaCalculator.js.flow +2 -0
- 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 +2 -2
- package/src/DeltaBundler/__fixtures__/hasteImpl.js +4 -0
- package/src/DeltaBundler/graphOperations.js +382 -222
- package/src/DeltaBundler/graphOperations.js.flow +404 -232
- package/src/DeltaBundler/types.flow.js +6 -0
- package/src/DeltaBundler/types.flow.js.flow +7 -1
- package/src/DeltaBundler.js +0 -2
- package/src/DeltaBundler.js.flow +1 -1
- package/src/HmrServer.js +0 -2
- package/src/HmrServer.js.flow +1 -2
- package/src/ModuleGraph/node-haste/node-haste.flow.js +0 -1
- package/src/ModuleGraph/node-haste/node-haste.flow.js.flow +1 -2
- package/src/ModuleGraph/node-haste/node-haste.js.flow +7 -2
- package/src/ModuleGraph/output/util.js.flow +2 -2
- package/src/ModuleGraph/silent-console.js +5 -4
- package/src/ModuleGraph/silent-console.js.flow +8 -4
- package/src/ModuleGraph/worker/collectDependencies.js +215 -8
- package/src/ModuleGraph/worker/collectDependencies.js.flow +233 -13
- package/src/Server.js +2 -0
- package/src/Server.js.flow +9 -2
- 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 +3 -1
- package/src/commands/serve.js +3 -3
- package/src/commands/serve.js.flow +3 -1
- package/src/index.flow.js +392 -0
- package/src/index.flow.js.flow +480 -0
- package/src/index.js +8 -380
- package/src/index.js.flow +8 -466
- 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/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 +15 -0
- 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/node-haste/DependencyGraph/ModuleResolution.js +15 -3
- package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +15 -0
- package/src/node-haste/DependencyGraph/createHasteMap.js +78 -19
- package/src/node-haste/DependencyGraph/createHasteMap.js.flow +14 -9
- package/src/node-haste/DependencyGraph.js +2 -2
- package/src/node-haste/DependencyGraph.js.flow +4 -2
|
@@ -10,9 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
+
import type {RequireContextParams} from '../ModuleGraph/worker/collectDependencies';
|
|
13
14
|
import type {PrivateState} from './graphOperations';
|
|
14
15
|
import type {JsTransformOptions} from 'metro-transform-worker';
|
|
15
16
|
|
|
17
|
+
import CountingSet from '../lib/CountingSet';
|
|
18
|
+
|
|
16
19
|
export type MixedOutput = {
|
|
17
20
|
+data: mixed,
|
|
18
21
|
+type: string,
|
|
@@ -48,6 +51,9 @@ export type TransformResultDependency = {
|
|
|
48
51
|
+isOptional?: boolean,
|
|
49
52
|
|
|
50
53
|
+locs: $ReadOnlyArray<BabelSourceLocation>,
|
|
54
|
+
|
|
55
|
+
/** Context for requiring a collection of modules. */
|
|
56
|
+
+contextParams?: RequireContextParams,
|
|
51
57
|
},
|
|
52
58
|
};
|
|
53
59
|
|
|
@@ -58,7 +64,7 @@ export type Dependency = {
|
|
|
58
64
|
|
|
59
65
|
export type Module<T = MixedOutput> = {
|
|
60
66
|
+dependencies: Map<string, Dependency>,
|
|
61
|
-
+inverseDependencies:
|
|
67
|
+
+inverseDependencies: CountingSet<string>,
|
|
62
68
|
+output: $ReadOnlyArray<T>,
|
|
63
69
|
+path: string,
|
|
64
70
|
+getSource: () => Buffer,
|
package/src/DeltaBundler.js
CHANGED
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
|
|
12
12
|
const DeltaCalculator = require("./DeltaBundler/DeltaCalculator");
|
|
13
13
|
|
|
14
|
-
const { EventEmitter } = require("events");
|
|
15
|
-
|
|
16
14
|
/**
|
|
17
15
|
* `DeltaBundler` uses the `DeltaTransformer` to build bundle deltas. This
|
|
18
16
|
* module handles all the transformer instances so it can support multiple
|
package/src/DeltaBundler.js.flow
CHANGED
|
@@ -18,9 +18,9 @@ import type {
|
|
|
18
18
|
MixedOutput,
|
|
19
19
|
Options,
|
|
20
20
|
} from './DeltaBundler/types.flow';
|
|
21
|
+
import type EventEmitter from 'events';
|
|
21
22
|
|
|
22
23
|
const DeltaCalculator = require('./DeltaBundler/DeltaCalculator');
|
|
23
|
-
const {EventEmitter} = require('events');
|
|
24
24
|
|
|
25
25
|
export type {
|
|
26
26
|
DeltaResult,
|
package/src/HmrServer.js
CHANGED
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
|
|
12
12
|
const hmrJSBundle = require("./DeltaBundler/Serializers/hmrJSBundle");
|
|
13
13
|
|
|
14
|
-
const IncrementalBundler = require("./IncrementalBundler");
|
|
15
|
-
|
|
16
14
|
const GraphNotFoundError = require("./IncrementalBundler/GraphNotFoundError");
|
|
17
15
|
|
|
18
16
|
const RevisionNotFoundError = require("./IncrementalBundler/RevisionNotFoundError");
|
package/src/HmrServer.js.flow
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
import type {RevisionId} from './IncrementalBundler';
|
|
13
|
+
import type IncrementalBundler, {RevisionId} from './IncrementalBundler';
|
|
14
14
|
import type {ConfigT} from 'metro-config/src/configTypes.flow';
|
|
15
15
|
import type {
|
|
16
16
|
HmrClientMessage,
|
|
@@ -20,7 +20,6 @@ import type {
|
|
|
20
20
|
} from 'metro-runtime/src/modules/types.flow';
|
|
21
21
|
|
|
22
22
|
const hmrJSBundle = require('./DeltaBundler/Serializers/hmrJSBundle');
|
|
23
|
-
const IncrementalBundler = require('./IncrementalBundler');
|
|
24
23
|
const GraphNotFoundError = require('./IncrementalBundler/GraphNotFoundError');
|
|
25
24
|
const RevisionNotFoundError = require('./IncrementalBundler/RevisionNotFoundError');
|
|
26
25
|
const debounceAsyncQueue = require('./lib/debounceAsyncQueue');
|
|
@@ -10,8 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
'use strict';
|
|
14
|
-
|
|
15
13
|
type ModuleID = string;
|
|
16
14
|
export type Path = string;
|
|
17
15
|
type Platform = string;
|
|
@@ -63,6 +61,7 @@ type HasteMapOptions = {
|
|
|
63
61
|
preferNativePlatform: true,
|
|
64
62
|
};
|
|
65
63
|
|
|
64
|
+
// eslint-disable-next-line no-unused-vars
|
|
66
65
|
declare class HasteMap {
|
|
67
66
|
// node-haste/DependencyGraph/HasteMap.js
|
|
68
67
|
build(): Promise<Object>;
|
|
@@ -56,7 +56,7 @@ const NULL_MODULE: Moduleish = {
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
const NODE_MODULES = path.sep + 'node_modules' + path.sep;
|
|
59
|
-
const isNodeModules = file => file.includes(NODE_MODULES);
|
|
59
|
+
const isNodeModules = (file: string) => file.includes(NODE_MODULES);
|
|
60
60
|
|
|
61
61
|
// This function maps the ModuleGraph data structure to metro-file-map's ModuleMap
|
|
62
62
|
const createModuleMap = ({
|
|
@@ -64,6 +64,11 @@ const createModuleMap = ({
|
|
|
64
64
|
moduleCache,
|
|
65
65
|
sourceExts,
|
|
66
66
|
platforms,
|
|
67
|
+
}: {
|
|
68
|
+
files: Array<string>,
|
|
69
|
+
moduleCache: ModuleCache,
|
|
70
|
+
platforms: void | $ReadOnlyArray<string>,
|
|
71
|
+
sourceExts: Extensions,
|
|
67
72
|
}): ModuleMapData => {
|
|
68
73
|
const platformSet = new Set(
|
|
69
74
|
(platforms ?? defaults.platforms).concat([NATIVE_PLATFORM]),
|
|
@@ -142,7 +147,7 @@ exports.createResolveFn = function (options: ResolveOptions): ResolveFn {
|
|
|
142
147
|
);
|
|
143
148
|
|
|
144
149
|
const assetExtensions = new Set(assetExts.map(asset => '.' + asset));
|
|
145
|
-
const isAssetFile = file => assetExtensions.has(path.extname(file));
|
|
150
|
+
const isAssetFile = (file: string) => assetExtensions.has(path.extname(file));
|
|
146
151
|
|
|
147
152
|
const moduleResolver = new ModuleResolver({
|
|
148
153
|
dirExists: (filePath: string): boolean => hasteFS.dirExists(filePath),
|
|
@@ -62,11 +62,11 @@ type InlineModuleIdsOptions = $ReadOnly<{
|
|
|
62
62
|
}>;
|
|
63
63
|
|
|
64
64
|
// TS detection conditions copied from metro-react-native-babel-preset
|
|
65
|
-
function isTypeScriptSource(fileName) {
|
|
65
|
+
function isTypeScriptSource(fileName: string) {
|
|
66
66
|
return !!fileName && fileName.endsWith('.ts');
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function isTSXSource(fileName) {
|
|
69
|
+
function isTSXSource(fileName: string) {
|
|
70
70
|
return !!fileName && fileName.endsWith('.tsx');
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
const { Console } = require("console");
|
|
13
13
|
|
|
14
14
|
const { Writable } = require("stream");
|
|
15
|
-
/* $FlowFixMe(>=0.97.0 site=react_native_fb) This comment suppresses an error
|
|
16
|
-
* found when Flow v0.97 was deployed. To see the error delete this comment and
|
|
17
|
-
* run Flow. */
|
|
18
15
|
|
|
19
|
-
const write = (_, __, callback) =>
|
|
16
|
+
const write = (_, __, callback) =>
|
|
17
|
+
/* $FlowFixMe(>=0.97.0 site=react_native_fb) This comment suppresses an error
|
|
18
|
+
* found when Flow v0.97 was deployed. To see the error delete this comment and
|
|
19
|
+
* run Flow. */
|
|
20
|
+
callback();
|
|
20
21
|
|
|
21
22
|
module.exports = new Console(
|
|
22
23
|
new Writable({
|
|
@@ -13,8 +13,12 @@
|
|
|
13
13
|
const {Console} = require('console');
|
|
14
14
|
const {Writable} = require('stream');
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const write = (
|
|
17
|
+
_: Buffer | string | Array<{chunk: Buffer | string, encoding: string, ...}>,
|
|
18
|
+
__: string | ((error?: Error) => void),
|
|
19
|
+
callback: void | ((error?: Error) => void),
|
|
20
|
+
/* $FlowFixMe(>=0.97.0 site=react_native_fb) This comment suppresses an error
|
|
21
|
+
* found when Flow v0.97 was deployed. To see the error delete this comment and
|
|
22
|
+
* run Flow. */
|
|
23
|
+
) => callback();
|
|
20
24
|
module.exports = (new Console(new Writable({write, writev: write})): Console);
|
|
@@ -53,6 +53,7 @@ function collectDependencies(ast, options) {
|
|
|
53
53
|
dynamicRequires: options.dynamicRequires,
|
|
54
54
|
keepRequireNames: options.keepRequireNames,
|
|
55
55
|
allowOptionalDependencies: options.allowOptionalDependencies,
|
|
56
|
+
unstable_allowRequireContext: options.unstable_allowRequireContext,
|
|
56
57
|
};
|
|
57
58
|
const visitor = {
|
|
58
59
|
CallExpression(path, state) {
|
|
@@ -97,6 +98,22 @@ function collectDependencies(ast, options) {
|
|
|
97
98
|
splitCondition: args[1],
|
|
98
99
|
});
|
|
99
100
|
return;
|
|
101
|
+
} // Match `require.context`
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
// Feature gate, defaults to `false`.
|
|
105
|
+
state.unstable_allowRequireContext &&
|
|
106
|
+
callee.type === "MemberExpression" && // `require`
|
|
107
|
+
callee.object.type === "Identifier" &&
|
|
108
|
+
callee.object.name === "require" && // `context`
|
|
109
|
+
callee.property.type === "Identifier" &&
|
|
110
|
+
callee.property.name === "context" &&
|
|
111
|
+
!callee.computed && // Ensure `require` refers to the global and not something else.
|
|
112
|
+
!path.scope.getBinding("require")
|
|
113
|
+
) {
|
|
114
|
+
processRequireContextCall(path, state);
|
|
115
|
+
visited.add(path.node);
|
|
116
|
+
return;
|
|
100
117
|
}
|
|
101
118
|
|
|
102
119
|
if (
|
|
@@ -148,6 +165,146 @@ function collectDependencies(ast, options) {
|
|
|
148
165
|
dependencyMapName: nullthrows(state.dependencyMapIdentifier).name,
|
|
149
166
|
};
|
|
150
167
|
}
|
|
168
|
+
/** Extract args passed to the `require.context` method. */
|
|
169
|
+
|
|
170
|
+
function getRequireContextArgs(path) {
|
|
171
|
+
const args = path.get("arguments");
|
|
172
|
+
let directory;
|
|
173
|
+
|
|
174
|
+
if (!Array.isArray(args) || args.length < 1) {
|
|
175
|
+
throw new InvalidRequireCallError(path);
|
|
176
|
+
} else {
|
|
177
|
+
const result = args[0].evaluate();
|
|
178
|
+
|
|
179
|
+
if (result.confident && typeof result.value === "string") {
|
|
180
|
+
directory = result.value;
|
|
181
|
+
} else {
|
|
182
|
+
var _result$deopt;
|
|
183
|
+
|
|
184
|
+
throw new InvalidRequireCallError(
|
|
185
|
+
(_result$deopt = result.deopt) !== null && _result$deopt !== void 0
|
|
186
|
+
? _result$deopt
|
|
187
|
+
: args[0],
|
|
188
|
+
"First argument of `require.context` should be a string denoting the directory to require."
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
} // Default to requiring through all directories.
|
|
192
|
+
|
|
193
|
+
let recursive = true;
|
|
194
|
+
|
|
195
|
+
if (args.length > 1) {
|
|
196
|
+
const result = args[1].evaluate();
|
|
197
|
+
|
|
198
|
+
if (result.confident && typeof result.value === "boolean") {
|
|
199
|
+
recursive = result.value;
|
|
200
|
+
} else if (!(result.confident && typeof result.value === "undefined")) {
|
|
201
|
+
var _result$deopt2;
|
|
202
|
+
|
|
203
|
+
throw new InvalidRequireCallError(
|
|
204
|
+
(_result$deopt2 = result.deopt) !== null && _result$deopt2 !== void 0
|
|
205
|
+
? _result$deopt2
|
|
206
|
+
: args[1],
|
|
207
|
+
"Second argument of `require.context` should be an optional boolean indicating if files should be imported recursively or not."
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
} // Default to all files.
|
|
211
|
+
|
|
212
|
+
let filter = {
|
|
213
|
+
pattern: ".*",
|
|
214
|
+
flags: "",
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
if (args.length > 2) {
|
|
218
|
+
// evaluate() to check for undefined (because it's technically a scope lookup)
|
|
219
|
+
// but check the AST for the regex literal, since evaluate() doesn't do regex.
|
|
220
|
+
const result = args[2].evaluate();
|
|
221
|
+
const argNode = args[2].node;
|
|
222
|
+
|
|
223
|
+
if (argNode.type === "RegExpLiteral") {
|
|
224
|
+
// TODO: Handle `new RegExp(...)` -- `argNode.type === 'NewExpression'`
|
|
225
|
+
filter = {
|
|
226
|
+
pattern: argNode.pattern,
|
|
227
|
+
flags: argNode.flags || "",
|
|
228
|
+
};
|
|
229
|
+
} else if (!(result.confident && typeof result.value === "undefined")) {
|
|
230
|
+
throw new InvalidRequireCallError(
|
|
231
|
+
args[2],
|
|
232
|
+
`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}.`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
} // Default to `sync`.
|
|
236
|
+
|
|
237
|
+
let mode = "sync";
|
|
238
|
+
|
|
239
|
+
if (args.length > 3) {
|
|
240
|
+
const result = args[3].evaluate();
|
|
241
|
+
|
|
242
|
+
if (result.confident && typeof result.value === "string") {
|
|
243
|
+
mode = getContextMode(args[3], result.value);
|
|
244
|
+
} else if (!(result.confident && typeof result.value === "undefined")) {
|
|
245
|
+
var _result$deopt3;
|
|
246
|
+
|
|
247
|
+
throw new InvalidRequireCallError(
|
|
248
|
+
(_result$deopt3 = result.deopt) !== null && _result$deopt3 !== void 0
|
|
249
|
+
? _result$deopt3
|
|
250
|
+
: args[3],
|
|
251
|
+
'Fourth argument of `require.context` should be an optional string "mode" denoting how the modules will be resolved.'
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (args.length > 4) {
|
|
257
|
+
throw new InvalidRequireCallError(
|
|
258
|
+
path,
|
|
259
|
+
`Too many arguments provided to \`require.context\` call. Expected 4, got: ${args.length}`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return [
|
|
264
|
+
directory,
|
|
265
|
+
{
|
|
266
|
+
recursive,
|
|
267
|
+
filter,
|
|
268
|
+
mode,
|
|
269
|
+
},
|
|
270
|
+
];
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function getContextMode(path, mode) {
|
|
274
|
+
if (
|
|
275
|
+
mode === "sync" ||
|
|
276
|
+
mode === "eager" ||
|
|
277
|
+
mode === "lazy" ||
|
|
278
|
+
mode === "lazy-once"
|
|
279
|
+
) {
|
|
280
|
+
return mode;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
throw new InvalidRequireCallError(
|
|
284
|
+
path,
|
|
285
|
+
`require.context "${mode}" mode is not supported. Expected one of: sync, eager, lazy, lazy-once`
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function processRequireContextCall(path, state) {
|
|
290
|
+
const [directory, contextParams] = getRequireContextArgs(path);
|
|
291
|
+
const transformer = state.dependencyTransformer;
|
|
292
|
+
const dep = registerDependency(
|
|
293
|
+
state,
|
|
294
|
+
{
|
|
295
|
+
// We basically want to "import" every file in a folder and then filter them out with the given `filter` RegExp.
|
|
296
|
+
name: directory,
|
|
297
|
+
// Capture the matching context
|
|
298
|
+
contextParams,
|
|
299
|
+
asyncType: null,
|
|
300
|
+
optional: isOptionalDependency(directory, path, state),
|
|
301
|
+
},
|
|
302
|
+
path
|
|
303
|
+
); // require() the generated module representing this context
|
|
304
|
+
|
|
305
|
+
path.get("callee").replaceWith(types.identifier("require"));
|
|
306
|
+
transformer.transformSyncRequire(path, dep, state);
|
|
307
|
+
}
|
|
151
308
|
|
|
152
309
|
function collectImports(path, state) {
|
|
153
310
|
if (path.node.source) {
|
|
@@ -309,10 +466,15 @@ function getModuleNameFromCallArgs(path) {
|
|
|
309
466
|
collectDependencies.getModuleNameFromCallArgs = getModuleNameFromCallArgs;
|
|
310
467
|
|
|
311
468
|
class InvalidRequireCallError extends Error {
|
|
312
|
-
constructor({ node }) {
|
|
469
|
+
constructor({ node }, message) {
|
|
313
470
|
const line = node.loc && node.loc.start && node.loc.start.line;
|
|
314
471
|
super(
|
|
315
|
-
|
|
472
|
+
[
|
|
473
|
+
`Invalid call at line ${line || "<unknown>"}: ${generate(node).code}`,
|
|
474
|
+
message,
|
|
475
|
+
]
|
|
476
|
+
.filter(Boolean)
|
|
477
|
+
.join("\n")
|
|
316
478
|
);
|
|
317
479
|
}
|
|
318
480
|
}
|
|
@@ -348,9 +510,11 @@ const makeJSResourceTemplate = template.statement(`
|
|
|
348
510
|
const DefaultDependencyTransformer = {
|
|
349
511
|
transformSyncRequire(path, dependency, state) {
|
|
350
512
|
const moduleIDExpression = createModuleIDExpression(dependency, state);
|
|
351
|
-
path.node.arguments =
|
|
352
|
-
|
|
353
|
-
|
|
513
|
+
path.node.arguments = [moduleIDExpression]; // Always add the debug name argument last
|
|
514
|
+
|
|
515
|
+
if (state.keepRequireNames) {
|
|
516
|
+
path.node.arguments.push(types.stringLiteral(dependency.name));
|
|
517
|
+
}
|
|
354
518
|
},
|
|
355
519
|
|
|
356
520
|
transformImportCall(path, dependency, state) {
|
|
@@ -420,12 +584,51 @@ function createModuleIDExpression(dependency, state) {
|
|
|
420
584
|
function createModuleNameLiteral(dependency) {
|
|
421
585
|
return types.stringLiteral(dependency.name);
|
|
422
586
|
}
|
|
587
|
+
/**
|
|
588
|
+
* 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
|
+
*
|
|
592
|
+
* For example, the following case would have collision issues if they all utilized the `name` property:
|
|
593
|
+
* ```
|
|
594
|
+
* require('./foo');
|
|
595
|
+
* require.context('./foo');
|
|
596
|
+
* require.context('./foo', true, /something/);
|
|
597
|
+
* require.context('./foo', false, /something/);
|
|
598
|
+
* require.context('./foo', false, /something/, 'lazy');
|
|
599
|
+
* ```
|
|
600
|
+
*
|
|
601
|
+
* This method should be utilized by `registerDependency`.
|
|
602
|
+
*/
|
|
603
|
+
|
|
604
|
+
function getKeyForDependency(qualifier) {
|
|
605
|
+
let key = qualifier.name;
|
|
606
|
+
const { contextParams } = qualifier; // Add extra qualifiers when using `require.context` to prevent collisions.
|
|
607
|
+
|
|
608
|
+
if (contextParams) {
|
|
609
|
+
// NOTE(EvanBacon): Keep this synchronized with `RequireContextParams`, if any other properties are added
|
|
610
|
+
// then this key algorithm should be updated to account for those properties.
|
|
611
|
+
// Example: `./directory__true__/foobar/m__lazy`
|
|
612
|
+
key += [
|
|
613
|
+
"",
|
|
614
|
+
"context",
|
|
615
|
+
String(contextParams.recursive),
|
|
616
|
+
String(contextParams.filter.pattern),
|
|
617
|
+
String(contextParams.filter.flags),
|
|
618
|
+
contextParams.mode, // Join together and append to the name:
|
|
619
|
+
].join("__");
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
return key;
|
|
623
|
+
}
|
|
423
624
|
|
|
424
625
|
class DefaultModuleDependencyRegistry {
|
|
425
626
|
_dependencies = new Map();
|
|
426
627
|
|
|
427
628
|
registerDependency(qualifier) {
|
|
428
|
-
|
|
629
|
+
const key = getKeyForDependency(qualifier);
|
|
630
|
+
|
|
631
|
+
let dependency = this._dependencies.get(key);
|
|
429
632
|
|
|
430
633
|
if (dependency == null) {
|
|
431
634
|
const newDependency = {
|
|
@@ -439,15 +642,19 @@ class DefaultModuleDependencyRegistry {
|
|
|
439
642
|
newDependency.isOptional = true;
|
|
440
643
|
}
|
|
441
644
|
|
|
645
|
+
if (qualifier.contextParams) {
|
|
646
|
+
newDependency.contextParams = qualifier.contextParams;
|
|
647
|
+
}
|
|
648
|
+
|
|
442
649
|
dependency = newDependency;
|
|
443
650
|
|
|
444
|
-
this._dependencies.set(
|
|
651
|
+
this._dependencies.set(key, dependency);
|
|
445
652
|
} else {
|
|
446
653
|
const original = dependency;
|
|
447
654
|
dependency = collapseDependencies(original, qualifier);
|
|
448
655
|
|
|
449
656
|
if (original !== dependency) {
|
|
450
|
-
this._dependencies.set(
|
|
657
|
+
this._dependencies.set(key, dependency);
|
|
451
658
|
}
|
|
452
659
|
}
|
|
453
660
|
|