webpack 4.1.0 → 4.4.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.
Files changed (118) hide show
  1. package/README.md +719 -721
  2. package/bin/webpack.js +69 -10
  3. package/lib/APIPlugin.js +84 -84
  4. package/lib/AmdMainTemplatePlugin.js +75 -77
  5. package/lib/AsyncDependencyToInitialChunkError.js +21 -23
  6. package/lib/BannerPlugin.js +101 -101
  7. package/lib/Chunk.js +477 -469
  8. package/lib/ChunkTemplate.js +51 -53
  9. package/lib/Compilation.js +1858 -1851
  10. package/lib/Compiler.js +493 -478
  11. package/lib/ConcurrentCompilationError.js +19 -0
  12. package/lib/ContextModule.js +696 -685
  13. package/lib/ContextModuleFactory.js +245 -243
  14. package/lib/DefinePlugin.js +197 -197
  15. package/lib/DelegatedModule.js +101 -101
  16. package/lib/DependenciesBlockVariable.js +51 -52
  17. package/lib/Dependency.js +53 -52
  18. package/lib/DllModule.js +54 -54
  19. package/lib/DllModuleFactory.js +29 -29
  20. package/lib/EnvironmentPlugin.js +65 -67
  21. package/lib/EvalDevToolModuleTemplatePlugin.js +60 -60
  22. package/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +105 -105
  23. package/lib/ExportPropertyMainTemplatePlugin.js +40 -40
  24. package/lib/ExternalModule.js +159 -159
  25. package/lib/FunctionModuleTemplatePlugin.js +98 -98
  26. package/lib/HotModuleReplacement.runtime.js +631 -631
  27. package/lib/HotModuleReplacementPlugin.js +407 -406
  28. package/lib/HotUpdateChunkTemplate.js +78 -80
  29. package/lib/JavascriptGenerator.js +228 -229
  30. package/lib/JavascriptModulesPlugin.js +184 -158
  31. package/lib/JsonGenerator.js +42 -42
  32. package/lib/MainTemplate.js +406 -402
  33. package/lib/Module.js +343 -340
  34. package/lib/ModuleBuildError.js +42 -42
  35. package/lib/ModuleError.js +28 -28
  36. package/lib/ModuleFilenameHelpers.js +166 -166
  37. package/lib/ModuleTemplate.js +77 -79
  38. package/lib/ModuleWarning.js +30 -30
  39. package/lib/MultiCompiler.js +271 -259
  40. package/lib/MultiModule.js +78 -75
  41. package/lib/MultiModuleFactory.js +23 -23
  42. package/lib/MultiWatching.js +38 -37
  43. package/lib/NoModeWarning.js +23 -21
  44. package/lib/NormalModule.js +478 -470
  45. package/lib/NormalModuleFactory.js +483 -481
  46. package/lib/OptionsDefaulter.js +80 -86
  47. package/lib/Parser.js +2074 -2071
  48. package/lib/ProgressPlugin.js +231 -231
  49. package/lib/RawModule.js +54 -55
  50. package/lib/RecordIdsPlugin.js +160 -160
  51. package/lib/RemovedPluginError.js +13 -13
  52. package/lib/ResolverFactory.js +64 -67
  53. package/lib/RuntimeTemplate.js +267 -297
  54. package/lib/SetVarMainTemplatePlugin.js +57 -57
  55. package/lib/SourceMapDevToolPlugin.js +302 -308
  56. package/lib/Stats.js +1234 -1212
  57. package/lib/Template.js +205 -205
  58. package/lib/TemplatedPathPlugin.js +170 -143
  59. package/lib/UmdMainTemplatePlugin.js +264 -269
  60. package/lib/Watching.js +193 -193
  61. package/lib/WebAssemblyParser.js +50 -54
  62. package/lib/WebpackOptionsApply.js +401 -401
  63. package/lib/WebpackOptionsDefaulter.js +337 -317
  64. package/lib/WebpackOptionsValidationError.js +316 -319
  65. package/lib/debug/ProfilingPlugin.js +409 -405
  66. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +328 -311
  67. package/lib/dependencies/AMDRequireContextDependency.js +20 -20
  68. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +270 -241
  69. package/lib/dependencies/HarmonyAcceptImportDependency.js +23 -23
  70. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +620 -606
  71. package/lib/dependencies/HarmonyExportSpecifierDependency.js +53 -53
  72. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +214 -214
  73. package/lib/dependencies/HarmonyImportSpecifierDependency.js +154 -156
  74. package/lib/dependencies/ImportDependenciesBlock.js +17 -17
  75. package/lib/dependencies/ImportDependency.js +34 -34
  76. package/lib/dependencies/ImportEagerDependency.js +32 -32
  77. package/lib/dependencies/ImportParserPlugin.js +175 -179
  78. package/lib/dependencies/ImportWeakDependency.js +34 -34
  79. package/lib/dependencies/JsonExportsDependency.js +25 -25
  80. package/lib/dependencies/ModuleDependency.js +20 -20
  81. package/lib/dependencies/NullDependency.js +20 -20
  82. package/lib/dependencies/RequireContextDependency.js +22 -22
  83. package/lib/dependencies/RequireIncludeDependency.js +40 -40
  84. package/lib/dependencies/WebpackMissingModule.js +20 -22
  85. package/lib/node/NodeChunkTemplatePlugin.js +31 -31
  86. package/lib/node/NodeHotUpdateChunkTemplatePlugin.js +36 -36
  87. package/lib/node/NodeMainTemplatePlugin.js +320 -273
  88. package/lib/node/ReadFileCompileWasmMainTemplatePlugin.js +113 -115
  89. package/lib/optimize/AggressiveSplittingPlugin.js +281 -281
  90. package/lib/optimize/ConcatenatedModule.js +1364 -1366
  91. package/lib/optimize/RemoveParentModulesPlugin.js +114 -114
  92. package/lib/optimize/SplitChunksPlugin.js +519 -491
  93. package/lib/performance/SizeLimitsPlugin.js +105 -105
  94. package/lib/util/TrackingSet.js +35 -35
  95. package/lib/util/objectToMap.js +10 -10
  96. package/lib/wasm/WasmModuleTemplatePlugin.js +106 -106
  97. package/lib/web/JsonpChunkTemplatePlugin.js +47 -47
  98. package/lib/web/JsonpExportMainTemplatePlugin.js +47 -47
  99. package/lib/web/JsonpHotUpdateChunkTemplatePlugin.js +39 -39
  100. package/lib/web/JsonpMainTemplatePlugin.js +425 -403
  101. package/lib/webpack.js +182 -179
  102. package/lib/webworker/WebWorkerChunkTemplatePlugin.js +35 -35
  103. package/lib/webworker/WebWorkerHotUpdateChunkTemplatePlugin.js +40 -40
  104. package/lib/webworker/WebWorkerMainTemplatePlugin.js +177 -154
  105. package/package.json +9 -8
  106. package/schemas/WebpackOptions.json +1973 -1951
  107. package/schemas/ajv.absolutePath.js +55 -29
  108. package/schemas/plugins/BannerPlugin.json +85 -85
  109. package/schemas/plugins/DllPlugin.json +28 -28
  110. package/schemas/plugins/DllReferencePlugin.json +99 -99
  111. package/schemas/plugins/HashedModuleIdsPlugin.json +24 -24
  112. package/schemas/plugins/LoaderOptionsPlugin.json +26 -26
  113. package/schemas/plugins/SourceMapDevToolPlugin.json +187 -187
  114. package/schemas/plugins/WatchIgnorePlugin.json +16 -16
  115. package/schemas/plugins/debug/ProfilingPlugin.json +12 -12
  116. package/schemas/plugins/optimize/AggressiveSplittingPlugin.json +22 -22
  117. package/schemas/plugins/optimize/LimitChunkCountPlugin.json +15 -15
  118. package/schemas/plugins/optimize/MinChunkSizePlugin.json +13 -13
@@ -1,481 +1,483 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- */
5
- "use strict";
6
-
7
- const asyncLib = require("neo-async");
8
- const Tapable = require("tapable").Tapable;
9
- const AsyncSeriesWaterfallHook = require("tapable").AsyncSeriesWaterfallHook;
10
- const SyncWaterfallHook = require("tapable").SyncWaterfallHook;
11
- const SyncBailHook = require("tapable").SyncBailHook;
12
- const SyncHook = require("tapable").SyncHook;
13
- const HookMap = require("tapable").HookMap;
14
- const NormalModule = require("./NormalModule");
15
- const RawModule = require("./RawModule");
16
- const RuleSet = require("./RuleSet");
17
- const cachedMerge = require("./util/cachedMerge");
18
-
19
- const EMPTY_RESOLVE_OPTIONS = {};
20
-
21
- const loaderToIdent = data => {
22
- if (!data.options) return data.loader;
23
- if (typeof data.options === "string") return data.loader + "?" + data.options;
24
- if (typeof data.options !== "object")
25
- throw new Error("loader options must be string or object");
26
- if (data.ident) return data.loader + "??" + data.ident;
27
- return data.loader + "?" + JSON.stringify(data.options);
28
- };
29
-
30
- const identToLoaderRequest = resultString => {
31
- const idx = resultString.indexOf("?");
32
- let options;
33
-
34
- if (idx >= 0) {
35
- options = resultString.substr(idx + 1);
36
- resultString = resultString.substr(0, idx);
37
-
38
- return {
39
- loader: resultString,
40
- options
41
- };
42
- } else {
43
- return {
44
- loader: resultString
45
- };
46
- }
47
- };
48
-
49
- class NormalModuleFactory extends Tapable {
50
- constructor(context, resolverFactory, options) {
51
- super();
52
- this.hooks = {
53
- resolver: new SyncWaterfallHook(["resolver"]),
54
- factory: new SyncWaterfallHook(["factory"]),
55
- beforeResolve: new AsyncSeriesWaterfallHook(["data"]),
56
- afterResolve: new AsyncSeriesWaterfallHook(["data"]),
57
- createModule: new SyncBailHook(["data"]),
58
- module: new SyncWaterfallHook(["module", "data"]),
59
- createParser: new HookMap(() => new SyncBailHook(["parserOptions"])),
60
- parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])),
61
- createGenerator: new HookMap(
62
- () => new SyncBailHook(["generatorOptions"])
63
- ),
64
- generator: new HookMap(
65
- () => new SyncHook(["generator", "generatorOptions"])
66
- )
67
- };
68
- this._pluginCompat.tap("NormalModuleFactory", options => {
69
- switch (options.name) {
70
- case "before-resolve":
71
- case "after-resolve":
72
- options.async = true;
73
- break;
74
- case "parser":
75
- this.hooks.parser
76
- .for("javascript/auto")
77
- .tap(options.fn.name || "unnamed compat plugin", options.fn);
78
- return true;
79
- }
80
- let match;
81
- match = /^parser (.+)$/.exec(options.name);
82
- if (match) {
83
- this.hooks.parser
84
- .for(match[1])
85
- .tap(
86
- options.fn.name || "unnamed compat plugin",
87
- options.fn.bind(this)
88
- );
89
- return true;
90
- }
91
- match = /^create-parser (.+)$/.exec(options.name);
92
- if (match) {
93
- this.hooks.createParser
94
- .for(match[1])
95
- .tap(
96
- options.fn.name || "unnamed compat plugin",
97
- options.fn.bind(this)
98
- );
99
- return true;
100
- }
101
- });
102
- this.resolverFactory = resolverFactory;
103
- this.ruleSet = new RuleSet(options.defaultRules.concat(options.rules));
104
- this.cachePredicate =
105
- typeof options.unsafeCache === "function"
106
- ? options.unsafeCache
107
- : Boolean.bind(null, options.unsafeCache);
108
- this.context = context || "";
109
- this.parserCache = Object.create(null);
110
- this.generatorCache = Object.create(null);
111
- this.hooks.factory.tap("NormalModuleFactory", () => (result, callback) => {
112
- let resolver = this.hooks.resolver.call(null);
113
-
114
- // Ignored
115
- if (!resolver) return callback();
116
-
117
- resolver(result, (err, data) => {
118
- if (err) return callback(err);
119
-
120
- // Ignored
121
- if (!data) return callback();
122
-
123
- // direct module
124
- if (typeof data.source === "function") return callback(null, data);
125
-
126
- this.hooks.afterResolve.callAsync(data, (err, result) => {
127
- if (err) return callback(err);
128
-
129
- // Ignored
130
- if (!result) return callback();
131
-
132
- let createdModule = this.hooks.createModule.call(result);
133
- if (!createdModule) {
134
- if (!result.request) {
135
- return callback(new Error("Empty dependency (no request)"));
136
- }
137
-
138
- createdModule = new NormalModule(result);
139
- }
140
-
141
- createdModule = this.hooks.module.call(createdModule, result);
142
-
143
- return callback(null, createdModule);
144
- });
145
- });
146
- });
147
- this.hooks.resolver.tap("NormalModuleFactory", () => (data, callback) => {
148
- const contextInfo = data.contextInfo;
149
- const context = data.context;
150
- const request = data.request;
151
-
152
- const noPreAutoLoaders = request.startsWith("-!");
153
- const noAutoLoaders = noPreAutoLoaders || request.startsWith("!");
154
- const noPrePostAutoLoaders = request.startsWith("!!");
155
- let elements = request
156
- .replace(/^-?!+/, "")
157
- .replace(/!!+/g, "!")
158
- .split("!");
159
- let resource = elements.pop();
160
- elements = elements.map(identToLoaderRequest);
161
-
162
- const loaderResolver = this.getResolver("loader");
163
- const normalResolver = this.getResolver("normal", data.resolveOptions);
164
-
165
- asyncLib.parallel(
166
- [
167
- callback =>
168
- this.resolveRequestArray(
169
- contextInfo,
170
- context,
171
- elements,
172
- loaderResolver,
173
- callback
174
- ),
175
- callback => {
176
- if (resource === "" || resource[0] === "?") {
177
- return callback(null, {
178
- resource
179
- });
180
- }
181
-
182
- normalResolver.resolve(
183
- contextInfo,
184
- context,
185
- resource,
186
- {},
187
- (err, resource, resourceResolveData) => {
188
- if (err) return callback(err);
189
- callback(null, {
190
- resourceResolveData,
191
- resource
192
- });
193
- }
194
- );
195
- }
196
- ],
197
- (err, results) => {
198
- if (err) return callback(err);
199
- let loaders = results[0];
200
- const resourceResolveData = results[1].resourceResolveData;
201
- resource = results[1].resource;
202
-
203
- // translate option idents
204
- try {
205
- for (const item of loaders) {
206
- if (typeof item.options === "string" && item.options[0] === "?") {
207
- const ident = item.options.substr(1);
208
- item.options = this.ruleSet.findOptionsByIdent(ident);
209
- item.ident = ident;
210
- }
211
- }
212
- } catch (e) {
213
- return callback(e);
214
- }
215
-
216
- if (resource === false) {
217
- // ignored
218
- return callback(
219
- null,
220
- new RawModule(
221
- "/* (ignored) */",
222
- `ignored ${context} ${request}`,
223
- `${request} (ignored)`
224
- )
225
- );
226
- }
227
-
228
- const userRequest = loaders
229
- .map(loaderToIdent)
230
- .concat([resource])
231
- .join("!");
232
-
233
- let resourcePath = resource;
234
- let resourceQuery = "";
235
- const queryIndex = resourcePath.indexOf("?");
236
- if (queryIndex >= 0) {
237
- resourceQuery = resourcePath.substr(queryIndex);
238
- resourcePath = resourcePath.substr(0, queryIndex);
239
- }
240
-
241
- const result = this.ruleSet.exec({
242
- resource: resourcePath,
243
- resourceQuery,
244
- issuer: contextInfo.issuer,
245
- compiler: contextInfo.compiler
246
- });
247
- const settings = {};
248
- const useLoadersPost = [];
249
- const useLoaders = [];
250
- const useLoadersPre = [];
251
- for (const r of result) {
252
- if (r.type === "use") {
253
- if (r.enforce === "post" && !noPrePostAutoLoaders)
254
- useLoadersPost.push(r.value);
255
- else if (
256
- r.enforce === "pre" &&
257
- !noPreAutoLoaders &&
258
- !noPrePostAutoLoaders
259
- )
260
- useLoadersPre.push(r.value);
261
- else if (!r.enforce && !noAutoLoaders && !noPrePostAutoLoaders)
262
- useLoaders.push(r.value);
263
- } else if (
264
- typeof r.value === "object" &&
265
- r.value !== null &&
266
- typeof settings[r.type] === "object" &&
267
- settings[r.type] !== null
268
- ) {
269
- settings[r.type] = cachedMerge(settings[r.type], r.value);
270
- } else {
271
- settings[r.type] = r.value;
272
- }
273
- }
274
- asyncLib.parallel(
275
- [
276
- this.resolveRequestArray.bind(
277
- this,
278
- contextInfo,
279
- this.context,
280
- useLoadersPost,
281
- loaderResolver
282
- ),
283
- this.resolveRequestArray.bind(
284
- this,
285
- contextInfo,
286
- this.context,
287
- useLoaders,
288
- loaderResolver
289
- ),
290
- this.resolveRequestArray.bind(
291
- this,
292
- contextInfo,
293
- this.context,
294
- useLoadersPre,
295
- loaderResolver
296
- )
297
- ],
298
- (err, results) => {
299
- if (err) return callback(err);
300
- loaders = results[0].concat(loaders, results[1], results[2]);
301
- process.nextTick(() => {
302
- const type = settings.type;
303
- const resolveOptions = settings.resolve;
304
- callback(null, {
305
- context: context,
306
- request: loaders
307
- .map(loaderToIdent)
308
- .concat([resource])
309
- .join("!"),
310
- dependencies: data.dependencies,
311
- userRequest,
312
- rawRequest: request,
313
- loaders,
314
- resource,
315
- resourceResolveData,
316
- settings,
317
- type,
318
- parser: this.getParser(type, settings.parser),
319
- generator: this.getGenerator(type, settings.generator),
320
- resolveOptions
321
- });
322
- });
323
- }
324
- );
325
- }
326
- );
327
- });
328
- }
329
-
330
- create(data, callback) {
331
- const dependencies = data.dependencies;
332
- const cacheEntry = dependencies[0].__NormalModuleFactoryCache;
333
- if (cacheEntry) return callback(null, cacheEntry);
334
- const context = data.context || this.context;
335
- const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS;
336
- const request = dependencies[0].request;
337
- const contextInfo = data.contextInfo || {};
338
- this.hooks.beforeResolve.callAsync(
339
- {
340
- contextInfo,
341
- resolveOptions,
342
- context,
343
- request,
344
- dependencies
345
- },
346
- (err, result) => {
347
- if (err) return callback(err);
348
-
349
- // Ignored
350
- if (!result) return callback();
351
-
352
- const factory = this.hooks.factory.call(null);
353
-
354
- // Ignored
355
- if (!factory) return callback();
356
-
357
- factory(result, (err, module) => {
358
- if (err) return callback(err);
359
-
360
- if (module && this.cachePredicate(module)) {
361
- for (const d of dependencies) {
362
- d.__NormalModuleFactoryCache = module;
363
- }
364
- }
365
-
366
- callback(null, module);
367
- });
368
- }
369
- );
370
- }
371
-
372
- resolveRequestArray(contextInfo, context, array, resolver, callback) {
373
- if (array.length === 0) return callback(null, []);
374
- asyncLib.map(
375
- array,
376
- (item, callback) => {
377
- resolver.resolve(
378
- contextInfo,
379
- context,
380
- item.loader,
381
- {},
382
- (err, result) => {
383
- if (
384
- err &&
385
- /^[^/]*$/.test(item.loader) &&
386
- !/-loader$/.test(item.loader)
387
- ) {
388
- return resolver.resolve(
389
- contextInfo,
390
- context,
391
- item.loader + "-loader",
392
- {},
393
- err2 => {
394
- if (!err2) {
395
- err.message =
396
- err.message +
397
- "\n" +
398
- "BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.\n" +
399
- ` You need to specify '${
400
- item.loader
401
- }-loader' instead of '${item.loader}',\n` +
402
- " see https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed";
403
- }
404
- callback(err);
405
- }
406
- );
407
- }
408
- if (err) return callback(err);
409
-
410
- const optionsOnly = item.options
411
- ? {
412
- options: item.options
413
- }
414
- : undefined;
415
- return callback(
416
- null,
417
- Object.assign({}, item, identToLoaderRequest(result), optionsOnly)
418
- );
419
- }
420
- );
421
- },
422
- callback
423
- );
424
- }
425
-
426
- getParser(type, parserOptions) {
427
- let ident = type;
428
- if (parserOptions) {
429
- if (parserOptions.ident) ident = `${type}|${parserOptions.ident}`;
430
- else ident = JSON.stringify([type, parserOptions]);
431
- }
432
- if (ident in this.parserCache) {
433
- return this.parserCache[ident];
434
- }
435
- return (this.parserCache[ident] = this.createParser(type, parserOptions));
436
- }
437
-
438
- createParser(type, parserOptions = {}) {
439
- const parser = this.hooks.createParser.for(type).call(parserOptions);
440
- if (!parser) {
441
- throw new Error(`No parser registered for ${type}`);
442
- }
443
- this.hooks.parser.for(type).call(parser, parserOptions);
444
- return parser;
445
- }
446
-
447
- getGenerator(type, generatorOptions) {
448
- let ident = type;
449
- if (generatorOptions) {
450
- if (generatorOptions.ident) ident = `${type}|${generatorOptions.ident}`;
451
- else ident = JSON.stringify([type, generatorOptions]);
452
- }
453
- if (ident in this.generatorCache) {
454
- return this.generatorCache[ident];
455
- }
456
- return (this.generatorCache[ident] = this.createGenerator(
457
- type,
458
- generatorOptions
459
- ));
460
- }
461
-
462
- createGenerator(type, generatorOptions = {}) {
463
- const generator = this.hooks.createGenerator
464
- .for(type)
465
- .call(generatorOptions);
466
- if (!generator) {
467
- throw new Error(`No generator registered for ${type}`);
468
- }
469
- this.hooks.generator.for(type).call(generator, generatorOptions);
470
- return generator;
471
- }
472
-
473
- getResolver(type, resolveOptions) {
474
- return this.resolverFactory.get(
475
- type,
476
- resolveOptions || EMPTY_RESOLVE_OPTIONS
477
- );
478
- }
479
- }
480
-
481
- module.exports = NormalModuleFactory;
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ "use strict";
6
+
7
+ const asyncLib = require("neo-async");
8
+ const {
9
+ Tapable,
10
+ AsyncSeriesWaterfallHook,
11
+ SyncWaterfallHook,
12
+ SyncBailHook,
13
+ SyncHook,
14
+ HookMap
15
+ } = require("tapable");
16
+ const NormalModule = require("./NormalModule");
17
+ const RawModule = require("./RawModule");
18
+ const RuleSet = require("./RuleSet");
19
+ const cachedMerge = require("./util/cachedMerge");
20
+
21
+ const EMPTY_RESOLVE_OPTIONS = {};
22
+
23
+ const loaderToIdent = data => {
24
+ if (!data.options) return data.loader;
25
+ if (typeof data.options === "string") return data.loader + "?" + data.options;
26
+ if (typeof data.options !== "object")
27
+ throw new Error("loader options must be string or object");
28
+ if (data.ident) return data.loader + "??" + data.ident;
29
+ return data.loader + "?" + JSON.stringify(data.options);
30
+ };
31
+
32
+ const identToLoaderRequest = resultString => {
33
+ const idx = resultString.indexOf("?");
34
+ let options;
35
+
36
+ if (idx >= 0) {
37
+ options = resultString.substr(idx + 1);
38
+ resultString = resultString.substr(0, idx);
39
+
40
+ return {
41
+ loader: resultString,
42
+ options
43
+ };
44
+ } else {
45
+ return {
46
+ loader: resultString
47
+ };
48
+ }
49
+ };
50
+
51
+ class NormalModuleFactory extends Tapable {
52
+ constructor(context, resolverFactory, options) {
53
+ super();
54
+ this.hooks = {
55
+ resolver: new SyncWaterfallHook(["resolver"]),
56
+ factory: new SyncWaterfallHook(["factory"]),
57
+ beforeResolve: new AsyncSeriesWaterfallHook(["data"]),
58
+ afterResolve: new AsyncSeriesWaterfallHook(["data"]),
59
+ createModule: new SyncBailHook(["data"]),
60
+ module: new SyncWaterfallHook(["module", "data"]),
61
+ createParser: new HookMap(() => new SyncBailHook(["parserOptions"])),
62
+ parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])),
63
+ createGenerator: new HookMap(
64
+ () => new SyncBailHook(["generatorOptions"])
65
+ ),
66
+ generator: new HookMap(
67
+ () => new SyncHook(["generator", "generatorOptions"])
68
+ )
69
+ };
70
+ this._pluginCompat.tap("NormalModuleFactory", options => {
71
+ switch (options.name) {
72
+ case "before-resolve":
73
+ case "after-resolve":
74
+ options.async = true;
75
+ break;
76
+ case "parser":
77
+ this.hooks.parser
78
+ .for("javascript/auto")
79
+ .tap(options.fn.name || "unnamed compat plugin", options.fn);
80
+ return true;
81
+ }
82
+ let match;
83
+ match = /^parser (.+)$/.exec(options.name);
84
+ if (match) {
85
+ this.hooks.parser
86
+ .for(match[1])
87
+ .tap(
88
+ options.fn.name || "unnamed compat plugin",
89
+ options.fn.bind(this)
90
+ );
91
+ return true;
92
+ }
93
+ match = /^create-parser (.+)$/.exec(options.name);
94
+ if (match) {
95
+ this.hooks.createParser
96
+ .for(match[1])
97
+ .tap(
98
+ options.fn.name || "unnamed compat plugin",
99
+ options.fn.bind(this)
100
+ );
101
+ return true;
102
+ }
103
+ });
104
+ this.resolverFactory = resolverFactory;
105
+ this.ruleSet = new RuleSet(options.defaultRules.concat(options.rules));
106
+ this.cachePredicate =
107
+ typeof options.unsafeCache === "function"
108
+ ? options.unsafeCache
109
+ : Boolean.bind(null, options.unsafeCache);
110
+ this.context = context || "";
111
+ this.parserCache = Object.create(null);
112
+ this.generatorCache = Object.create(null);
113
+ this.hooks.factory.tap("NormalModuleFactory", () => (result, callback) => {
114
+ let resolver = this.hooks.resolver.call(null);
115
+
116
+ // Ignored
117
+ if (!resolver) return callback();
118
+
119
+ resolver(result, (err, data) => {
120
+ if (err) return callback(err);
121
+
122
+ // Ignored
123
+ if (!data) return callback();
124
+
125
+ // direct module
126
+ if (typeof data.source === "function") return callback(null, data);
127
+
128
+ this.hooks.afterResolve.callAsync(data, (err, result) => {
129
+ if (err) return callback(err);
130
+
131
+ // Ignored
132
+ if (!result) return callback();
133
+
134
+ let createdModule = this.hooks.createModule.call(result);
135
+ if (!createdModule) {
136
+ if (!result.request) {
137
+ return callback(new Error("Empty dependency (no request)"));
138
+ }
139
+
140
+ createdModule = new NormalModule(result);
141
+ }
142
+
143
+ createdModule = this.hooks.module.call(createdModule, result);
144
+
145
+ return callback(null, createdModule);
146
+ });
147
+ });
148
+ });
149
+ this.hooks.resolver.tap("NormalModuleFactory", () => (data, callback) => {
150
+ const contextInfo = data.contextInfo;
151
+ const context = data.context;
152
+ const request = data.request;
153
+
154
+ const noPreAutoLoaders = request.startsWith("-!");
155
+ const noAutoLoaders = noPreAutoLoaders || request.startsWith("!");
156
+ const noPrePostAutoLoaders = request.startsWith("!!");
157
+ let elements = request
158
+ .replace(/^-?!+/, "")
159
+ .replace(/!!+/g, "!")
160
+ .split("!");
161
+ let resource = elements.pop();
162
+ elements = elements.map(identToLoaderRequest);
163
+
164
+ const loaderResolver = this.getResolver("loader");
165
+ const normalResolver = this.getResolver("normal", data.resolveOptions);
166
+
167
+ asyncLib.parallel(
168
+ [
169
+ callback =>
170
+ this.resolveRequestArray(
171
+ contextInfo,
172
+ context,
173
+ elements,
174
+ loaderResolver,
175
+ callback
176
+ ),
177
+ callback => {
178
+ if (resource === "" || resource[0] === "?") {
179
+ return callback(null, {
180
+ resource
181
+ });
182
+ }
183
+
184
+ normalResolver.resolve(
185
+ contextInfo,
186
+ context,
187
+ resource,
188
+ {},
189
+ (err, resource, resourceResolveData) => {
190
+ if (err) return callback(err);
191
+ callback(null, {
192
+ resourceResolveData,
193
+ resource
194
+ });
195
+ }
196
+ );
197
+ }
198
+ ],
199
+ (err, results) => {
200
+ if (err) return callback(err);
201
+ let loaders = results[0];
202
+ const resourceResolveData = results[1].resourceResolveData;
203
+ resource = results[1].resource;
204
+
205
+ // translate option idents
206
+ try {
207
+ for (const item of loaders) {
208
+ if (typeof item.options === "string" && item.options[0] === "?") {
209
+ const ident = item.options.substr(1);
210
+ item.options = this.ruleSet.findOptionsByIdent(ident);
211
+ item.ident = ident;
212
+ }
213
+ }
214
+ } catch (e) {
215
+ return callback(e);
216
+ }
217
+
218
+ if (resource === false) {
219
+ // ignored
220
+ return callback(
221
+ null,
222
+ new RawModule(
223
+ "/* (ignored) */",
224
+ `ignored ${context} ${request}`,
225
+ `${request} (ignored)`
226
+ )
227
+ );
228
+ }
229
+
230
+ const userRequest = loaders
231
+ .map(loaderToIdent)
232
+ .concat([resource])
233
+ .join("!");
234
+
235
+ let resourcePath = resource;
236
+ let resourceQuery = "";
237
+ const queryIndex = resourcePath.indexOf("?");
238
+ if (queryIndex >= 0) {
239
+ resourceQuery = resourcePath.substr(queryIndex);
240
+ resourcePath = resourcePath.substr(0, queryIndex);
241
+ }
242
+
243
+ const result = this.ruleSet.exec({
244
+ resource: resourcePath,
245
+ resourceQuery,
246
+ issuer: contextInfo.issuer,
247
+ compiler: contextInfo.compiler
248
+ });
249
+ const settings = {};
250
+ const useLoadersPost = [];
251
+ const useLoaders = [];
252
+ const useLoadersPre = [];
253
+ for (const r of result) {
254
+ if (r.type === "use") {
255
+ if (r.enforce === "post" && !noPrePostAutoLoaders)
256
+ useLoadersPost.push(r.value);
257
+ else if (
258
+ r.enforce === "pre" &&
259
+ !noPreAutoLoaders &&
260
+ !noPrePostAutoLoaders
261
+ )
262
+ useLoadersPre.push(r.value);
263
+ else if (!r.enforce && !noAutoLoaders && !noPrePostAutoLoaders)
264
+ useLoaders.push(r.value);
265
+ } else if (
266
+ typeof r.value === "object" &&
267
+ r.value !== null &&
268
+ typeof settings[r.type] === "object" &&
269
+ settings[r.type] !== null
270
+ ) {
271
+ settings[r.type] = cachedMerge(settings[r.type], r.value);
272
+ } else {
273
+ settings[r.type] = r.value;
274
+ }
275
+ }
276
+ asyncLib.parallel(
277
+ [
278
+ this.resolveRequestArray.bind(
279
+ this,
280
+ contextInfo,
281
+ this.context,
282
+ useLoadersPost,
283
+ loaderResolver
284
+ ),
285
+ this.resolveRequestArray.bind(
286
+ this,
287
+ contextInfo,
288
+ this.context,
289
+ useLoaders,
290
+ loaderResolver
291
+ ),
292
+ this.resolveRequestArray.bind(
293
+ this,
294
+ contextInfo,
295
+ this.context,
296
+ useLoadersPre,
297
+ loaderResolver
298
+ )
299
+ ],
300
+ (err, results) => {
301
+ if (err) return callback(err);
302
+ loaders = results[0].concat(loaders, results[1], results[2]);
303
+ process.nextTick(() => {
304
+ const type = settings.type;
305
+ const resolveOptions = settings.resolve;
306
+ callback(null, {
307
+ context: context,
308
+ request: loaders
309
+ .map(loaderToIdent)
310
+ .concat([resource])
311
+ .join("!"),
312
+ dependencies: data.dependencies,
313
+ userRequest,
314
+ rawRequest: request,
315
+ loaders,
316
+ resource,
317
+ resourceResolveData,
318
+ settings,
319
+ type,
320
+ parser: this.getParser(type, settings.parser),
321
+ generator: this.getGenerator(type, settings.generator),
322
+ resolveOptions
323
+ });
324
+ });
325
+ }
326
+ );
327
+ }
328
+ );
329
+ });
330
+ }
331
+
332
+ create(data, callback) {
333
+ const dependencies = data.dependencies;
334
+ const cacheEntry = dependencies[0].__NormalModuleFactoryCache;
335
+ if (cacheEntry) return callback(null, cacheEntry);
336
+ const context = data.context || this.context;
337
+ const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS;
338
+ const request = dependencies[0].request;
339
+ const contextInfo = data.contextInfo || {};
340
+ this.hooks.beforeResolve.callAsync(
341
+ {
342
+ contextInfo,
343
+ resolveOptions,
344
+ context,
345
+ request,
346
+ dependencies
347
+ },
348
+ (err, result) => {
349
+ if (err) return callback(err);
350
+
351
+ // Ignored
352
+ if (!result) return callback();
353
+
354
+ const factory = this.hooks.factory.call(null);
355
+
356
+ // Ignored
357
+ if (!factory) return callback();
358
+
359
+ factory(result, (err, module) => {
360
+ if (err) return callback(err);
361
+
362
+ if (module && this.cachePredicate(module)) {
363
+ for (const d of dependencies) {
364
+ d.__NormalModuleFactoryCache = module;
365
+ }
366
+ }
367
+
368
+ callback(null, module);
369
+ });
370
+ }
371
+ );
372
+ }
373
+
374
+ resolveRequestArray(contextInfo, context, array, resolver, callback) {
375
+ if (array.length === 0) return callback(null, []);
376
+ asyncLib.map(
377
+ array,
378
+ (item, callback) => {
379
+ resolver.resolve(
380
+ contextInfo,
381
+ context,
382
+ item.loader,
383
+ {},
384
+ (err, result) => {
385
+ if (
386
+ err &&
387
+ /^[^/]*$/.test(item.loader) &&
388
+ !/-loader$/.test(item.loader)
389
+ ) {
390
+ return resolver.resolve(
391
+ contextInfo,
392
+ context,
393
+ item.loader + "-loader",
394
+ {},
395
+ err2 => {
396
+ if (!err2) {
397
+ err.message =
398
+ err.message +
399
+ "\n" +
400
+ "BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.\n" +
401
+ ` You need to specify '${
402
+ item.loader
403
+ }-loader' instead of '${item.loader}',\n` +
404
+ " see https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed";
405
+ }
406
+ callback(err);
407
+ }
408
+ );
409
+ }
410
+ if (err) return callback(err);
411
+
412
+ const optionsOnly = item.options
413
+ ? {
414
+ options: item.options
415
+ }
416
+ : undefined;
417
+ return callback(
418
+ null,
419
+ Object.assign({}, item, identToLoaderRequest(result), optionsOnly)
420
+ );
421
+ }
422
+ );
423
+ },
424
+ callback
425
+ );
426
+ }
427
+
428
+ getParser(type, parserOptions) {
429
+ let ident = type;
430
+ if (parserOptions) {
431
+ if (parserOptions.ident) ident = `${type}|${parserOptions.ident}`;
432
+ else ident = JSON.stringify([type, parserOptions]);
433
+ }
434
+ if (ident in this.parserCache) {
435
+ return this.parserCache[ident];
436
+ }
437
+ return (this.parserCache[ident] = this.createParser(type, parserOptions));
438
+ }
439
+
440
+ createParser(type, parserOptions = {}) {
441
+ const parser = this.hooks.createParser.for(type).call(parserOptions);
442
+ if (!parser) {
443
+ throw new Error(`No parser registered for ${type}`);
444
+ }
445
+ this.hooks.parser.for(type).call(parser, parserOptions);
446
+ return parser;
447
+ }
448
+
449
+ getGenerator(type, generatorOptions) {
450
+ let ident = type;
451
+ if (generatorOptions) {
452
+ if (generatorOptions.ident) ident = `${type}|${generatorOptions.ident}`;
453
+ else ident = JSON.stringify([type, generatorOptions]);
454
+ }
455
+ if (ident in this.generatorCache) {
456
+ return this.generatorCache[ident];
457
+ }
458
+ return (this.generatorCache[ident] = this.createGenerator(
459
+ type,
460
+ generatorOptions
461
+ ));
462
+ }
463
+
464
+ createGenerator(type, generatorOptions = {}) {
465
+ const generator = this.hooks.createGenerator
466
+ .for(type)
467
+ .call(generatorOptions);
468
+ if (!generator) {
469
+ throw new Error(`No generator registered for ${type}`);
470
+ }
471
+ this.hooks.generator.for(type).call(generator, generatorOptions);
472
+ return generator;
473
+ }
474
+
475
+ getResolver(type, resolveOptions) {
476
+ return this.resolverFactory.get(
477
+ type,
478
+ resolveOptions || EMPTY_RESOLVE_OPTIONS
479
+ );
480
+ }
481
+ }
482
+
483
+ module.exports = NormalModuleFactory;