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
|
@@ -22,19 +22,19 @@ export type BuildResult = GraphResult;
|
|
|
22
22
|
export type Callback<A = void, B = void> = (Error => void) &
|
|
23
23
|
((null | void, A, B) => void);
|
|
24
24
|
|
|
25
|
-
export type Dependency = {
|
|
25
|
+
export type Dependency = {
|
|
26
26
|
// The module name or path used to require the dependency
|
|
27
27
|
id: string,
|
|
28
28
|
+isAsync: boolean,
|
|
29
29
|
+isPrefetchOnly: boolean,
|
|
30
|
-
+splitCondition: ?{
|
|
30
|
+
+splitCondition: ?{
|
|
31
31
|
+mobileConfigName: string,
|
|
32
|
-
|
|
32
|
+
},
|
|
33
33
|
path: string,
|
|
34
34
|
+locs: $ReadOnlyArray<BabelSourceLocation>,
|
|
35
|
-
|
|
35
|
+
};
|
|
36
36
|
|
|
37
|
-
export type File = {
|
|
37
|
+
export type File = {
|
|
38
38
|
code: string,
|
|
39
39
|
map: ?BasicSourceMap,
|
|
40
40
|
functionMap: ?FBSourceFunctionMap,
|
|
@@ -42,7 +42,7 @@ export type File = {|
|
|
|
42
42
|
type: CodeFileTypes,
|
|
43
43
|
libraryIdx: ?number,
|
|
44
44
|
soundResources?: ?Array<string>,
|
|
45
|
-
|
|
45
|
+
};
|
|
46
46
|
|
|
47
47
|
type CodeFileTypes = 'module' | 'script';
|
|
48
48
|
|
|
@@ -51,11 +51,11 @@ export type GraphFn = (
|
|
|
51
51
|
// platform: string,
|
|
52
52
|
) => GraphResult;
|
|
53
53
|
|
|
54
|
-
export type GraphResult = {
|
|
54
|
+
export type GraphResult = {
|
|
55
55
|
modules: Array<Module>,
|
|
56
|
-
|
|
56
|
+
};
|
|
57
57
|
|
|
58
|
-
export type ModuleIds = {
|
|
58
|
+
export type ModuleIds = {
|
|
59
59
|
/**
|
|
60
60
|
* The module ID is global across all segments and identifies the module
|
|
61
61
|
* uniquely. This is useful to cache modules that has been loaded already at
|
|
@@ -71,7 +71,7 @@ export type ModuleIds = {|
|
|
|
71
71
|
* case this property does not apply and will be omitted.
|
|
72
72
|
*/
|
|
73
73
|
+localId?: number,
|
|
74
|
-
|
|
74
|
+
};
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Indempotent function that gets us the IDs corresponding to a particular
|
|
@@ -87,17 +87,17 @@ export type LoadResult = {
|
|
|
87
87
|
|
|
88
88
|
export type LoadFn = (file: string) => LoadResult;
|
|
89
89
|
|
|
90
|
-
export type Module = {
|
|
90
|
+
export type Module = {
|
|
91
91
|
dependencies: Array<Dependency>,
|
|
92
92
|
file: File,
|
|
93
|
-
|
|
93
|
+
};
|
|
94
94
|
|
|
95
95
|
export type PostProcessModules = (
|
|
96
96
|
modules: $ReadOnlyArray<Module>,
|
|
97
97
|
entryPoints: Array<string>,
|
|
98
98
|
) => $ReadOnlyArray<Module>;
|
|
99
99
|
|
|
100
|
-
export type OutputFnArg = {
|
|
100
|
+
export type OutputFnArg = {
|
|
101
101
|
dependencyMapReservedName?: ?string,
|
|
102
102
|
filename: string,
|
|
103
103
|
globalPrefix: string,
|
|
@@ -107,22 +107,22 @@ export type OutputFnArg = {|
|
|
|
107
107
|
sourceMapPath?: ?string,
|
|
108
108
|
enableIDInlining: boolean,
|
|
109
109
|
segmentID: number,
|
|
110
|
-
|
|
110
|
+
};
|
|
111
111
|
export type OutputFn<M: MixedSourceMap = MixedSourceMap> =
|
|
112
112
|
OutputFnArg => OutputResult<M>;
|
|
113
113
|
|
|
114
|
-
export type OutputResult<M: MixedSourceMap> = {
|
|
114
|
+
export type OutputResult<M: MixedSourceMap> = {
|
|
115
115
|
code: string | Buffer,
|
|
116
116
|
extraFiles?: Iterable<[string, string | Buffer]>,
|
|
117
117
|
map: M,
|
|
118
|
-
|
|
118
|
+
};
|
|
119
119
|
|
|
120
|
-
export type PackageData = {
|
|
120
|
+
export type PackageData = {
|
|
121
121
|
browser?: Object | string,
|
|
122
122
|
main?: string,
|
|
123
123
|
name?: string,
|
|
124
124
|
'react-native'?: Object | string,
|
|
125
|
-
|
|
125
|
+
};
|
|
126
126
|
|
|
127
127
|
export type ResolveFn = (id: string, source: ?string) => string;
|
|
128
128
|
|
|
@@ -159,16 +159,16 @@ export type TransformResults = {
|
|
|
159
159
|
|
|
160
160
|
export type TransformVariants = {+[name: string]: {...}};
|
|
161
161
|
|
|
162
|
-
export type TransformedCodeFile = {
|
|
162
|
+
export type TransformedCodeFile = {
|
|
163
163
|
+file: string,
|
|
164
164
|
+functionMap: ?FBSourceFunctionMap,
|
|
165
165
|
+hasteID: ?string,
|
|
166
166
|
+package?: PackageData,
|
|
167
167
|
+transformed: TransformResults,
|
|
168
168
|
+type: CodeFileTypes,
|
|
169
|
-
|
|
169
|
+
};
|
|
170
170
|
|
|
171
|
-
export type ImageSize = {
|
|
171
|
+
export type ImageSize = {+width: number, +height: number};
|
|
172
172
|
|
|
173
173
|
export type AssetFileVariant = $ReadOnly<{
|
|
174
174
|
/**
|
|
@@ -228,24 +228,24 @@ export type AssetFile = $ReadOnly<{
|
|
|
228
228
|
}>;
|
|
229
229
|
|
|
230
230
|
export type TransformedSourceFile =
|
|
231
|
-
| {
|
|
231
|
+
| {
|
|
232
232
|
+type: 'code',
|
|
233
233
|
+details: TransformedCodeFile,
|
|
234
|
-
|
|
235
|
-
| {
|
|
234
|
+
}
|
|
235
|
+
| {
|
|
236
236
|
+type: 'asset',
|
|
237
237
|
+details: AssetFile,
|
|
238
|
-
|
|
239
|
-
| {
|
|
238
|
+
}
|
|
239
|
+
| {
|
|
240
240
|
+type: 'unknown',
|
|
241
|
-
|
|
241
|
+
};
|
|
242
242
|
|
|
243
|
-
export type LibraryOptions = {
|
|
243
|
+
export type LibraryOptions = {
|
|
244
244
|
dependencies?: Array<string>,
|
|
245
245
|
optimize: boolean,
|
|
246
246
|
platform?: string,
|
|
247
247
|
rebasePath: string => string,
|
|
248
|
-
|
|
248
|
+
};
|
|
249
249
|
|
|
250
250
|
export type Base64Content = string;
|
|
251
251
|
export type AssetContents = {
|
|
@@ -258,7 +258,7 @@ export type AssetContentsByPath = {
|
|
|
258
258
|
...
|
|
259
259
|
};
|
|
260
260
|
|
|
261
|
-
export type ResolvedCodeFile = {
|
|
261
|
+
export type ResolvedCodeFile = {
|
|
262
262
|
+codeFile: TransformedCodeFile,
|
|
263
263
|
/**
|
|
264
264
|
* Imagine we have a source file that contains a `require('foo')`. The library
|
|
@@ -267,35 +267,35 @@ export type ResolvedCodeFile = {|
|
|
|
267
267
|
* `{'foo': 'bar/foo.js', 'bar': 'node_modules/bar/index.js'}`.
|
|
268
268
|
*/
|
|
269
269
|
+filePathsByDependencyName: {[dependencyName: string]: string, ...},
|
|
270
|
-
|
|
270
|
+
};
|
|
271
271
|
|
|
272
|
-
export type LibraryBoundCodeFile = {
|
|
272
|
+
export type LibraryBoundCodeFile = {
|
|
273
273
|
...ResolvedCodeFile,
|
|
274
274
|
/**
|
|
275
275
|
* Index of the library that this code file has been exported from.
|
|
276
276
|
*/
|
|
277
277
|
+libraryIdx: number,
|
|
278
|
-
|
|
278
|
+
};
|
|
279
279
|
|
|
280
280
|
/**
|
|
281
281
|
* Describe a set of JavaScript files and the associated assets. It could be
|
|
282
282
|
* depending on modules from other libraries. To be able to resolve these
|
|
283
283
|
* dependencies, these libraries need to be provided by callsites (ex. Buck).
|
|
284
284
|
*/
|
|
285
|
-
export type Library = {
|
|
285
|
+
export type Library = {
|
|
286
286
|
+files: Array<TransformedCodeFile>,
|
|
287
287
|
/* cannot be a Map because it's JSONified later on */
|
|
288
288
|
+assets: AssetContentsByPath,
|
|
289
|
-
|
|
289
|
+
};
|
|
290
290
|
|
|
291
291
|
/**
|
|
292
292
|
* Just like a `Library`, but it also contains module resolutions. For example
|
|
293
293
|
* if there is a `require('foo')` in some JavaScript file, we keep track of the
|
|
294
294
|
* path it resolves to, ex. `beep/glo/foo.js`.
|
|
295
295
|
*/
|
|
296
|
-
export type ResolvedLibrary = {
|
|
296
|
+
export type ResolvedLibrary = {
|
|
297
297
|
+files: $ReadOnlyArray<ResolvedCodeFile>,
|
|
298
298
|
/* cannot be a Map because it's JSONified later on */
|
|
299
299
|
+assets: AssetContentsByPath,
|
|
300
300
|
+isPartiallyResolved?: boolean,
|
|
301
|
-
|
|
301
|
+
};
|
|
@@ -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
|
|