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,1851 +1,1858 @@
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 util = require("util");
9
- const Tapable = require("tapable").Tapable;
10
- const SyncHook = require("tapable").SyncHook;
11
- const SyncBailHook = require("tapable").SyncBailHook;
12
- const SyncWaterfallHook = require("tapable").SyncWaterfallHook;
13
- const AsyncSeriesHook = require("tapable").AsyncSeriesHook;
14
- const EntryModuleNotFoundError = require("./EntryModuleNotFoundError");
15
- const ModuleNotFoundError = require("./ModuleNotFoundError");
16
- const ModuleDependencyWarning = require("./ModuleDependencyWarning");
17
- const ModuleDependencyError = require("./ModuleDependencyError");
18
- const ChunkGroup = require("./ChunkGroup");
19
- const Chunk = require("./Chunk");
20
- const Entrypoint = require("./Entrypoint");
21
- const MainTemplate = require("./MainTemplate");
22
- const ChunkTemplate = require("./ChunkTemplate");
23
- const HotUpdateChunkTemplate = require("./HotUpdateChunkTemplate");
24
- const ModuleTemplate = require("./ModuleTemplate");
25
- const RuntimeTemplate = require("./RuntimeTemplate");
26
- const Dependency = require("./Dependency");
27
- const ChunkRenderError = require("./ChunkRenderError");
28
- const AsyncDependencyToInitialChunkError = require("./AsyncDependencyToInitialChunkError");
29
- const CachedSource = require("webpack-sources").CachedSource;
30
- const Stats = require("./Stats");
31
- const Semaphore = require("./util/Semaphore");
32
- const createHash = require("./util/createHash");
33
- const Queue = require("./util/Queue");
34
- const SortableSet = require("./util/SortableSet");
35
- const GraphHelpers = require("./GraphHelpers");
36
-
37
- const byId = (a, b) => {
38
- if (a.id < b.id) return -1;
39
- if (a.id > b.id) return 1;
40
- return 0;
41
- };
42
-
43
- const byIdOrIdentifier = (a, b) => {
44
- if (a.id < b.id) return -1;
45
- if (a.id > b.id) return 1;
46
- const identA = a.identifier();
47
- const identB = b.identifier();
48
- if (identA < identB) return -1;
49
- if (identA > identB) return 1;
50
- return 0;
51
- };
52
-
53
- const byIndexOrIdentifier = (a, b) => {
54
- if (a.index < b.index) return -1;
55
- if (a.index > b.index) return 1;
56
- const identA = a.identifier();
57
- const identB = b.identifier();
58
- if (identA < identB) return -1;
59
- if (identA > identB) return 1;
60
- return 0;
61
- };
62
-
63
- const iterationBlockVariable = (variables, fn) => {
64
- for (
65
- let indexVariable = 0;
66
- indexVariable < variables.length;
67
- indexVariable++
68
- ) {
69
- const varDep = variables[indexVariable].dependencies;
70
- for (let indexVDep = 0; indexVDep < varDep.length; indexVDep++) {
71
- fn(varDep[indexVDep]);
72
- }
73
- }
74
- };
75
-
76
- const iterationOfArrayCallback = (arr, fn) => {
77
- for (let index = 0; index < arr.length; index++) {
78
- fn(arr[index]);
79
- }
80
- };
81
-
82
- function addAllToSet(set, otherSet) {
83
- for (const item of otherSet) {
84
- set.add(item);
85
- }
86
- }
87
-
88
- class Compilation extends Tapable {
89
- constructor(compiler) {
90
- super();
91
- this.hooks = {
92
- buildModule: new SyncHook(["module"]),
93
- rebuildModule: new SyncHook(["module"]),
94
- failedModule: new SyncHook(["module", "error"]),
95
- succeedModule: new SyncHook(["module"]),
96
-
97
- finishModules: new SyncHook(["modules"]),
98
- finishRebuildingModule: new SyncHook(["module"]),
99
-
100
- unseal: new SyncHook([]),
101
- seal: new SyncHook([]),
102
-
103
- optimizeDependenciesBasic: new SyncBailHook(["modules"]),
104
- optimizeDependencies: new SyncBailHook(["modules"]),
105
- optimizeDependenciesAdvanced: new SyncBailHook(["modules"]),
106
- afterOptimizeDependencies: new SyncHook(["modules"]),
107
-
108
- optimize: new SyncHook([]),
109
-
110
- optimizeModulesBasic: new SyncBailHook(["modules"]),
111
- optimizeModules: new SyncBailHook(["modules"]),
112
- optimizeModulesAdvanced: new SyncBailHook(["modules"]),
113
- afterOptimizeModules: new SyncHook(["modules"]),
114
-
115
- optimizeChunksBasic: new SyncBailHook(["chunks", "chunkGroups"]),
116
- optimizeChunks: new SyncBailHook(["chunks", "chunkGroups"]),
117
- optimizeChunksAdvanced: new SyncBailHook(["chunks", "chunkGroups"]),
118
- afterOptimizeChunks: new SyncHook(["chunks", "chunkGroups"]),
119
-
120
- optimizeTree: new AsyncSeriesHook(["chunks", "modules"]),
121
- afterOptimizeTree: new SyncHook(["chunks", "modules"]),
122
-
123
- optimizeChunkModulesBasic: new SyncBailHook(["chunks", "modules"]),
124
- optimizeChunkModules: new SyncBailHook(["chunks", "modules"]),
125
- optimizeChunkModulesAdvanced: new SyncBailHook(["chunks", "modules"]),
126
- afterOptimizeChunkModules: new SyncHook(["chunks", "modules"]),
127
- shouldRecord: new SyncBailHook([]),
128
-
129
- reviveModules: new SyncHook(["modules", "records"]),
130
- optimizeModuleOrder: new SyncHook(["modules"]),
131
- advancedOptimizeModuleOrder: new SyncHook(["modules"]),
132
- beforeModuleIds: new SyncHook(["modules"]),
133
- moduleIds: new SyncHook(["modules"]),
134
- optimizeModuleIds: new SyncHook(["modules"]),
135
- afterOptimizeModuleIds: new SyncHook(["modules"]),
136
-
137
- reviveChunks: new SyncHook(["chunks", "records"]),
138
- optimizeChunkOrder: new SyncHook(["chunks"]),
139
- beforeChunkIds: new SyncHook(["chunks"]),
140
- optimizeChunkIds: new SyncHook(["chunks"]),
141
- afterOptimizeChunkIds: new SyncHook(["chunks"]),
142
-
143
- recordModules: new SyncHook(["modules", "records"]),
144
- recordChunks: new SyncHook(["chunks", "records"]),
145
-
146
- beforeHash: new SyncHook([]),
147
- afterHash: new SyncHook([]),
148
-
149
- recordHash: new SyncHook(["records"]),
150
-
151
- record: new SyncHook(["compilation", "records"]),
152
-
153
- beforeModuleAssets: new SyncHook([]),
154
- shouldGenerateChunkAssets: new SyncBailHook([]),
155
- beforeChunkAssets: new SyncHook([]),
156
- additionalChunkAssets: new SyncHook(["chunks"]),
157
-
158
- records: new SyncHook(["compilation", "records"]),
159
-
160
- additionalAssets: new AsyncSeriesHook([]),
161
- optimizeChunkAssets: new AsyncSeriesHook(["chunks"]),
162
- afterOptimizeChunkAssets: new SyncHook(["chunks"]),
163
- optimizeAssets: new AsyncSeriesHook(["assets"]),
164
- afterOptimizeAssets: new SyncHook(["assets"]),
165
-
166
- needAdditionalSeal: new SyncBailHook([]),
167
- afterSeal: new AsyncSeriesHook([]),
168
-
169
- chunkHash: new SyncHook(["chunk", "chunkHash"]),
170
- moduleAsset: new SyncHook(["module", "filename"]),
171
- chunkAsset: new SyncHook(["chunk", "filename"]),
172
-
173
- assetPath: new SyncWaterfallHook(["filename", "data"]), // TODO MainTemplate
174
-
175
- needAdditionalPass: new SyncBailHook([]),
176
- childCompiler: new SyncHook([
177
- "childCompiler",
178
- "compilerName",
179
- "compilerIndex"
180
- ]),
181
-
182
- // TODO the following hooks are weirdly located here
183
- // TODO move them for webpack 5
184
- normalModuleLoader: new SyncHook(["loaderContext", "module"]),
185
-
186
- optimizeExtractedChunksBasic: new SyncBailHook(["chunks"]),
187
- optimizeExtractedChunks: new SyncBailHook(["chunks"]),
188
- optimizeExtractedChunksAdvanced: new SyncBailHook(["chunks"]),
189
- afterOptimizeExtractedChunks: new SyncHook(["chunks"])
190
- };
191
- this._pluginCompat.tap("Compilation", options => {
192
- switch (options.name) {
193
- case "optimize-tree":
194
- case "additional-assets":
195
- case "optimize-chunk-assets":
196
- case "optimize-assets":
197
- case "after-seal":
198
- options.async = true;
199
- break;
200
- }
201
- });
202
- this.compiler = compiler;
203
- this.resolverFactory = compiler.resolverFactory;
204
- this.inputFileSystem = compiler.inputFileSystem;
205
- this.requestShortener = compiler.requestShortener;
206
-
207
- const options = (this.options = compiler.options);
208
- this.outputOptions = options && options.output;
209
- this.bail = options && options.bail;
210
- this.profile = options && options.profile;
211
- this.performance = options && options.performance;
212
-
213
- this.mainTemplate = new MainTemplate(this.outputOptions);
214
- this.chunkTemplate = new ChunkTemplate(this.outputOptions);
215
- this.hotUpdateChunkTemplate = new HotUpdateChunkTemplate(
216
- this.outputOptions
217
- );
218
- this.runtimeTemplate = new RuntimeTemplate(
219
- this.outputOptions,
220
- this.requestShortener
221
- );
222
- this.moduleTemplates = {
223
- javascript: new ModuleTemplate(this.runtimeTemplate),
224
- webassembly: new ModuleTemplate(this.runtimeTemplate)
225
- };
226
-
227
- this.semaphore = new Semaphore(options.parallelism || 100);
228
-
229
- this.entries = [];
230
- this._preparedEntrypoints = [];
231
- this.entrypoints = new Map();
232
- this.chunks = [];
233
- this.chunkGroups = [];
234
- this.namedChunkGroups = new Map();
235
- this.namedChunks = new Map();
236
- this.modules = [];
237
- this._modules = new Map();
238
- this.cache = null;
239
- this.records = null;
240
- this.nextFreeModuleIndex = undefined;
241
- this.nextFreeModuleIndex2 = undefined;
242
- this.additionalChunkAssets = [];
243
- this.assets = {};
244
- this.errors = [];
245
- this.warnings = [];
246
- this.children = [];
247
- this.dependencyFactories = new Map();
248
- this.dependencyTemplates = new Map();
249
- this.dependencyTemplates.set("hash", "");
250
- this.childrenCounters = {};
251
- this.usedChunkIds = null;
252
- this.usedModuleIds = null;
253
-
254
- this._buildingModules = new Map();
255
- this._rebuildingModules = new Map();
256
- }
257
-
258
- getStats() {
259
- return new Stats(this);
260
- }
261
-
262
- addModule(module, cacheGroup) {
263
- const identifier = module.identifier();
264
- const alreadyAddedModule = this._modules.get(identifier);
265
- if (alreadyAddedModule) {
266
- return {
267
- module: alreadyAddedModule,
268
- issuer: false,
269
- build: false,
270
- dependencies: false
271
- };
272
- }
273
- const cacheName = (cacheGroup || "m") + identifier;
274
- if (this.cache && this.cache[cacheName]) {
275
- const cacheModule = this.cache[cacheName];
276
-
277
- let rebuild = true;
278
- if (this.fileTimestamps && this.contextTimestamps) {
279
- rebuild = cacheModule.needRebuild(
280
- this.fileTimestamps,
281
- this.contextTimestamps
282
- );
283
- }
284
-
285
- if (!rebuild) {
286
- cacheModule.disconnect();
287
- this._modules.set(identifier, cacheModule);
288
- this.modules.push(cacheModule);
289
- for (const err of cacheModule.errors) this.errors.push(err);
290
- for (const err of cacheModule.warnings) this.warnings.push(err);
291
- return {
292
- module: cacheModule,
293
- issuer: true,
294
- build: false,
295
- dependencies: true
296
- };
297
- }
298
- cacheModule.unbuild();
299
- module = cacheModule;
300
- }
301
- this._modules.set(identifier, module);
302
- if (this.cache) {
303
- this.cache[cacheName] = module;
304
- }
305
- this.modules.push(module);
306
- return {
307
- module: module,
308
- issuer: true,
309
- build: true,
310
- dependencies: true
311
- };
312
- }
313
-
314
- getModule(module) {
315
- const identifier = module.identifier();
316
- return this._modules.get(identifier);
317
- }
318
-
319
- findModule(identifier) {
320
- return this._modules.get(identifier);
321
- }
322
-
323
- waitForBuildingFinished(module, callback) {
324
- let callbackList = this._buildingModules.get(module);
325
- if (callbackList) {
326
- callbackList.push(() => callback());
327
- } else {
328
- process.nextTick(callback);
329
- }
330
- }
331
-
332
- buildModule(module, optional, origin, dependencies, thisCallback) {
333
- let callbackList = this._buildingModules.get(module);
334
- if (callbackList) {
335
- callbackList.push(thisCallback);
336
- return;
337
- }
338
- this._buildingModules.set(module, (callbackList = [thisCallback]));
339
-
340
- const callback = err => {
341
- this._buildingModules.delete(module);
342
- for (const cb of callbackList) cb(err);
343
- };
344
-
345
- this.hooks.buildModule.call(module);
346
- module.build(
347
- this.options,
348
- this,
349
- this.resolverFactory.get("normal", module.resolveOptions),
350
- this.inputFileSystem,
351
- error => {
352
- const errors = module.errors;
353
- for (let indexError = 0; indexError < errors.length; indexError++) {
354
- const err = errors[indexError];
355
- err.origin = origin;
356
- err.dependencies = dependencies;
357
- if (optional) this.warnings.push(err);
358
- else this.errors.push(err);
359
- }
360
-
361
- const warnings = module.warnings;
362
- for (
363
- let indexWarning = 0;
364
- indexWarning < warnings.length;
365
- indexWarning++
366
- ) {
367
- const war = warnings[indexWarning];
368
- war.origin = origin;
369
- war.dependencies = dependencies;
370
- this.warnings.push(war);
371
- }
372
- module.dependencies.sort(Dependency.compare);
373
- if (error) {
374
- this.hooks.failedModule.call(module, error);
375
- return callback(error);
376
- }
377
- this.hooks.succeedModule.call(module);
378
- return callback();
379
- }
380
- );
381
- }
382
-
383
- processModuleDependencies(module, callback) {
384
- const dependencies = new Map();
385
-
386
- const addDependency = dep => {
387
- const resourceIdent = dep.getResourceIdentifier();
388
- if (resourceIdent) {
389
- const factory = this.dependencyFactories.get(dep.constructor);
390
- if (factory === undefined)
391
- throw new Error(
392
- `No module factory available for dependency type: ${
393
- dep.constructor.name
394
- }`
395
- );
396
- let innerMap = dependencies.get(factory);
397
- if (innerMap === undefined)
398
- dependencies.set(factory, (innerMap = new Map()));
399
- let list = innerMap.get(resourceIdent);
400
- if (list === undefined) innerMap.set(resourceIdent, (list = []));
401
- list.push(dep);
402
- }
403
- };
404
-
405
- const addDependenciesBlock = block => {
406
- if (block.dependencies) {
407
- iterationOfArrayCallback(block.dependencies, addDependency);
408
- }
409
- if (block.blocks) {
410
- iterationOfArrayCallback(block.blocks, addDependenciesBlock);
411
- }
412
- if (block.variables) {
413
- iterationBlockVariable(block.variables, addDependency);
414
- }
415
- };
416
-
417
- try {
418
- addDependenciesBlock(module);
419
- } catch (e) {
420
- callback(e);
421
- }
422
-
423
- const sortedDependencies = [];
424
-
425
- for (const pair1 of dependencies) {
426
- for (const pair2 of pair1[1]) {
427
- sortedDependencies.push({
428
- factory: pair1[0],
429
- dependencies: pair2[1]
430
- });
431
- }
432
- }
433
-
434
- this.addModuleDependencies(
435
- module,
436
- sortedDependencies,
437
- this.bail,
438
- null,
439
- true,
440
- callback
441
- );
442
- }
443
-
444
- addModuleDependencies(
445
- module,
446
- dependencies,
447
- bail,
448
- cacheGroup,
449
- recursive,
450
- callback
451
- ) {
452
- let _this = this;
453
- const start = _this.profile && Date.now();
454
- const currentProfile = _this.profile && {};
455
-
456
- asyncLib.forEach(
457
- dependencies,
458
- (item, callback) => {
459
- const dependencies = item.dependencies;
460
-
461
- const errorAndCallback = err => {
462
- err.origin = module;
463
- _this.errors.push(err);
464
- if (bail) {
465
- callback(err);
466
- } else {
467
- callback();
468
- }
469
- };
470
- const warningAndCallback = err => {
471
- err.origin = module;
472
- _this.warnings.push(err);
473
- callback();
474
- };
475
-
476
- const semaphore = _this.semaphore;
477
- semaphore.acquire(() => {
478
- if (_this === null) return semaphore.release();
479
-
480
- const factory = item.factory;
481
- factory.create(
482
- {
483
- contextInfo: {
484
- issuer: module.nameForCondition && module.nameForCondition(),
485
- compiler: _this.compiler.name
486
- },
487
- resolveOptions: module.resolveOptions,
488
- context: module.context,
489
- dependencies: dependencies
490
- },
491
- (err, dependentModule) => {
492
- if (_this === null) return semaphore.release();
493
-
494
- let afterFactory;
495
-
496
- const isOptional = () => {
497
- return dependencies.every(d => d.optional);
498
- };
499
-
500
- const errorOrWarningAndCallback = err => {
501
- if (isOptional()) {
502
- return warningAndCallback(err);
503
- } else {
504
- return errorAndCallback(err);
505
- }
506
- };
507
-
508
- if (err) {
509
- semaphore.release();
510
- return errorOrWarningAndCallback(
511
- new ModuleNotFoundError(module, err, dependencies)
512
- );
513
- }
514
- if (!dependentModule) {
515
- semaphore.release();
516
- return process.nextTick(callback);
517
- }
518
- if (currentProfile) {
519
- afterFactory = Date.now();
520
- currentProfile.factory = afterFactory - start;
521
- }
522
-
523
- const iterationDependencies = depend => {
524
- for (let index = 0; index < depend.length; index++) {
525
- const dep = depend[index];
526
- dep.module = dependentModule;
527
- dependentModule.addReason(module, dep);
528
- }
529
- };
530
-
531
- const addModuleResult = _this.addModule(
532
- dependentModule,
533
- cacheGroup
534
- );
535
- dependentModule = addModuleResult.module;
536
- iterationDependencies(dependencies);
537
-
538
- const afterBuild = () => {
539
- if (currentProfile) {
540
- const afterBuilding = Date.now();
541
- currentProfile.building = afterBuilding - afterFactory;
542
- }
543
-
544
- if (recursive && addModuleResult.dependencies) {
545
- _this.processModuleDependencies(dependentModule, callback);
546
- } else {
547
- return callback();
548
- }
549
- };
550
-
551
- if (addModuleResult.issuer) {
552
- if (currentProfile) {
553
- dependentModule.profile = currentProfile;
554
- }
555
-
556
- dependentModule.issuer = module;
557
- } else {
558
- if (_this.profile) {
559
- if (module.profile) {
560
- const time = Date.now() - start;
561
- if (
562
- !module.profile.dependencies ||
563
- time > module.profile.dependencies
564
- ) {
565
- module.profile.dependencies = time;
566
- }
567
- }
568
- }
569
- }
570
-
571
- if (addModuleResult.build) {
572
- _this.buildModule(
573
- dependentModule,
574
- isOptional(),
575
- module,
576
- dependencies,
577
- err => {
578
- if (_this === null) return semaphore.release();
579
-
580
- if (err) {
581
- semaphore.release();
582
- return errorOrWarningAndCallback(err);
583
- }
584
-
585
- if (currentProfile) {
586
- const afterBuilding = Date.now();
587
- currentProfile.building = afterBuilding - afterFactory;
588
- }
589
-
590
- semaphore.release();
591
- afterBuild();
592
- }
593
- );
594
- } else {
595
- semaphore.release();
596
- _this.waitForBuildingFinished(dependentModule, afterBuild);
597
- }
598
- }
599
- );
600
- });
601
- },
602
- err => {
603
- // In V8, the Error objects keep a reference to the functions on the stack. These warnings &
604
- // errors are created inside closures that keep a reference to the Compilation, so errors are
605
- // leaking the Compilation object.
606
-
607
- if (err) {
608
- err.stack = err.stack;
609
- return callback(err);
610
- }
611
-
612
- return process.nextTick(callback);
613
- }
614
- );
615
- }
616
-
617
- _addModuleChain(context, dependency, onModule, callback) {
618
- const start = this.profile && Date.now();
619
- const currentProfile = this.profile && {};
620
-
621
- const errorAndCallback = this.bail
622
- ? err => {
623
- callback(err);
624
- }
625
- : err => {
626
- err.dependencies = [dependency];
627
- this.errors.push(err);
628
- callback();
629
- };
630
-
631
- if (
632
- typeof dependency !== "object" ||
633
- dependency === null ||
634
- !dependency.constructor
635
- ) {
636
- throw new Error("Parameter 'dependency' must be a Dependency");
637
- }
638
-
639
- const moduleFactory = this.dependencyFactories.get(dependency.constructor);
640
- if (!moduleFactory) {
641
- throw new Error(
642
- `No dependency factory available for this dependency type: ${
643
- dependency.constructor.name
644
- }`
645
- );
646
- }
647
-
648
- this.semaphore.acquire(() => {
649
- moduleFactory.create(
650
- {
651
- contextInfo: {
652
- issuer: "",
653
- compiler: this.compiler.name
654
- },
655
- context: context,
656
- dependencies: [dependency]
657
- },
658
- (err, module) => {
659
- if (err) {
660
- this.semaphore.release();
661
- return errorAndCallback(new EntryModuleNotFoundError(err));
662
- }
663
-
664
- let afterFactory;
665
-
666
- if (currentProfile) {
667
- afterFactory = Date.now();
668
- currentProfile.factory = afterFactory - start;
669
- }
670
-
671
- const addModuleResult = this.addModule(module);
672
- module = addModuleResult.module;
673
-
674
- onModule(module);
675
-
676
- dependency.module = module;
677
- module.addReason(null, dependency);
678
-
679
- const afterBuild = () => {
680
- if (currentProfile) {
681
- const afterBuilding = Date.now();
682
- currentProfile.building = afterBuilding - afterFactory;
683
- }
684
-
685
- if (addModuleResult.dependencies) {
686
- this.processModuleDependencies(module, err => {
687
- if (err) return callback(err);
688
- callback(null, module);
689
- });
690
- } else {
691
- return callback(null, module);
692
- }
693
- };
694
-
695
- if (addModuleResult.issuer) {
696
- if (currentProfile) {
697
- module.profile = currentProfile;
698
- }
699
- }
700
-
701
- if (addModuleResult.build) {
702
- this.buildModule(module, false, null, null, err => {
703
- if (err) {
704
- this.semaphore.release();
705
- return errorAndCallback(err);
706
- }
707
-
708
- if (currentProfile) {
709
- const afterBuilding = Date.now();
710
- currentProfile.building = afterBuilding - afterFactory;
711
- }
712
-
713
- this.semaphore.release();
714
- afterBuild();
715
- });
716
- } else {
717
- this.semaphore.release();
718
- this.waitForBuildingFinished(module, afterBuild);
719
- }
720
- }
721
- );
722
- });
723
- }
724
-
725
- addEntry(context, entry, name, callback) {
726
- const slot = {
727
- name: name,
728
- request: entry.request,
729
- module: null
730
- };
731
- this._preparedEntrypoints.push(slot);
732
- this._addModuleChain(
733
- context,
734
- entry,
735
- module => {
736
- this.entries.push(module);
737
- },
738
- (err, module) => {
739
- if (err) {
740
- return callback(err);
741
- }
742
-
743
- if (module) {
744
- slot.module = module;
745
- } else {
746
- const idx = this._preparedEntrypoints.indexOf(slot);
747
- this._preparedEntrypoints.splice(idx, 1);
748
- }
749
- return callback(null, module);
750
- }
751
- );
752
- }
753
-
754
- prefetch(context, dependency, callback) {
755
- this._addModuleChain(
756
- context,
757
- dependency,
758
- module => {
759
- module.prefetched = true;
760
- },
761
- callback
762
- );
763
- }
764
-
765
- rebuildModule(module, thisCallback) {
766
- let callbackList = this._rebuildingModules.get(module);
767
- if (callbackList) {
768
- callbackList.push(thisCallback);
769
- return;
770
- }
771
- this._rebuildingModules.set(module, (callbackList = [thisCallback]));
772
-
773
- const callback = err => {
774
- this._rebuildingModules.delete(module);
775
- for (const cb of callbackList) cb(err);
776
- };
777
-
778
- this.hooks.rebuildModule.call(module);
779
- const oldDependencies = module.dependencies.slice();
780
- const oldVariables = module.variables.slice();
781
- const oldBlocks = module.blocks.slice();
782
- module.unbuild();
783
- this.buildModule(module, false, module, null, err => {
784
- if (err) {
785
- this.hooks.finishRebuildingModule.call(module);
786
- return callback(err);
787
- }
788
-
789
- this.processModuleDependencies(module, err => {
790
- if (err) return callback(err);
791
- this.removeReasonsOfDependencyBlock(module, {
792
- dependencies: oldDependencies,
793
- variables: oldVariables,
794
- blocks: oldBlocks
795
- });
796
- this.hooks.finishRebuildingModule.call(module);
797
- callback();
798
- });
799
- });
800
- }
801
-
802
- finish() {
803
- const modules = this.modules;
804
- this.hooks.finishModules.call(modules);
805
-
806
- for (let index = 0; index < modules.length; index++) {
807
- const module = modules[index];
808
- this.reportDependencyErrorsAndWarnings(module, [module]);
809
- }
810
- }
811
-
812
- unseal() {
813
- this.hooks.unseal.call();
814
- this.chunks.length = 0;
815
- this.chunkGroups.length = 0;
816
- this.namedChunks.clear();
817
- this.namedChunkGroups.clear();
818
- this.additionalChunkAssets.length = 0;
819
- this.assets = {};
820
- for (const module of this.modules) {
821
- module.unseal();
822
- }
823
- }
824
-
825
- seal(callback) {
826
- this.hooks.seal.call();
827
-
828
- while (
829
- this.hooks.optimizeDependenciesBasic.call(this.modules) ||
830
- this.hooks.optimizeDependencies.call(this.modules) ||
831
- this.hooks.optimizeDependenciesAdvanced.call(this.modules)
832
- ) {
833
- /* empty */
834
- }
835
- this.hooks.afterOptimizeDependencies.call(this.modules);
836
-
837
- this.nextFreeModuleIndex = 0;
838
- this.nextFreeModuleIndex2 = 0;
839
- for (const preparedEntrypoint of this._preparedEntrypoints) {
840
- const module = preparedEntrypoint.module;
841
- const name = preparedEntrypoint.name;
842
- const chunk = this.addChunk(name);
843
- const entrypoint = new Entrypoint(name);
844
- entrypoint.setRuntimeChunk(chunk);
845
- entrypoint.addOrigin(null, name, preparedEntrypoint.request);
846
- this.namedChunkGroups.set(name, entrypoint);
847
- this.entrypoints.set(name, entrypoint);
848
- this.chunkGroups.push(entrypoint);
849
-
850
- GraphHelpers.connectChunkGroupAndChunk(entrypoint, chunk);
851
- GraphHelpers.connectChunkAndModule(chunk, module);
852
-
853
- chunk.entryModule = module;
854
- chunk.name = name;
855
-
856
- this.assignIndex(module);
857
- this.assignDepth(module);
858
- }
859
- this.processDependenciesBlocksForChunkGroups(this.chunkGroups);
860
- this.sortModules(this.modules);
861
- this.hooks.optimize.call();
862
-
863
- while (
864
- this.hooks.optimizeModulesBasic.call(this.modules) ||
865
- this.hooks.optimizeModules.call(this.modules) ||
866
- this.hooks.optimizeModulesAdvanced.call(this.modules)
867
- ) {
868
- /* empty */
869
- }
870
- this.hooks.afterOptimizeModules.call(this.modules);
871
-
872
- while (
873
- this.hooks.optimizeChunksBasic.call(this.chunks, this.chunkGroups) ||
874
- this.hooks.optimizeChunks.call(this.chunks, this.chunkGroups) ||
875
- this.hooks.optimizeChunksAdvanced.call(this.chunks, this.chunkGroups)
876
- ) {
877
- /* empty */
878
- }
879
- this.hooks.afterOptimizeChunks.call(this.chunks, this.chunkGroups);
880
-
881
- this.hooks.optimizeTree.callAsync(this.chunks, this.modules, err => {
882
- if (err) {
883
- return callback(err);
884
- }
885
-
886
- this.hooks.afterOptimizeTree.call(this.chunks, this.modules);
887
-
888
- while (
889
- this.hooks.optimizeChunkModulesBasic.call(this.chunks, this.modules) ||
890
- this.hooks.optimizeChunkModules.call(this.chunks, this.modules) ||
891
- this.hooks.optimizeChunkModulesAdvanced.call(this.chunks, this.modules)
892
- ) {
893
- /* empty */
894
- }
895
- this.hooks.afterOptimizeChunkModules.call(this.chunks, this.modules);
896
-
897
- const shouldRecord = this.hooks.shouldRecord.call() !== false;
898
-
899
- this.hooks.reviveModules.call(this.modules, this.records);
900
- this.hooks.optimizeModuleOrder.call(this.modules);
901
- this.hooks.advancedOptimizeModuleOrder.call(this.modules);
902
- this.hooks.beforeModuleIds.call(this.modules);
903
- this.hooks.moduleIds.call(this.modules);
904
- this.applyModuleIds();
905
- this.hooks.optimizeModuleIds.call(this.modules);
906
- this.hooks.afterOptimizeModuleIds.call(this.modules);
907
-
908
- this.sortItemsWithModuleIds();
909
-
910
- this.hooks.reviveChunks.call(this.chunks, this.records);
911
- this.hooks.optimizeChunkOrder.call(this.chunks);
912
- this.hooks.beforeChunkIds.call(this.chunks);
913
- this.applyChunkIds();
914
- this.hooks.optimizeChunkIds.call(this.chunks);
915
- this.hooks.afterOptimizeChunkIds.call(this.chunks);
916
-
917
- this.sortItemsWithChunkIds();
918
-
919
- if (shouldRecord)
920
- this.hooks.recordModules.call(this.modules, this.records);
921
- if (shouldRecord) this.hooks.recordChunks.call(this.chunks, this.records);
922
-
923
- this.hooks.beforeHash.call();
924
- this.createHash();
925
- this.hooks.afterHash.call();
926
-
927
- if (shouldRecord) this.hooks.recordHash.call(this.records);
928
-
929
- this.hooks.beforeModuleAssets.call();
930
- this.createModuleAssets();
931
- if (this.hooks.shouldGenerateChunkAssets.call() !== false) {
932
- this.hooks.beforeChunkAssets.call();
933
- this.createChunkAssets();
934
- }
935
- this.hooks.additionalChunkAssets.call(this.chunks);
936
- this.summarizeDependencies();
937
- if (shouldRecord) this.hooks.record.call(this, this.records);
938
-
939
- this.hooks.additionalAssets.callAsync(err => {
940
- if (err) {
941
- return callback(err);
942
- }
943
- this.hooks.optimizeChunkAssets.callAsync(this.chunks, err => {
944
- if (err) {
945
- return callback(err);
946
- }
947
- this.hooks.afterOptimizeChunkAssets.call(this.chunks);
948
- this.hooks.optimizeAssets.callAsync(this.assets, err => {
949
- if (err) {
950
- return callback(err);
951
- }
952
- this.hooks.afterOptimizeAssets.call(this.assets);
953
- if (this.hooks.needAdditionalSeal.call()) {
954
- this.unseal();
955
- return this.seal(callback);
956
- }
957
- return this.hooks.afterSeal.callAsync(callback);
958
- });
959
- });
960
- });
961
- });
962
- }
963
-
964
- sortModules(modules) {
965
- modules.sort(byIndexOrIdentifier);
966
- }
967
-
968
- reportDependencyErrorsAndWarnings(module, blocks) {
969
- for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) {
970
- const block = blocks[indexBlock];
971
- const dependencies = block.dependencies;
972
-
973
- for (let indexDep = 0; indexDep < dependencies.length; indexDep++) {
974
- const d = dependencies[indexDep];
975
-
976
- const warnings = d.getWarnings();
977
- if (warnings) {
978
- for (let indexWar = 0; indexWar < warnings.length; indexWar++) {
979
- const w = warnings[indexWar];
980
-
981
- const warning = new ModuleDependencyWarning(module, w, d.loc);
982
- this.warnings.push(warning);
983
- }
984
- }
985
- const errors = d.getErrors();
986
- if (errors) {
987
- for (let indexErr = 0; indexErr < errors.length; indexErr++) {
988
- const e = errors[indexErr];
989
-
990
- const error = new ModuleDependencyError(module, e, d.loc);
991
- this.errors.push(error);
992
- }
993
- }
994
- }
995
-
996
- this.reportDependencyErrorsAndWarnings(module, block.blocks);
997
- }
998
- }
999
-
1000
- addChunkInGroup(name, module, loc, request) {
1001
- if (name) {
1002
- const chunkGroup = this.namedChunkGroups.get(name);
1003
- if (chunkGroup !== undefined) {
1004
- if (module) {
1005
- chunkGroup.addOrigin(module, loc, request);
1006
- }
1007
- return chunkGroup;
1008
- }
1009
- }
1010
- const chunkGroup = new ChunkGroup(name);
1011
- if (module) chunkGroup.addOrigin(module, loc, request);
1012
- const chunk = this.addChunk(name);
1013
-
1014
- GraphHelpers.connectChunkGroupAndChunk(chunkGroup, chunk);
1015
-
1016
- this.chunkGroups.push(chunkGroup);
1017
- if (name) {
1018
- this.namedChunkGroups.set(name, chunkGroup);
1019
- }
1020
- return chunkGroup;
1021
- }
1022
-
1023
- addChunk(name) {
1024
- if (name) {
1025
- const chunk = this.namedChunks.get(name);
1026
- if (chunk !== undefined) {
1027
- return chunk;
1028
- }
1029
- }
1030
- const chunk = new Chunk(name);
1031
- this.chunks.push(chunk);
1032
- if (name) {
1033
- this.namedChunks.set(name, chunk);
1034
- }
1035
- return chunk;
1036
- }
1037
-
1038
- assignIndex(module) {
1039
- const _this = this;
1040
-
1041
- const assignIndexToModule = module => {
1042
- // enter module
1043
- if (typeof module.index !== "number") {
1044
- module.index = _this.nextFreeModuleIndex++;
1045
-
1046
- // leave module
1047
- queue.push(() => (module.index2 = _this.nextFreeModuleIndex2++));
1048
-
1049
- // enter it as block
1050
- assignIndexToDependencyBlock(module);
1051
- }
1052
- };
1053
-
1054
- const assignIndexToDependency = dependency => {
1055
- if (dependency.module) {
1056
- queue.push(() => assignIndexToModule(dependency.module));
1057
- }
1058
- };
1059
-
1060
- const assignIndexToDependencyBlock = block => {
1061
- let allDependencies = [];
1062
-
1063
- const iteratorDependency = d => allDependencies.push(d);
1064
-
1065
- const iteratorBlock = b =>
1066
- queue.push(() => assignIndexToDependencyBlock(b));
1067
-
1068
- if (block.variables) {
1069
- iterationBlockVariable(block.variables, iteratorDependency);
1070
- }
1071
-
1072
- if (block.dependencies) {
1073
- iterationOfArrayCallback(block.dependencies, iteratorDependency);
1074
- }
1075
- if (block.blocks) {
1076
- const blocks = block.blocks;
1077
- let indexBlock = blocks.length;
1078
- while (indexBlock--) {
1079
- iteratorBlock(blocks[indexBlock]);
1080
- }
1081
- }
1082
-
1083
- let indexAll = allDependencies.length;
1084
- while (indexAll--) {
1085
- iteratorAllDependencies(allDependencies[indexAll]);
1086
- }
1087
- };
1088
-
1089
- const queue = [
1090
- () => {
1091
- assignIndexToModule(module);
1092
- }
1093
- ];
1094
-
1095
- const iteratorAllDependencies = d => {
1096
- queue.push(() => assignIndexToDependency(d));
1097
- };
1098
-
1099
- while (queue.length) {
1100
- queue.pop()();
1101
- }
1102
- }
1103
-
1104
- assignDepth(module) {
1105
- const queue = new Set([module]);
1106
- let depth;
1107
-
1108
- module.depth = 0;
1109
-
1110
- const enqueueJob = module => {
1111
- const d = module.depth;
1112
- if (typeof d === "number" && d <= depth) return;
1113
- queue.add(module);
1114
- module.depth = depth;
1115
- };
1116
-
1117
- const assignDepthToDependency = (dependency, depth) => {
1118
- if (dependency.module) {
1119
- enqueueJob(dependency.module);
1120
- }
1121
- };
1122
-
1123
- const assignDepthToDependencyBlock = block => {
1124
- if (block.variables) {
1125
- iterationBlockVariable(block.variables, assignDepthToDependency);
1126
- }
1127
-
1128
- if (block.dependencies) {
1129
- iterationOfArrayCallback(block.dependencies, assignDepthToDependency);
1130
- }
1131
-
1132
- if (block.blocks) {
1133
- iterationOfArrayCallback(block.blocks, assignDepthToDependencyBlock);
1134
- }
1135
- };
1136
-
1137
- for (module of queue) {
1138
- queue.delete(module);
1139
- depth = module.depth;
1140
-
1141
- depth++;
1142
- assignDepthToDependencyBlock(module);
1143
- }
1144
- }
1145
-
1146
- // This method creates the Chunk graph from the Module graph
1147
- processDependenciesBlocksForChunkGroups(inputChunkGroups) {
1148
- // Process is splitting into two parts:
1149
- // Part one traverse the module graph and builds a very basic chunks graph
1150
- // in chunkDependencies.
1151
- // Part two traverse every possible way through the basic chunk graph and
1152
- // tracks the available modules. While traversing it connects chunks with
1153
- // eachother and Blocks with Chunks. It stops traversing when all modules
1154
- // for a chunk are already available. So it doesn't connect unneeded chunks.
1155
-
1156
- const chunkDependencies = new Map(); // Map<Chunk, Array<{Module, Chunk}>>
1157
- const allCreatedChunkGroups = new Set();
1158
-
1159
- // PART ONE
1160
-
1161
- const blockChunkGroups = new Map();
1162
-
1163
- // Start with the provided modules/chunks
1164
- const queue = inputChunkGroups.map(chunkGroup => ({
1165
- block: chunkGroup.chunks[0].entryModule,
1166
- module: chunkGroup.chunks[0].entryModule,
1167
- chunk: chunkGroup.chunks[0],
1168
- chunkGroup
1169
- }));
1170
-
1171
- let module, block, chunk, chunkGroup;
1172
-
1173
- // For each async Block in graph
1174
- const iteratorBlock = b => {
1175
- // 1. We create a chunk for this Block
1176
- // but only once (blockChunkGroups map)
1177
- let c = blockChunkGroups.get(b);
1178
- if (c === undefined) {
1179
- c = this.namedChunkGroups.get(b.chunkName);
1180
- if (c && c.isInitial()) {
1181
- this.errors.push(
1182
- new AsyncDependencyToInitialChunkError(b.chunkName, module, b.loc)
1183
- );
1184
- c = chunkGroup;
1185
- } else {
1186
- c = this.addChunkInGroup(b.chunkName, module, b.loc, b.request);
1187
- blockChunkGroups.set(b, c);
1188
- allCreatedChunkGroups.add(c);
1189
- }
1190
- } else {
1191
- c.addOrigin(module, b.loc, b.request);
1192
- }
1193
-
1194
- // 2. We store the Block+Chunk mapping as dependency for the chunk
1195
- let deps = chunkDependencies.get(chunkGroup);
1196
- if (!deps) chunkDependencies.set(chunkGroup, (deps = []));
1197
- deps.push({
1198
- block: b,
1199
- chunkGroup: c
1200
- });
1201
-
1202
- // 3. We enqueue the DependenciesBlock for traversal
1203
- queue.push({
1204
- block: b,
1205
- module: module,
1206
- chunk: c.chunks[0],
1207
- chunkGroup: c
1208
- });
1209
- };
1210
-
1211
- // For each Dependency in the graph
1212
- const iteratorDependency = d => {
1213
- // We skip Dependencies without Reference
1214
- const ref = d.getReference();
1215
- if (!ref) {
1216
- return;
1217
- }
1218
- // We skip Dependencies without Module pointer
1219
- const refModule = ref.module;
1220
- if (!refModule) {
1221
- return;
1222
- }
1223
- // We skip weak Dependencies
1224
- if (ref.weak) {
1225
- return;
1226
- }
1227
- // We connect Module and Chunk when not already done
1228
- if (chunk.addModule(refModule)) {
1229
- refModule.addChunk(chunk);
1230
-
1231
- // And enqueue the Module for traversal
1232
- queue.push({
1233
- block: refModule,
1234
- module: refModule,
1235
- chunk,
1236
- chunkGroup
1237
- });
1238
- }
1239
- };
1240
-
1241
- // Iterative traversal of the Module graph
1242
- // Recursive would be simpler to write but could result in Stack Overflows
1243
- while (queue.length) {
1244
- const queueItem = queue.pop();
1245
- module = queueItem.module;
1246
- block = queueItem.block;
1247
- chunk = queueItem.chunk;
1248
- chunkGroup = queueItem.chunkGroup;
1249
-
1250
- // Traverse all variables, Dependencies and Blocks
1251
- if (block.variables) {
1252
- iterationBlockVariable(block.variables, iteratorDependency);
1253
- }
1254
-
1255
- if (block.dependencies) {
1256
- iterationOfArrayCallback(block.dependencies, iteratorDependency);
1257
- }
1258
-
1259
- if (block.blocks) {
1260
- iterationOfArrayCallback(block.blocks, iteratorBlock);
1261
- }
1262
- }
1263
-
1264
- // PART TWO
1265
-
1266
- let availableModules;
1267
- let newAvailableModules;
1268
- const queue2 = new Queue(
1269
- inputChunkGroups.map(chunkGroup => ({
1270
- chunkGroup,
1271
- availableModules: new Set()
1272
- }))
1273
- );
1274
-
1275
- // Helper function to check if all modules of a chunk are available
1276
- const areModulesAvailable = (chunkGroup, availableModules) => {
1277
- for (const chunk of chunkGroup.chunks) {
1278
- for (const module of chunk.modulesIterable) {
1279
- if (!availableModules.has(module)) return false;
1280
- }
1281
- }
1282
- return true;
1283
- };
1284
-
1285
- // For each edge in the basic chunk graph
1286
- const filterFn = dep => {
1287
- // Filter egdes that are not needed because all modules are already available
1288
- // This also filters circular dependencies in the chunks graph
1289
- const depChunkGroup = dep.chunkGroup;
1290
- if (areModulesAvailable(depChunkGroup, newAvailableModules)) return false; // break all modules are already available
1291
- return true;
1292
- };
1293
-
1294
- const minAvailableModulesMap = new Map();
1295
-
1296
- // Iterative traversing of the basic chunk graph
1297
- while (queue2.length) {
1298
- const queueItem = queue2.dequeue();
1299
- chunkGroup = queueItem.chunkGroup;
1300
- availableModules = queueItem.availableModules;
1301
-
1302
- // 1. Get minimal available modules
1303
- // It doesn't make sense to traverse a chunk again with more available modules.
1304
- // This step calculates the minimal available modules and skips traversal when
1305
- // the list didn't shrink.
1306
- let minAvailableModules = minAvailableModulesMap.get(chunkGroup);
1307
- if (minAvailableModules === undefined) {
1308
- minAvailableModulesMap.set(chunkGroup, new Set(availableModules));
1309
- } else {
1310
- let deletedModules = false;
1311
- for (const m of minAvailableModules) {
1312
- if (!availableModules.has(m)) {
1313
- minAvailableModules.delete(m);
1314
- deletedModules = true;
1315
- }
1316
- }
1317
- if (!deletedModules) continue;
1318
- availableModules = minAvailableModules;
1319
- }
1320
-
1321
- // 2. Get the edges at this point of the graph
1322
- const deps = chunkDependencies.get(chunkGroup);
1323
- if (!deps) continue;
1324
- if (deps.length === 0) continue;
1325
-
1326
- // 3. Create a new Set of available modules at this points
1327
- newAvailableModules = new Set(availableModules);
1328
- for (const chunk of chunkGroup.chunks)
1329
- for (const m of chunk.modulesIterable) newAvailableModules.add(m);
1330
-
1331
- // 4. Filter edges with available modules
1332
- const filteredDeps = deps.filter(filterFn);
1333
-
1334
- // 5. Foreach remaining edge
1335
- const nextChunkGroups = new Set();
1336
- for (let i = 0; i < filteredDeps.length; i++) {
1337
- const dep = filteredDeps[i];
1338
- const depChunkGroup = dep.chunkGroup;
1339
- const depBlock = dep.block;
1340
-
1341
- // 6. Connect block with chunk
1342
- GraphHelpers.connectDependenciesBlockAndChunkGroup(
1343
- depBlock,
1344
- depChunkGroup
1345
- );
1346
-
1347
- // 7. Connect chunk with parent
1348
- GraphHelpers.connectChunkGroupParentAndChild(chunkGroup, depChunkGroup);
1349
-
1350
- nextChunkGroups.add(depChunkGroup);
1351
- }
1352
-
1353
- // 8. Enqueue further traversal
1354
- for (const nextChunkGroup of nextChunkGroups) {
1355
- queue2.enqueue({
1356
- chunkGroup: nextChunkGroup,
1357
- availableModules: newAvailableModules
1358
- });
1359
- }
1360
- }
1361
-
1362
- // Remove all unconnected chunk groups
1363
- for (const chunkGroup of allCreatedChunkGroups) {
1364
- if (chunkGroup.getNumberOfParents() === 0) {
1365
- for (const chunk of chunkGroup.chunks) {
1366
- const idx = this.chunks.indexOf(chunk);
1367
- if (idx >= 0) this.chunks.splice(idx, 1);
1368
- chunk.remove("unconnected");
1369
- }
1370
- chunkGroup.remove("unconnected");
1371
- }
1372
- }
1373
- }
1374
-
1375
- removeReasonsOfDependencyBlock(module, block) {
1376
- const iteratorDependency = d => {
1377
- if (!d.module) {
1378
- return;
1379
- }
1380
- if (d.module.removeReason(module, d)) {
1381
- for (const chunk of d.module.chunksIterable) {
1382
- this.patchChunksAfterReasonRemoval(d.module, chunk);
1383
- }
1384
- }
1385
- };
1386
-
1387
- if (block.blocks) {
1388
- iterationOfArrayCallback(block.blocks, block =>
1389
- this.removeReasonsOfDependencyBlock(module, block)
1390
- );
1391
- }
1392
-
1393
- if (block.dependencies) {
1394
- iterationOfArrayCallback(block.dependencies, iteratorDependency);
1395
- }
1396
-
1397
- if (block.variables) {
1398
- iterationBlockVariable(block.variables, iteratorDependency);
1399
- }
1400
- }
1401
-
1402
- patchChunksAfterReasonRemoval(module, chunk) {
1403
- if (!module.hasReasons()) {
1404
- this.removeReasonsOfDependencyBlock(module, module);
1405
- }
1406
- if (!module.hasReasonForChunk(chunk)) {
1407
- if (module.removeChunk(chunk)) {
1408
- this.removeChunkFromDependencies(module, chunk);
1409
- }
1410
- }
1411
- }
1412
-
1413
- removeChunkFromDependencies(block, chunk) {
1414
- const iteratorDependency = d => {
1415
- if (!d.module) {
1416
- return;
1417
- }
1418
- this.patchChunksAfterReasonRemoval(d.module, chunk);
1419
- };
1420
-
1421
- const blocks = block.blocks;
1422
- for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) {
1423
- const chunks = blocks[indexBlock].chunks;
1424
- for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1425
- const blockChunk = chunks[indexChunk];
1426
- chunk.removeChunk(blockChunk);
1427
- blockChunk.removeParent(chunk);
1428
- this.removeChunkFromDependencies(chunks, blockChunk);
1429
- }
1430
- }
1431
-
1432
- if (block.dependencies) {
1433
- iterationOfArrayCallback(block.dependencies, iteratorDependency);
1434
- }
1435
-
1436
- if (block.variables) {
1437
- iterationBlockVariable(block.variables, iteratorDependency);
1438
- }
1439
- }
1440
-
1441
- applyModuleIds() {
1442
- const unusedIds = [];
1443
- let nextFreeModuleId = 0;
1444
- const usedIds = new Set();
1445
- if (this.usedModuleIds) {
1446
- for (const id of this.usedModuleIds) {
1447
- usedIds.add(id);
1448
- }
1449
- }
1450
-
1451
- const modules1 = this.modules;
1452
- for (let indexModule1 = 0; indexModule1 < modules1.length; indexModule1++) {
1453
- const module1 = modules1[indexModule1];
1454
- if (module1.id !== null) {
1455
- usedIds.add(module1.id);
1456
- }
1457
- }
1458
-
1459
- if (usedIds.size > 0) {
1460
- let usedIdMax = -1;
1461
- for (const usedIdKey of usedIds) {
1462
- if (typeof usedIdKey !== "number") {
1463
- continue;
1464
- }
1465
-
1466
- usedIdMax = Math.max(usedIdMax, usedIdKey);
1467
- }
1468
-
1469
- let lengthFreeModules = (nextFreeModuleId = usedIdMax + 1);
1470
-
1471
- while (lengthFreeModules--) {
1472
- if (!usedIds.has(lengthFreeModules)) {
1473
- unusedIds.push(lengthFreeModules);
1474
- }
1475
- }
1476
- }
1477
-
1478
- const modules2 = this.modules;
1479
- for (let indexModule2 = 0; indexModule2 < modules2.length; indexModule2++) {
1480
- const module2 = modules2[indexModule2];
1481
- if (module2.id === null) {
1482
- if (unusedIds.length > 0) module2.id = unusedIds.pop();
1483
- else module2.id = nextFreeModuleId++;
1484
- }
1485
- }
1486
- }
1487
-
1488
- applyChunkIds() {
1489
- const usedIds = new Set();
1490
-
1491
- // Get used ids from usedChunkIds property (i. e. from records)
1492
- if (this.usedChunkIds) {
1493
- for (const id of this.usedChunkIds) {
1494
- if (typeof id !== "number") {
1495
- continue;
1496
- }
1497
-
1498
- usedIds.add(id);
1499
- }
1500
- }
1501
-
1502
- // Get used ids from existing chunks
1503
- const chunks = this.chunks;
1504
- for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1505
- const chunk = chunks[indexChunk];
1506
- const usedIdValue = chunk.id;
1507
-
1508
- if (typeof usedIdValue !== "number") {
1509
- continue;
1510
- }
1511
-
1512
- usedIds.add(usedIdValue);
1513
- }
1514
-
1515
- // Calculate maximum assigned chunk id
1516
- let nextFreeChunkId = -1;
1517
- for (const id of usedIds) {
1518
- nextFreeChunkId = Math.max(nextFreeChunkId, id);
1519
- }
1520
- nextFreeChunkId++;
1521
-
1522
- // Determine free chunk ids from 0 to maximum
1523
- const unusedIds = [];
1524
- if (nextFreeChunkId > 0) {
1525
- let index = nextFreeChunkId;
1526
- while (index--) {
1527
- if (!usedIds.has(index)) {
1528
- unusedIds.push(index);
1529
- }
1530
- }
1531
- }
1532
-
1533
- // Assign ids to chunk which has no id
1534
- for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1535
- const chunk = chunks[indexChunk];
1536
- if (chunk.id === null) {
1537
- if (unusedIds.length > 0) chunk.id = unusedIds.pop();
1538
- else chunk.id = nextFreeChunkId++;
1539
- }
1540
- if (!chunk.ids) {
1541
- chunk.ids = [chunk.id];
1542
- }
1543
- }
1544
- }
1545
-
1546
- sortItemsWithModuleIds() {
1547
- this.modules.sort(byIdOrIdentifier);
1548
-
1549
- const modules = this.modules;
1550
- for (let indexModule = 0; indexModule < modules.length; indexModule++) {
1551
- modules[indexModule].sortItems(false);
1552
- }
1553
-
1554
- const chunks = this.chunks;
1555
- for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1556
- chunks[indexChunk].sortItems(false);
1557
- }
1558
- }
1559
-
1560
- sortItemsWithChunkIds() {
1561
- for (const chunkGroup of this.chunkGroups) {
1562
- chunkGroup.sortItems();
1563
- }
1564
-
1565
- this.chunks.sort(byId);
1566
-
1567
- for (
1568
- let indexModule = 0;
1569
- indexModule < this.modules.length;
1570
- indexModule++
1571
- ) {
1572
- this.modules[indexModule].sortItems(true);
1573
- }
1574
-
1575
- const chunks = this.chunks;
1576
- for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1577
- chunks[indexChunk].sortItems(true);
1578
- }
1579
-
1580
- const byMessage = (a, b) => {
1581
- const ma = `${a.message}`;
1582
- const mb = `${b.message}`;
1583
- if (ma < mb) return -1;
1584
- if (mb < ma) return 1;
1585
- return 0;
1586
- };
1587
-
1588
- this.errors.sort(byMessage);
1589
- this.warnings.sort(byMessage);
1590
- }
1591
-
1592
- summarizeDependencies() {
1593
- this.fileDependencies = new SortableSet(this.compilationDependencies);
1594
- this.contextDependencies = new SortableSet();
1595
- this.missingDependencies = new SortableSet();
1596
-
1597
- for (
1598
- let indexChildren = 0;
1599
- indexChildren < this.children.length;
1600
- indexChildren++
1601
- ) {
1602
- const child = this.children[indexChildren];
1603
-
1604
- addAllToSet(this.fileDependencies, child.fileDependencies);
1605
- addAllToSet(this.contextDependencies, child.contextDependencies);
1606
- addAllToSet(this.missingDependencies, child.missingDependencies);
1607
- }
1608
-
1609
- for (
1610
- let indexModule = 0;
1611
- indexModule < this.modules.length;
1612
- indexModule++
1613
- ) {
1614
- const module = this.modules[indexModule];
1615
-
1616
- if (module.buildInfo.fileDependencies) {
1617
- addAllToSet(this.fileDependencies, module.buildInfo.fileDependencies);
1618
- }
1619
- if (module.buildInfo.contextDependencies) {
1620
- addAllToSet(
1621
- this.contextDependencies,
1622
- module.buildInfo.contextDependencies
1623
- );
1624
- }
1625
- }
1626
- for (const error of this.errors) {
1627
- if (
1628
- typeof error.missing === "object" &&
1629
- error.missing &&
1630
- error.missing[Symbol.iterator]
1631
- ) {
1632
- addAllToSet(this.missingDependencies, error.missing);
1633
- }
1634
- }
1635
- this.fileDependencies.sort();
1636
- this.contextDependencies.sort();
1637
- this.missingDependencies.sort();
1638
- }
1639
-
1640
- createHash() {
1641
- const outputOptions = this.outputOptions;
1642
- const hashFunction = outputOptions.hashFunction;
1643
- const hashDigest = outputOptions.hashDigest;
1644
- const hashDigestLength = outputOptions.hashDigestLength;
1645
- const hash = createHash(hashFunction);
1646
- if (outputOptions.hashSalt) hash.update(outputOptions.hashSalt);
1647
- this.mainTemplate.updateHash(hash);
1648
- this.chunkTemplate.updateHash(hash);
1649
- for (const key of Object.keys(this.moduleTemplates).sort())
1650
- this.moduleTemplates[key].updateHash(hash);
1651
- for (const child of this.children) hash.update(child.hash);
1652
- for (const warning of this.warnings) hash.update(`${warning.message}`);
1653
- for (const error of this.errors) hash.update(`${error.message}`);
1654
- const modules = this.modules;
1655
- for (let i = 0; i < modules.length; i++) {
1656
- const module = modules[i];
1657
- const moduleHash = createHash(hashFunction);
1658
- module.updateHash(moduleHash);
1659
- module.hash = moduleHash.digest(hashDigest);
1660
- module.renderedHash = module.hash.substr(0, hashDigestLength);
1661
- }
1662
- // clone needed as sort below is inplace mutation
1663
- const chunks = this.chunks.slice();
1664
- /**
1665
- * sort here will bring all "falsy" values to the beginning
1666
- * this is needed as the "hasRuntime()" chunks are dependent on the
1667
- * hashes of the non-runtime chunks.
1668
- */
1669
- chunks.sort((a, b) => {
1670
- const aEntry = a.hasRuntime();
1671
- const bEntry = b.hasRuntime();
1672
- if (aEntry && !bEntry) return 1;
1673
- if (!aEntry && bEntry) return -1;
1674
- return 0;
1675
- });
1676
- for (let i = 0; i < chunks.length; i++) {
1677
- const chunk = chunks[i];
1678
- const chunkHash = createHash(hashFunction);
1679
- if (outputOptions.hashSalt) chunkHash.update(outputOptions.hashSalt);
1680
- chunk.updateHash(chunkHash);
1681
- if (chunk.hasRuntime()) {
1682
- this.mainTemplate.updateHashForChunk(chunkHash, chunk);
1683
- } else {
1684
- this.chunkTemplate.updateHashForChunk(chunkHash, chunk);
1685
- }
1686
- this.hooks.chunkHash.call(chunk, chunkHash);
1687
- chunk.hash = chunkHash.digest(hashDigest);
1688
- hash.update(chunk.hash);
1689
- chunk.renderedHash = chunk.hash.substr(0, hashDigestLength);
1690
- }
1691
- this.fullHash = hash.digest(hashDigest);
1692
- this.hash = this.fullHash.substr(0, hashDigestLength);
1693
- }
1694
-
1695
- modifyHash(update) {
1696
- const outputOptions = this.outputOptions;
1697
- const hashFunction = outputOptions.hashFunction;
1698
- const hashDigest = outputOptions.hashDigest;
1699
- const hashDigestLength = outputOptions.hashDigestLength;
1700
- const hash = createHash(hashFunction);
1701
- hash.update(this.fullHash);
1702
- hash.update(update);
1703
- this.fullHash = hash.digest(hashDigest);
1704
- this.hash = this.fullHash.substr(0, hashDigestLength);
1705
- }
1706
-
1707
- createModuleAssets() {
1708
- for (let i = 0; i < this.modules.length; i++) {
1709
- const module = this.modules[i];
1710
- if (module.buildInfo.assets) {
1711
- for (const assetName of Object.keys(module.buildInfo.assets)) {
1712
- const fileName = this.getPath(assetName);
1713
- this.assets[fileName] = module.buildInfo.assets[assetName];
1714
- this.hooks.moduleAsset.call(module, fileName);
1715
- }
1716
- }
1717
- }
1718
- }
1719
-
1720
- createChunkAssets() {
1721
- const outputOptions = this.outputOptions;
1722
- const cachedSourceMap = new Map();
1723
- for (let i = 0; i < this.chunks.length; i++) {
1724
- const chunk = this.chunks[i];
1725
- chunk.files = [];
1726
- let source;
1727
- let file;
1728
- let filenameTemplate;
1729
- try {
1730
- const template = chunk.hasRuntime()
1731
- ? this.mainTemplate
1732
- : this.chunkTemplate;
1733
- const manifest = template.getRenderManifest({
1734
- chunk,
1735
- hash: this.hash,
1736
- fullHash: this.fullHash,
1737
- outputOptions,
1738
- moduleTemplates: this.moduleTemplates,
1739
- dependencyTemplates: this.dependencyTemplates
1740
- }); // [{ render(), filenameTemplate, pathOptions, identifier, hash }]
1741
- for (const fileManifest of manifest) {
1742
- const cacheName = fileManifest.identifier;
1743
- const usedHash = fileManifest.hash;
1744
- filenameTemplate = fileManifest.filenameTemplate;
1745
- if (
1746
- this.cache &&
1747
- this.cache[cacheName] &&
1748
- this.cache[cacheName].hash === usedHash
1749
- ) {
1750
- source = this.cache[cacheName].source;
1751
- } else {
1752
- source = fileManifest.render();
1753
- // Ensure that source is a cached source to avoid additional cost because of repeated access
1754
- if (!(source instanceof CachedSource)) {
1755
- const cacheEntry = cachedSourceMap.get(source);
1756
- if (cacheEntry) {
1757
- source = cacheEntry;
1758
- } else {
1759
- const cachedSource = new CachedSource(source);
1760
- cachedSourceMap.set(source, cachedSource);
1761
- source = cachedSource;
1762
- }
1763
- }
1764
- if (this.cache) {
1765
- this.cache[cacheName] = {
1766
- hash: usedHash,
1767
- source
1768
- };
1769
- }
1770
- }
1771
- file = this.getPath(filenameTemplate, fileManifest.pathOptions);
1772
- if (this.assets[file] && this.assets[file] !== source)
1773
- throw new Error(
1774
- `Conflict: Multiple assets emit to the same filename ${file}`
1775
- );
1776
- this.assets[file] = source;
1777
- chunk.files.push(file);
1778
- this.hooks.chunkAsset.call(chunk, file);
1779
- }
1780
- } catch (err) {
1781
- this.errors.push(
1782
- new ChunkRenderError(chunk, file || filenameTemplate, err)
1783
- );
1784
- }
1785
- }
1786
- }
1787
-
1788
- getPath(filename, data) {
1789
- data = data || {};
1790
- data.hash = data.hash || this.hash;
1791
- return this.mainTemplate.getAssetPath(filename, data);
1792
- }
1793
-
1794
- createChildCompiler(name, outputOptions, plugins) {
1795
- const idx = this.childrenCounters[name] || 0;
1796
- this.childrenCounters[name] = idx + 1;
1797
- return this.compiler.createChildCompiler(
1798
- this,
1799
- name,
1800
- idx,
1801
- outputOptions,
1802
- plugins
1803
- );
1804
- }
1805
-
1806
- checkConstraints() {
1807
- const usedIds = new Set();
1808
-
1809
- const modules = this.modules;
1810
- for (let indexModule = 0; indexModule < modules.length; indexModule++) {
1811
- const moduleId = modules[indexModule].id;
1812
- if (moduleId === null) continue;
1813
- if (usedIds.has(moduleId))
1814
- throw new Error(`checkConstraints: duplicate module id ${moduleId}`);
1815
- usedIds.add(moduleId);
1816
- }
1817
-
1818
- const chunks = this.chunks;
1819
- for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1820
- const chunk = chunks[indexChunk];
1821
- if (chunks.indexOf(chunk) !== indexChunk)
1822
- throw new Error(
1823
- `checkConstraints: duplicate chunk in compilation ${chunk.debugId}`
1824
- );
1825
- }
1826
-
1827
- for (const chunkGroup of this.chunkGroups) {
1828
- chunkGroup.checkConstraints();
1829
- }
1830
- }
1831
- }
1832
-
1833
- // TODO remove in webpack 5
1834
- Compilation.prototype.applyPlugins = util.deprecate(function(name, ...args) {
1835
- this.hooks[
1836
- name.replace(/[- ]([a-z])/g, match => match[1].toUpperCase())
1837
- ].call(...args);
1838
- }, "Compilation.applyPlugins is deprecated. Use new API on `.hooks` instead");
1839
-
1840
- // TODO remove in webpack 5
1841
- Object.defineProperty(Compilation.prototype, "moduleTemplate", {
1842
- configurable: false,
1843
- get: util.deprecate(function() {
1844
- return this.moduleTemplates.javascript;
1845
- }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead"),
1846
- set: util.deprecate(function(value) {
1847
- this.moduleTemplates.javascript = value;
1848
- }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead.")
1849
- });
1850
-
1851
- module.exports = Compilation;
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 util = require("util");
9
+ const { CachedSource } = require("webpack-sources");
10
+ const {
11
+ Tapable,
12
+ SyncHook,
13
+ SyncBailHook,
14
+ SyncWaterfallHook,
15
+ AsyncSeriesHook
16
+ } = require("tapable");
17
+ const EntryModuleNotFoundError = require("./EntryModuleNotFoundError");
18
+ const ModuleNotFoundError = require("./ModuleNotFoundError");
19
+ const ModuleDependencyWarning = require("./ModuleDependencyWarning");
20
+ const ModuleDependencyError = require("./ModuleDependencyError");
21
+ const ChunkGroup = require("./ChunkGroup");
22
+ const Chunk = require("./Chunk");
23
+ const Entrypoint = require("./Entrypoint");
24
+ const MainTemplate = require("./MainTemplate");
25
+ const ChunkTemplate = require("./ChunkTemplate");
26
+ const HotUpdateChunkTemplate = require("./HotUpdateChunkTemplate");
27
+ const ModuleTemplate = require("./ModuleTemplate");
28
+ const RuntimeTemplate = require("./RuntimeTemplate");
29
+ const Dependency = require("./Dependency");
30
+ const ChunkRenderError = require("./ChunkRenderError");
31
+ const AsyncDependencyToInitialChunkError = require("./AsyncDependencyToInitialChunkError");
32
+ const Stats = require("./Stats");
33
+ const Semaphore = require("./util/Semaphore");
34
+ const createHash = require("./util/createHash");
35
+ const Queue = require("./util/Queue");
36
+ const SortableSet = require("./util/SortableSet");
37
+ const GraphHelpers = require("./GraphHelpers");
38
+
39
+ const byId = (a, b) => {
40
+ if (a.id < b.id) return -1;
41
+ if (a.id > b.id) return 1;
42
+ return 0;
43
+ };
44
+
45
+ const byIdOrIdentifier = (a, b) => {
46
+ if (a.id < b.id) return -1;
47
+ if (a.id > b.id) return 1;
48
+ const identA = a.identifier();
49
+ const identB = b.identifier();
50
+ if (identA < identB) return -1;
51
+ if (identA > identB) return 1;
52
+ return 0;
53
+ };
54
+
55
+ const byIndexOrIdentifier = (a, b) => {
56
+ if (a.index < b.index) return -1;
57
+ if (a.index > b.index) return 1;
58
+ const identA = a.identifier();
59
+ const identB = b.identifier();
60
+ if (identA < identB) return -1;
61
+ if (identA > identB) return 1;
62
+ return 0;
63
+ };
64
+
65
+ const iterationBlockVariable = (variables, fn) => {
66
+ for (
67
+ let indexVariable = 0;
68
+ indexVariable < variables.length;
69
+ indexVariable++
70
+ ) {
71
+ const varDep = variables[indexVariable].dependencies;
72
+ for (let indexVDep = 0; indexVDep < varDep.length; indexVDep++) {
73
+ fn(varDep[indexVDep]);
74
+ }
75
+ }
76
+ };
77
+
78
+ const iterationOfArrayCallback = (arr, fn) => {
79
+ for (let index = 0; index < arr.length; index++) {
80
+ fn(arr[index]);
81
+ }
82
+ };
83
+
84
+ function addAllToSet(set, otherSet) {
85
+ for (const item of otherSet) {
86
+ set.add(item);
87
+ }
88
+ }
89
+
90
+ class Compilation extends Tapable {
91
+ constructor(compiler) {
92
+ super();
93
+ this.hooks = {
94
+ buildModule: new SyncHook(["module"]),
95
+ rebuildModule: new SyncHook(["module"]),
96
+ failedModule: new SyncHook(["module", "error"]),
97
+ succeedModule: new SyncHook(["module"]),
98
+
99
+ finishModules: new SyncHook(["modules"]),
100
+ finishRebuildingModule: new SyncHook(["module"]),
101
+
102
+ unseal: new SyncHook([]),
103
+ seal: new SyncHook([]),
104
+
105
+ optimizeDependenciesBasic: new SyncBailHook(["modules"]),
106
+ optimizeDependencies: new SyncBailHook(["modules"]),
107
+ optimizeDependenciesAdvanced: new SyncBailHook(["modules"]),
108
+ afterOptimizeDependencies: new SyncHook(["modules"]),
109
+
110
+ optimize: new SyncHook([]),
111
+
112
+ optimizeModulesBasic: new SyncBailHook(["modules"]),
113
+ optimizeModules: new SyncBailHook(["modules"]),
114
+ optimizeModulesAdvanced: new SyncBailHook(["modules"]),
115
+ afterOptimizeModules: new SyncHook(["modules"]),
116
+
117
+ optimizeChunksBasic: new SyncBailHook(["chunks", "chunkGroups"]),
118
+ optimizeChunks: new SyncBailHook(["chunks", "chunkGroups"]),
119
+ optimizeChunksAdvanced: new SyncBailHook(["chunks", "chunkGroups"]),
120
+ afterOptimizeChunks: new SyncHook(["chunks", "chunkGroups"]),
121
+
122
+ optimizeTree: new AsyncSeriesHook(["chunks", "modules"]),
123
+ afterOptimizeTree: new SyncHook(["chunks", "modules"]),
124
+
125
+ optimizeChunkModulesBasic: new SyncBailHook(["chunks", "modules"]),
126
+ optimizeChunkModules: new SyncBailHook(["chunks", "modules"]),
127
+ optimizeChunkModulesAdvanced: new SyncBailHook(["chunks", "modules"]),
128
+ afterOptimizeChunkModules: new SyncHook(["chunks", "modules"]),
129
+ shouldRecord: new SyncBailHook([]),
130
+
131
+ reviveModules: new SyncHook(["modules", "records"]),
132
+ optimizeModuleOrder: new SyncHook(["modules"]),
133
+ advancedOptimizeModuleOrder: new SyncHook(["modules"]),
134
+ beforeModuleIds: new SyncHook(["modules"]),
135
+ moduleIds: new SyncHook(["modules"]),
136
+ optimizeModuleIds: new SyncHook(["modules"]),
137
+ afterOptimizeModuleIds: new SyncHook(["modules"]),
138
+
139
+ reviveChunks: new SyncHook(["chunks", "records"]),
140
+ optimizeChunkOrder: new SyncHook(["chunks"]),
141
+ beforeChunkIds: new SyncHook(["chunks"]),
142
+ optimizeChunkIds: new SyncHook(["chunks"]),
143
+ afterOptimizeChunkIds: new SyncHook(["chunks"]),
144
+
145
+ recordModules: new SyncHook(["modules", "records"]),
146
+ recordChunks: new SyncHook(["chunks", "records"]),
147
+
148
+ beforeHash: new SyncHook([]),
149
+ contentHash: new SyncHook(["chunk"]),
150
+ afterHash: new SyncHook([]),
151
+
152
+ recordHash: new SyncHook(["records"]),
153
+
154
+ record: new SyncHook(["compilation", "records"]),
155
+
156
+ beforeModuleAssets: new SyncHook([]),
157
+ shouldGenerateChunkAssets: new SyncBailHook([]),
158
+ beforeChunkAssets: new SyncHook([]),
159
+ additionalChunkAssets: new SyncHook(["chunks"]),
160
+
161
+ additionalAssets: new AsyncSeriesHook([]),
162
+ optimizeChunkAssets: new AsyncSeriesHook(["chunks"]),
163
+ afterOptimizeChunkAssets: new SyncHook(["chunks"]),
164
+ optimizeAssets: new AsyncSeriesHook(["assets"]),
165
+ afterOptimizeAssets: new SyncHook(["assets"]),
166
+
167
+ needAdditionalSeal: new SyncBailHook([]),
168
+ afterSeal: new AsyncSeriesHook([]),
169
+
170
+ chunkHash: new SyncHook(["chunk", "chunkHash"]),
171
+ moduleAsset: new SyncHook(["module", "filename"]),
172
+ chunkAsset: new SyncHook(["chunk", "filename"]),
173
+
174
+ assetPath: new SyncWaterfallHook(["filename", "data"]), // TODO MainTemplate
175
+
176
+ needAdditionalPass: new SyncBailHook([]),
177
+ childCompiler: new SyncHook([
178
+ "childCompiler",
179
+ "compilerName",
180
+ "compilerIndex"
181
+ ]),
182
+
183
+ // TODO the following hooks are weirdly located here
184
+ // TODO move them for webpack 5
185
+ normalModuleLoader: new SyncHook(["loaderContext", "module"]),
186
+
187
+ optimizeExtractedChunksBasic: new SyncBailHook(["chunks"]),
188
+ optimizeExtractedChunks: new SyncBailHook(["chunks"]),
189
+ optimizeExtractedChunksAdvanced: new SyncBailHook(["chunks"]),
190
+ afterOptimizeExtractedChunks: new SyncHook(["chunks"])
191
+ };
192
+ this._pluginCompat.tap("Compilation", options => {
193
+ switch (options.name) {
194
+ case "optimize-tree":
195
+ case "additional-assets":
196
+ case "optimize-chunk-assets":
197
+ case "optimize-assets":
198
+ case "after-seal":
199
+ options.async = true;
200
+ break;
201
+ }
202
+ });
203
+ this.compiler = compiler;
204
+ this.resolverFactory = compiler.resolverFactory;
205
+ this.inputFileSystem = compiler.inputFileSystem;
206
+ this.requestShortener = compiler.requestShortener;
207
+
208
+ const options = (this.options = compiler.options);
209
+ this.outputOptions = options && options.output;
210
+ this.bail = options && options.bail;
211
+ this.profile = options && options.profile;
212
+ this.performance = options && options.performance;
213
+
214
+ this.mainTemplate = new MainTemplate(this.outputOptions);
215
+ this.chunkTemplate = new ChunkTemplate(this.outputOptions);
216
+ this.hotUpdateChunkTemplate = new HotUpdateChunkTemplate(
217
+ this.outputOptions
218
+ );
219
+ this.runtimeTemplate = new RuntimeTemplate(
220
+ this.outputOptions,
221
+ this.requestShortener
222
+ );
223
+ this.moduleTemplates = {
224
+ javascript: new ModuleTemplate(this.runtimeTemplate),
225
+ webassembly: new ModuleTemplate(this.runtimeTemplate)
226
+ };
227
+
228
+ this.semaphore = new Semaphore(options.parallelism || 100);
229
+
230
+ this.entries = [];
231
+ this._preparedEntrypoints = [];
232
+ this.entrypoints = new Map();
233
+ this.chunks = [];
234
+ this.chunkGroups = [];
235
+ this.namedChunkGroups = new Map();
236
+ this.namedChunks = new Map();
237
+ this.modules = [];
238
+ this._modules = new Map();
239
+ this.cache = null;
240
+ this.records = null;
241
+ this.nextFreeModuleIndex = undefined;
242
+ this.nextFreeModuleIndex2 = undefined;
243
+ this.additionalChunkAssets = [];
244
+ this.assets = {};
245
+ this.errors = [];
246
+ this.warnings = [];
247
+ this.children = [];
248
+ this.dependencyFactories = new Map();
249
+ this.dependencyTemplates = new Map();
250
+ this.dependencyTemplates.set("hash", "");
251
+ this.childrenCounters = {};
252
+ this.usedChunkIds = null;
253
+ this.usedModuleIds = null;
254
+ this.fileTimestamps = undefined;
255
+ this.contextTimestamps = undefined;
256
+ this.compilationDependencies = undefined;
257
+
258
+ this._buildingModules = new Map();
259
+ this._rebuildingModules = new Map();
260
+ }
261
+
262
+ getStats() {
263
+ return new Stats(this);
264
+ }
265
+
266
+ addModule(module, cacheGroup) {
267
+ const identifier = module.identifier();
268
+ const alreadyAddedModule = this._modules.get(identifier);
269
+ if (alreadyAddedModule) {
270
+ return {
271
+ module: alreadyAddedModule,
272
+ issuer: false,
273
+ build: false,
274
+ dependencies: false
275
+ };
276
+ }
277
+ const cacheName = (cacheGroup || "m") + identifier;
278
+ if (this.cache && this.cache[cacheName]) {
279
+ const cacheModule = this.cache[cacheName];
280
+
281
+ if (typeof cacheModule.updateCacheModule === "function")
282
+ cacheModule.updateCacheModule(module);
283
+
284
+ let rebuild = true;
285
+ if (this.fileTimestamps && this.contextTimestamps) {
286
+ rebuild = cacheModule.needRebuild(
287
+ this.fileTimestamps,
288
+ this.contextTimestamps
289
+ );
290
+ }
291
+
292
+ if (!rebuild) {
293
+ cacheModule.disconnect();
294
+ this._modules.set(identifier, cacheModule);
295
+ this.modules.push(cacheModule);
296
+ for (const err of cacheModule.errors) this.errors.push(err);
297
+ for (const err of cacheModule.warnings) this.warnings.push(err);
298
+ return {
299
+ module: cacheModule,
300
+ issuer: true,
301
+ build: false,
302
+ dependencies: true
303
+ };
304
+ }
305
+ cacheModule.unbuild();
306
+ module = cacheModule;
307
+ }
308
+ this._modules.set(identifier, module);
309
+ if (this.cache) {
310
+ this.cache[cacheName] = module;
311
+ }
312
+ this.modules.push(module);
313
+ return {
314
+ module: module,
315
+ issuer: true,
316
+ build: true,
317
+ dependencies: true
318
+ };
319
+ }
320
+
321
+ getModule(module) {
322
+ const identifier = module.identifier();
323
+ return this._modules.get(identifier);
324
+ }
325
+
326
+ findModule(identifier) {
327
+ return this._modules.get(identifier);
328
+ }
329
+
330
+ waitForBuildingFinished(module, callback) {
331
+ let callbackList = this._buildingModules.get(module);
332
+ if (callbackList) {
333
+ callbackList.push(() => callback());
334
+ } else {
335
+ process.nextTick(callback);
336
+ }
337
+ }
338
+
339
+ buildModule(module, optional, origin, dependencies, thisCallback) {
340
+ let callbackList = this._buildingModules.get(module);
341
+ if (callbackList) {
342
+ callbackList.push(thisCallback);
343
+ return;
344
+ }
345
+ this._buildingModules.set(module, (callbackList = [thisCallback]));
346
+
347
+ const callback = err => {
348
+ this._buildingModules.delete(module);
349
+ for (const cb of callbackList) cb(err);
350
+ };
351
+
352
+ this.hooks.buildModule.call(module);
353
+ module.build(
354
+ this.options,
355
+ this,
356
+ this.resolverFactory.get("normal", module.resolveOptions),
357
+ this.inputFileSystem,
358
+ error => {
359
+ const errors = module.errors;
360
+ for (let indexError = 0; indexError < errors.length; indexError++) {
361
+ const err = errors[indexError];
362
+ err.origin = origin;
363
+ err.dependencies = dependencies;
364
+ if (optional) this.warnings.push(err);
365
+ else this.errors.push(err);
366
+ }
367
+
368
+ const warnings = module.warnings;
369
+ for (
370
+ let indexWarning = 0;
371
+ indexWarning < warnings.length;
372
+ indexWarning++
373
+ ) {
374
+ const war = warnings[indexWarning];
375
+ war.origin = origin;
376
+ war.dependencies = dependencies;
377
+ this.warnings.push(war);
378
+ }
379
+ module.dependencies.sort(Dependency.compare);
380
+ if (error) {
381
+ this.hooks.failedModule.call(module, error);
382
+ return callback(error);
383
+ }
384
+ this.hooks.succeedModule.call(module);
385
+ return callback();
386
+ }
387
+ );
388
+ }
389
+
390
+ processModuleDependencies(module, callback) {
391
+ const dependencies = new Map();
392
+
393
+ const addDependency = dep => {
394
+ const resourceIdent = dep.getResourceIdentifier();
395
+ if (resourceIdent) {
396
+ const factory = this.dependencyFactories.get(dep.constructor);
397
+ if (factory === undefined)
398
+ throw new Error(
399
+ `No module factory available for dependency type: ${
400
+ dep.constructor.name
401
+ }`
402
+ );
403
+ let innerMap = dependencies.get(factory);
404
+ if (innerMap === undefined)
405
+ dependencies.set(factory, (innerMap = new Map()));
406
+ let list = innerMap.get(resourceIdent);
407
+ if (list === undefined) innerMap.set(resourceIdent, (list = []));
408
+ list.push(dep);
409
+ }
410
+ };
411
+
412
+ const addDependenciesBlock = block => {
413
+ if (block.dependencies) {
414
+ iterationOfArrayCallback(block.dependencies, addDependency);
415
+ }
416
+ if (block.blocks) {
417
+ iterationOfArrayCallback(block.blocks, addDependenciesBlock);
418
+ }
419
+ if (block.variables) {
420
+ iterationBlockVariable(block.variables, addDependency);
421
+ }
422
+ };
423
+
424
+ try {
425
+ addDependenciesBlock(module);
426
+ } catch (e) {
427
+ callback(e);
428
+ }
429
+
430
+ const sortedDependencies = [];
431
+
432
+ for (const pair1 of dependencies) {
433
+ for (const pair2 of pair1[1]) {
434
+ sortedDependencies.push({
435
+ factory: pair1[0],
436
+ dependencies: pair2[1]
437
+ });
438
+ }
439
+ }
440
+
441
+ this.addModuleDependencies(
442
+ module,
443
+ sortedDependencies,
444
+ this.bail,
445
+ null,
446
+ true,
447
+ callback
448
+ );
449
+ }
450
+
451
+ addModuleDependencies(
452
+ module,
453
+ dependencies,
454
+ bail,
455
+ cacheGroup,
456
+ recursive,
457
+ callback
458
+ ) {
459
+ let _this = this;
460
+ const start = _this.profile && Date.now();
461
+ const currentProfile = _this.profile && {};
462
+
463
+ asyncLib.forEach(
464
+ dependencies,
465
+ (item, callback) => {
466
+ const dependencies = item.dependencies;
467
+
468
+ const errorAndCallback = err => {
469
+ err.origin = module;
470
+ _this.errors.push(err);
471
+ if (bail) {
472
+ callback(err);
473
+ } else {
474
+ callback();
475
+ }
476
+ };
477
+ const warningAndCallback = err => {
478
+ err.origin = module;
479
+ _this.warnings.push(err);
480
+ callback();
481
+ };
482
+
483
+ const semaphore = _this.semaphore;
484
+ semaphore.acquire(() => {
485
+ if (_this === null) return semaphore.release();
486
+
487
+ const factory = item.factory;
488
+ factory.create(
489
+ {
490
+ contextInfo: {
491
+ issuer: module.nameForCondition && module.nameForCondition(),
492
+ compiler: _this.compiler.name
493
+ },
494
+ resolveOptions: module.resolveOptions,
495
+ context: module.context,
496
+ dependencies: dependencies
497
+ },
498
+ (err, dependentModule) => {
499
+ if (_this === null) return semaphore.release();
500
+
501
+ let afterFactory;
502
+
503
+ const isOptional = () => {
504
+ return dependencies.every(d => d.optional);
505
+ };
506
+
507
+ const errorOrWarningAndCallback = err => {
508
+ if (isOptional()) {
509
+ return warningAndCallback(err);
510
+ } else {
511
+ return errorAndCallback(err);
512
+ }
513
+ };
514
+
515
+ if (err) {
516
+ semaphore.release();
517
+ return errorOrWarningAndCallback(
518
+ new ModuleNotFoundError(module, err, dependencies)
519
+ );
520
+ }
521
+ if (!dependentModule) {
522
+ semaphore.release();
523
+ return process.nextTick(callback);
524
+ }
525
+ if (currentProfile) {
526
+ afterFactory = Date.now();
527
+ currentProfile.factory = afterFactory - start;
528
+ }
529
+
530
+ const iterationDependencies = depend => {
531
+ for (let index = 0; index < depend.length; index++) {
532
+ const dep = depend[index];
533
+ dep.module = dependentModule;
534
+ dependentModule.addReason(module, dep);
535
+ }
536
+ };
537
+
538
+ const addModuleResult = _this.addModule(
539
+ dependentModule,
540
+ cacheGroup
541
+ );
542
+ dependentModule = addModuleResult.module;
543
+ iterationDependencies(dependencies);
544
+
545
+ const afterBuild = () => {
546
+ if (currentProfile) {
547
+ const afterBuilding = Date.now();
548
+ currentProfile.building = afterBuilding - afterFactory;
549
+ }
550
+
551
+ if (recursive && addModuleResult.dependencies) {
552
+ _this.processModuleDependencies(dependentModule, callback);
553
+ } else {
554
+ return callback();
555
+ }
556
+ };
557
+
558
+ if (addModuleResult.issuer) {
559
+ if (currentProfile) {
560
+ dependentModule.profile = currentProfile;
561
+ }
562
+
563
+ dependentModule.issuer = module;
564
+ } else {
565
+ if (_this.profile) {
566
+ if (module.profile) {
567
+ const time = Date.now() - start;
568
+ if (
569
+ !module.profile.dependencies ||
570
+ time > module.profile.dependencies
571
+ ) {
572
+ module.profile.dependencies = time;
573
+ }
574
+ }
575
+ }
576
+ }
577
+
578
+ if (addModuleResult.build) {
579
+ _this.buildModule(
580
+ dependentModule,
581
+ isOptional(),
582
+ module,
583
+ dependencies,
584
+ err => {
585
+ if (_this === null) return semaphore.release();
586
+
587
+ if (err) {
588
+ semaphore.release();
589
+ return errorOrWarningAndCallback(err);
590
+ }
591
+
592
+ if (currentProfile) {
593
+ const afterBuilding = Date.now();
594
+ currentProfile.building = afterBuilding - afterFactory;
595
+ }
596
+
597
+ semaphore.release();
598
+ afterBuild();
599
+ }
600
+ );
601
+ } else {
602
+ semaphore.release();
603
+ _this.waitForBuildingFinished(dependentModule, afterBuild);
604
+ }
605
+ }
606
+ );
607
+ });
608
+ },
609
+ err => {
610
+ // In V8, the Error objects keep a reference to the functions on the stack. These warnings &
611
+ // errors are created inside closures that keep a reference to the Compilation, so errors are
612
+ // leaking the Compilation object.
613
+
614
+ if (err) {
615
+ err.stack = err.stack;
616
+ return callback(err);
617
+ }
618
+
619
+ return process.nextTick(callback);
620
+ }
621
+ );
622
+ }
623
+
624
+ _addModuleChain(context, dependency, onModule, callback) {
625
+ const start = this.profile && Date.now();
626
+ const currentProfile = this.profile && {};
627
+
628
+ const errorAndCallback = this.bail
629
+ ? err => {
630
+ callback(err);
631
+ }
632
+ : err => {
633
+ err.dependencies = [dependency];
634
+ this.errors.push(err);
635
+ callback();
636
+ };
637
+
638
+ if (
639
+ typeof dependency !== "object" ||
640
+ dependency === null ||
641
+ !dependency.constructor
642
+ ) {
643
+ throw new Error("Parameter 'dependency' must be a Dependency");
644
+ }
645
+
646
+ const moduleFactory = this.dependencyFactories.get(dependency.constructor);
647
+ if (!moduleFactory) {
648
+ throw new Error(
649
+ `No dependency factory available for this dependency type: ${
650
+ dependency.constructor.name
651
+ }`
652
+ );
653
+ }
654
+
655
+ this.semaphore.acquire(() => {
656
+ moduleFactory.create(
657
+ {
658
+ contextInfo: {
659
+ issuer: "",
660
+ compiler: this.compiler.name
661
+ },
662
+ context: context,
663
+ dependencies: [dependency]
664
+ },
665
+ (err, module) => {
666
+ if (err) {
667
+ this.semaphore.release();
668
+ return errorAndCallback(new EntryModuleNotFoundError(err));
669
+ }
670
+
671
+ let afterFactory;
672
+
673
+ if (currentProfile) {
674
+ afterFactory = Date.now();
675
+ currentProfile.factory = afterFactory - start;
676
+ }
677
+
678
+ const addModuleResult = this.addModule(module);
679
+ module = addModuleResult.module;
680
+
681
+ onModule(module);
682
+
683
+ dependency.module = module;
684
+ module.addReason(null, dependency);
685
+
686
+ const afterBuild = () => {
687
+ if (currentProfile) {
688
+ const afterBuilding = Date.now();
689
+ currentProfile.building = afterBuilding - afterFactory;
690
+ }
691
+
692
+ if (addModuleResult.dependencies) {
693
+ this.processModuleDependencies(module, err => {
694
+ if (err) return callback(err);
695
+ callback(null, module);
696
+ });
697
+ } else {
698
+ return callback(null, module);
699
+ }
700
+ };
701
+
702
+ if (addModuleResult.issuer) {
703
+ if (currentProfile) {
704
+ module.profile = currentProfile;
705
+ }
706
+ }
707
+
708
+ if (addModuleResult.build) {
709
+ this.buildModule(module, false, null, null, err => {
710
+ if (err) {
711
+ this.semaphore.release();
712
+ return errorAndCallback(err);
713
+ }
714
+
715
+ if (currentProfile) {
716
+ const afterBuilding = Date.now();
717
+ currentProfile.building = afterBuilding - afterFactory;
718
+ }
719
+
720
+ this.semaphore.release();
721
+ afterBuild();
722
+ });
723
+ } else {
724
+ this.semaphore.release();
725
+ this.waitForBuildingFinished(module, afterBuild);
726
+ }
727
+ }
728
+ );
729
+ });
730
+ }
731
+
732
+ addEntry(context, entry, name, callback) {
733
+ const slot = {
734
+ name: name,
735
+ request: entry.request,
736
+ module: null
737
+ };
738
+ this._preparedEntrypoints.push(slot);
739
+ this._addModuleChain(
740
+ context,
741
+ entry,
742
+ module => {
743
+ this.entries.push(module);
744
+ },
745
+ (err, module) => {
746
+ if (err) {
747
+ return callback(err);
748
+ }
749
+
750
+ if (module) {
751
+ slot.module = module;
752
+ } else {
753
+ const idx = this._preparedEntrypoints.indexOf(slot);
754
+ this._preparedEntrypoints.splice(idx, 1);
755
+ }
756
+ return callback(null, module);
757
+ }
758
+ );
759
+ }
760
+
761
+ prefetch(context, dependency, callback) {
762
+ this._addModuleChain(
763
+ context,
764
+ dependency,
765
+ module => {
766
+ module.prefetched = true;
767
+ },
768
+ callback
769
+ );
770
+ }
771
+
772
+ rebuildModule(module, thisCallback) {
773
+ let callbackList = this._rebuildingModules.get(module);
774
+ if (callbackList) {
775
+ callbackList.push(thisCallback);
776
+ return;
777
+ }
778
+ this._rebuildingModules.set(module, (callbackList = [thisCallback]));
779
+
780
+ const callback = err => {
781
+ this._rebuildingModules.delete(module);
782
+ for (const cb of callbackList) cb(err);
783
+ };
784
+
785
+ this.hooks.rebuildModule.call(module);
786
+ const oldDependencies = module.dependencies.slice();
787
+ const oldVariables = module.variables.slice();
788
+ const oldBlocks = module.blocks.slice();
789
+ module.unbuild();
790
+ this.buildModule(module, false, module, null, err => {
791
+ if (err) {
792
+ this.hooks.finishRebuildingModule.call(module);
793
+ return callback(err);
794
+ }
795
+
796
+ this.processModuleDependencies(module, err => {
797
+ if (err) return callback(err);
798
+ this.removeReasonsOfDependencyBlock(module, {
799
+ dependencies: oldDependencies,
800
+ variables: oldVariables,
801
+ blocks: oldBlocks
802
+ });
803
+ this.hooks.finishRebuildingModule.call(module);
804
+ callback();
805
+ });
806
+ });
807
+ }
808
+
809
+ finish() {
810
+ const modules = this.modules;
811
+ this.hooks.finishModules.call(modules);
812
+
813
+ for (let index = 0; index < modules.length; index++) {
814
+ const module = modules[index];
815
+ this.reportDependencyErrorsAndWarnings(module, [module]);
816
+ }
817
+ }
818
+
819
+ unseal() {
820
+ this.hooks.unseal.call();
821
+ this.chunks.length = 0;
822
+ this.chunkGroups.length = 0;
823
+ this.namedChunks.clear();
824
+ this.namedChunkGroups.clear();
825
+ this.additionalChunkAssets.length = 0;
826
+ this.assets = {};
827
+ for (const module of this.modules) {
828
+ module.unseal();
829
+ }
830
+ }
831
+
832
+ seal(callback) {
833
+ this.hooks.seal.call();
834
+
835
+ while (
836
+ this.hooks.optimizeDependenciesBasic.call(this.modules) ||
837
+ this.hooks.optimizeDependencies.call(this.modules) ||
838
+ this.hooks.optimizeDependenciesAdvanced.call(this.modules)
839
+ ) {
840
+ /* empty */
841
+ }
842
+ this.hooks.afterOptimizeDependencies.call(this.modules);
843
+
844
+ this.nextFreeModuleIndex = 0;
845
+ this.nextFreeModuleIndex2 = 0;
846
+ for (const preparedEntrypoint of this._preparedEntrypoints) {
847
+ const module = preparedEntrypoint.module;
848
+ const name = preparedEntrypoint.name;
849
+ const chunk = this.addChunk(name);
850
+ const entrypoint = new Entrypoint(name);
851
+ entrypoint.setRuntimeChunk(chunk);
852
+ entrypoint.addOrigin(null, name, preparedEntrypoint.request);
853
+ this.namedChunkGroups.set(name, entrypoint);
854
+ this.entrypoints.set(name, entrypoint);
855
+ this.chunkGroups.push(entrypoint);
856
+
857
+ GraphHelpers.connectChunkGroupAndChunk(entrypoint, chunk);
858
+ GraphHelpers.connectChunkAndModule(chunk, module);
859
+
860
+ chunk.entryModule = module;
861
+ chunk.name = name;
862
+
863
+ this.assignIndex(module);
864
+ this.assignDepth(module);
865
+ }
866
+ this.processDependenciesBlocksForChunkGroups(this.chunkGroups);
867
+ this.sortModules(this.modules);
868
+ this.hooks.optimize.call();
869
+
870
+ while (
871
+ this.hooks.optimizeModulesBasic.call(this.modules) ||
872
+ this.hooks.optimizeModules.call(this.modules) ||
873
+ this.hooks.optimizeModulesAdvanced.call(this.modules)
874
+ ) {
875
+ /* empty */
876
+ }
877
+ this.hooks.afterOptimizeModules.call(this.modules);
878
+
879
+ while (
880
+ this.hooks.optimizeChunksBasic.call(this.chunks, this.chunkGroups) ||
881
+ this.hooks.optimizeChunks.call(this.chunks, this.chunkGroups) ||
882
+ this.hooks.optimizeChunksAdvanced.call(this.chunks, this.chunkGroups)
883
+ ) {
884
+ /* empty */
885
+ }
886
+ this.hooks.afterOptimizeChunks.call(this.chunks, this.chunkGroups);
887
+
888
+ this.hooks.optimizeTree.callAsync(this.chunks, this.modules, err => {
889
+ if (err) {
890
+ return callback(err);
891
+ }
892
+
893
+ this.hooks.afterOptimizeTree.call(this.chunks, this.modules);
894
+
895
+ while (
896
+ this.hooks.optimizeChunkModulesBasic.call(this.chunks, this.modules) ||
897
+ this.hooks.optimizeChunkModules.call(this.chunks, this.modules) ||
898
+ this.hooks.optimizeChunkModulesAdvanced.call(this.chunks, this.modules)
899
+ ) {
900
+ /* empty */
901
+ }
902
+ this.hooks.afterOptimizeChunkModules.call(this.chunks, this.modules);
903
+
904
+ const shouldRecord = this.hooks.shouldRecord.call() !== false;
905
+
906
+ this.hooks.reviveModules.call(this.modules, this.records);
907
+ this.hooks.optimizeModuleOrder.call(this.modules);
908
+ this.hooks.advancedOptimizeModuleOrder.call(this.modules);
909
+ this.hooks.beforeModuleIds.call(this.modules);
910
+ this.hooks.moduleIds.call(this.modules);
911
+ this.applyModuleIds();
912
+ this.hooks.optimizeModuleIds.call(this.modules);
913
+ this.hooks.afterOptimizeModuleIds.call(this.modules);
914
+
915
+ this.sortItemsWithModuleIds();
916
+
917
+ this.hooks.reviveChunks.call(this.chunks, this.records);
918
+ this.hooks.optimizeChunkOrder.call(this.chunks);
919
+ this.hooks.beforeChunkIds.call(this.chunks);
920
+ this.applyChunkIds();
921
+ this.hooks.optimizeChunkIds.call(this.chunks);
922
+ this.hooks.afterOptimizeChunkIds.call(this.chunks);
923
+
924
+ this.sortItemsWithChunkIds();
925
+
926
+ if (shouldRecord)
927
+ this.hooks.recordModules.call(this.modules, this.records);
928
+ if (shouldRecord) this.hooks.recordChunks.call(this.chunks, this.records);
929
+
930
+ this.hooks.beforeHash.call();
931
+ this.createHash();
932
+ this.hooks.afterHash.call();
933
+
934
+ if (shouldRecord) this.hooks.recordHash.call(this.records);
935
+
936
+ this.hooks.beforeModuleAssets.call();
937
+ this.createModuleAssets();
938
+ if (this.hooks.shouldGenerateChunkAssets.call() !== false) {
939
+ this.hooks.beforeChunkAssets.call();
940
+ this.createChunkAssets();
941
+ }
942
+ this.hooks.additionalChunkAssets.call(this.chunks);
943
+ this.summarizeDependencies();
944
+ if (shouldRecord) this.hooks.record.call(this, this.records);
945
+
946
+ this.hooks.additionalAssets.callAsync(err => {
947
+ if (err) {
948
+ return callback(err);
949
+ }
950
+ this.hooks.optimizeChunkAssets.callAsync(this.chunks, err => {
951
+ if (err) {
952
+ return callback(err);
953
+ }
954
+ this.hooks.afterOptimizeChunkAssets.call(this.chunks);
955
+ this.hooks.optimizeAssets.callAsync(this.assets, err => {
956
+ if (err) {
957
+ return callback(err);
958
+ }
959
+ this.hooks.afterOptimizeAssets.call(this.assets);
960
+ if (this.hooks.needAdditionalSeal.call()) {
961
+ this.unseal();
962
+ return this.seal(callback);
963
+ }
964
+ return this.hooks.afterSeal.callAsync(callback);
965
+ });
966
+ });
967
+ });
968
+ });
969
+ }
970
+
971
+ sortModules(modules) {
972
+ modules.sort(byIndexOrIdentifier);
973
+ }
974
+
975
+ reportDependencyErrorsAndWarnings(module, blocks) {
976
+ for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) {
977
+ const block = blocks[indexBlock];
978
+ const dependencies = block.dependencies;
979
+
980
+ for (let indexDep = 0; indexDep < dependencies.length; indexDep++) {
981
+ const d = dependencies[indexDep];
982
+
983
+ const warnings = d.getWarnings();
984
+ if (warnings) {
985
+ for (let indexWar = 0; indexWar < warnings.length; indexWar++) {
986
+ const w = warnings[indexWar];
987
+
988
+ const warning = new ModuleDependencyWarning(module, w, d.loc);
989
+ this.warnings.push(warning);
990
+ }
991
+ }
992
+ const errors = d.getErrors();
993
+ if (errors) {
994
+ for (let indexErr = 0; indexErr < errors.length; indexErr++) {
995
+ const e = errors[indexErr];
996
+
997
+ const error = new ModuleDependencyError(module, e, d.loc);
998
+ this.errors.push(error);
999
+ }
1000
+ }
1001
+ }
1002
+
1003
+ this.reportDependencyErrorsAndWarnings(module, block.blocks);
1004
+ }
1005
+ }
1006
+
1007
+ addChunkInGroup(name, module, loc, request) {
1008
+ if (name) {
1009
+ const chunkGroup = this.namedChunkGroups.get(name);
1010
+ if (chunkGroup !== undefined) {
1011
+ if (module) {
1012
+ chunkGroup.addOrigin(module, loc, request);
1013
+ }
1014
+ return chunkGroup;
1015
+ }
1016
+ }
1017
+ const chunkGroup = new ChunkGroup(name);
1018
+ if (module) chunkGroup.addOrigin(module, loc, request);
1019
+ const chunk = this.addChunk(name);
1020
+
1021
+ GraphHelpers.connectChunkGroupAndChunk(chunkGroup, chunk);
1022
+
1023
+ this.chunkGroups.push(chunkGroup);
1024
+ if (name) {
1025
+ this.namedChunkGroups.set(name, chunkGroup);
1026
+ }
1027
+ return chunkGroup;
1028
+ }
1029
+
1030
+ addChunk(name) {
1031
+ if (name) {
1032
+ const chunk = this.namedChunks.get(name);
1033
+ if (chunk !== undefined) {
1034
+ return chunk;
1035
+ }
1036
+ }
1037
+ const chunk = new Chunk(name);
1038
+ this.chunks.push(chunk);
1039
+ if (name) {
1040
+ this.namedChunks.set(name, chunk);
1041
+ }
1042
+ return chunk;
1043
+ }
1044
+
1045
+ assignIndex(module) {
1046
+ const _this = this;
1047
+
1048
+ const assignIndexToModule = module => {
1049
+ // enter module
1050
+ if (typeof module.index !== "number") {
1051
+ module.index = _this.nextFreeModuleIndex++;
1052
+
1053
+ // leave module
1054
+ queue.push(() => (module.index2 = _this.nextFreeModuleIndex2++));
1055
+
1056
+ // enter it as block
1057
+ assignIndexToDependencyBlock(module);
1058
+ }
1059
+ };
1060
+
1061
+ const assignIndexToDependency = dependency => {
1062
+ if (dependency.module) {
1063
+ queue.push(() => assignIndexToModule(dependency.module));
1064
+ }
1065
+ };
1066
+
1067
+ const assignIndexToDependencyBlock = block => {
1068
+ let allDependencies = [];
1069
+
1070
+ const iteratorDependency = d => allDependencies.push(d);
1071
+
1072
+ const iteratorBlock = b =>
1073
+ queue.push(() => assignIndexToDependencyBlock(b));
1074
+
1075
+ if (block.variables) {
1076
+ iterationBlockVariable(block.variables, iteratorDependency);
1077
+ }
1078
+
1079
+ if (block.dependencies) {
1080
+ iterationOfArrayCallback(block.dependencies, iteratorDependency);
1081
+ }
1082
+ if (block.blocks) {
1083
+ const blocks = block.blocks;
1084
+ let indexBlock = blocks.length;
1085
+ while (indexBlock--) {
1086
+ iteratorBlock(blocks[indexBlock]);
1087
+ }
1088
+ }
1089
+
1090
+ let indexAll = allDependencies.length;
1091
+ while (indexAll--) {
1092
+ iteratorAllDependencies(allDependencies[indexAll]);
1093
+ }
1094
+ };
1095
+
1096
+ const queue = [
1097
+ () => {
1098
+ assignIndexToModule(module);
1099
+ }
1100
+ ];
1101
+
1102
+ const iteratorAllDependencies = d => {
1103
+ queue.push(() => assignIndexToDependency(d));
1104
+ };
1105
+
1106
+ while (queue.length) {
1107
+ queue.pop()();
1108
+ }
1109
+ }
1110
+
1111
+ assignDepth(module) {
1112
+ const queue = new Set([module]);
1113
+ let depth;
1114
+
1115
+ module.depth = 0;
1116
+
1117
+ const enqueueJob = module => {
1118
+ const d = module.depth;
1119
+ if (typeof d === "number" && d <= depth) return;
1120
+ queue.add(module);
1121
+ module.depth = depth;
1122
+ };
1123
+
1124
+ const assignDepthToDependency = (dependency, depth) => {
1125
+ if (dependency.module) {
1126
+ enqueueJob(dependency.module);
1127
+ }
1128
+ };
1129
+
1130
+ const assignDepthToDependencyBlock = block => {
1131
+ if (block.variables) {
1132
+ iterationBlockVariable(block.variables, assignDepthToDependency);
1133
+ }
1134
+
1135
+ if (block.dependencies) {
1136
+ iterationOfArrayCallback(block.dependencies, assignDepthToDependency);
1137
+ }
1138
+
1139
+ if (block.blocks) {
1140
+ iterationOfArrayCallback(block.blocks, assignDepthToDependencyBlock);
1141
+ }
1142
+ };
1143
+
1144
+ for (module of queue) {
1145
+ queue.delete(module);
1146
+ depth = module.depth;
1147
+
1148
+ depth++;
1149
+ assignDepthToDependencyBlock(module);
1150
+ }
1151
+ }
1152
+
1153
+ // This method creates the Chunk graph from the Module graph
1154
+ processDependenciesBlocksForChunkGroups(inputChunkGroups) {
1155
+ // Process is splitting into two parts:
1156
+ // Part one traverse the module graph and builds a very basic chunks graph
1157
+ // in chunkDependencies.
1158
+ // Part two traverse every possible way through the basic chunk graph and
1159
+ // tracks the available modules. While traversing it connects chunks with
1160
+ // eachother and Blocks with Chunks. It stops traversing when all modules
1161
+ // for a chunk are already available. So it doesn't connect unneeded chunks.
1162
+
1163
+ const chunkDependencies = new Map(); // Map<Chunk, Array<{Module, Chunk}>>
1164
+ const allCreatedChunkGroups = new Set();
1165
+
1166
+ // PART ONE
1167
+
1168
+ const blockChunkGroups = new Map();
1169
+
1170
+ // Start with the provided modules/chunks
1171
+ const queue = inputChunkGroups.map(chunkGroup => ({
1172
+ block: chunkGroup.chunks[0].entryModule,
1173
+ module: chunkGroup.chunks[0].entryModule,
1174
+ chunk: chunkGroup.chunks[0],
1175
+ chunkGroup
1176
+ }));
1177
+
1178
+ let module, block, chunk, chunkGroup;
1179
+
1180
+ // For each async Block in graph
1181
+ const iteratorBlock = b => {
1182
+ // 1. We create a chunk for this Block
1183
+ // but only once (blockChunkGroups map)
1184
+ let c = blockChunkGroups.get(b);
1185
+ if (c === undefined) {
1186
+ c = this.namedChunkGroups.get(b.chunkName);
1187
+ if (c && c.isInitial()) {
1188
+ this.errors.push(
1189
+ new AsyncDependencyToInitialChunkError(b.chunkName, module, b.loc)
1190
+ );
1191
+ c = chunkGroup;
1192
+ } else {
1193
+ c = this.addChunkInGroup(b.chunkName, module, b.loc, b.request);
1194
+ blockChunkGroups.set(b, c);
1195
+ allCreatedChunkGroups.add(c);
1196
+ }
1197
+ } else {
1198
+ c.addOrigin(module, b.loc, b.request);
1199
+ }
1200
+
1201
+ // 2. We store the Block+Chunk mapping as dependency for the chunk
1202
+ let deps = chunkDependencies.get(chunkGroup);
1203
+ if (!deps) chunkDependencies.set(chunkGroup, (deps = []));
1204
+ deps.push({
1205
+ block: b,
1206
+ chunkGroup: c
1207
+ });
1208
+
1209
+ // 3. We enqueue the DependenciesBlock for traversal
1210
+ queue.push({
1211
+ block: b,
1212
+ module: module,
1213
+ chunk: c.chunks[0],
1214
+ chunkGroup: c
1215
+ });
1216
+ };
1217
+
1218
+ // For each Dependency in the graph
1219
+ const iteratorDependency = d => {
1220
+ // We skip Dependencies without Reference
1221
+ const ref = d.getReference();
1222
+ if (!ref) {
1223
+ return;
1224
+ }
1225
+ // We skip Dependencies without Module pointer
1226
+ const refModule = ref.module;
1227
+ if (!refModule) {
1228
+ return;
1229
+ }
1230
+ // We skip weak Dependencies
1231
+ if (ref.weak) {
1232
+ return;
1233
+ }
1234
+ // We connect Module and Chunk when not already done
1235
+ if (chunk.addModule(refModule)) {
1236
+ refModule.addChunk(chunk);
1237
+
1238
+ // And enqueue the Module for traversal
1239
+ queue.push({
1240
+ block: refModule,
1241
+ module: refModule,
1242
+ chunk,
1243
+ chunkGroup
1244
+ });
1245
+ }
1246
+ };
1247
+
1248
+ // Iterative traversal of the Module graph
1249
+ // Recursive would be simpler to write but could result in Stack Overflows
1250
+ while (queue.length) {
1251
+ const queueItem = queue.pop();
1252
+ module = queueItem.module;
1253
+ block = queueItem.block;
1254
+ chunk = queueItem.chunk;
1255
+ chunkGroup = queueItem.chunkGroup;
1256
+
1257
+ // Traverse all variables, Dependencies and Blocks
1258
+ if (block.variables) {
1259
+ iterationBlockVariable(block.variables, iteratorDependency);
1260
+ }
1261
+
1262
+ if (block.dependencies) {
1263
+ iterationOfArrayCallback(block.dependencies, iteratorDependency);
1264
+ }
1265
+
1266
+ if (block.blocks) {
1267
+ iterationOfArrayCallback(block.blocks, iteratorBlock);
1268
+ }
1269
+ }
1270
+
1271
+ // PART TWO
1272
+
1273
+ let availableModules;
1274
+ let newAvailableModules;
1275
+ const queue2 = new Queue(
1276
+ inputChunkGroups.map(chunkGroup => ({
1277
+ chunkGroup,
1278
+ availableModules: new Set()
1279
+ }))
1280
+ );
1281
+
1282
+ // Helper function to check if all modules of a chunk are available
1283
+ const areModulesAvailable = (chunkGroup, availableModules) => {
1284
+ for (const chunk of chunkGroup.chunks) {
1285
+ for (const module of chunk.modulesIterable) {
1286
+ if (!availableModules.has(module)) return false;
1287
+ }
1288
+ }
1289
+ return true;
1290
+ };
1291
+
1292
+ // For each edge in the basic chunk graph
1293
+ const filterFn = dep => {
1294
+ // Filter egdes that are not needed because all modules are already available
1295
+ // This also filters circular dependencies in the chunks graph
1296
+ const depChunkGroup = dep.chunkGroup;
1297
+ if (areModulesAvailable(depChunkGroup, newAvailableModules)) return false; // break all modules are already available
1298
+ return true;
1299
+ };
1300
+
1301
+ const minAvailableModulesMap = new Map();
1302
+
1303
+ // Iterative traversing of the basic chunk graph
1304
+ while (queue2.length) {
1305
+ const queueItem = queue2.dequeue();
1306
+ chunkGroup = queueItem.chunkGroup;
1307
+ availableModules = queueItem.availableModules;
1308
+
1309
+ // 1. Get minimal available modules
1310
+ // It doesn't make sense to traverse a chunk again with more available modules.
1311
+ // This step calculates the minimal available modules and skips traversal when
1312
+ // the list didn't shrink.
1313
+ let minAvailableModules = minAvailableModulesMap.get(chunkGroup);
1314
+ if (minAvailableModules === undefined) {
1315
+ minAvailableModulesMap.set(chunkGroup, new Set(availableModules));
1316
+ } else {
1317
+ let deletedModules = false;
1318
+ for (const m of minAvailableModules) {
1319
+ if (!availableModules.has(m)) {
1320
+ minAvailableModules.delete(m);
1321
+ deletedModules = true;
1322
+ }
1323
+ }
1324
+ if (!deletedModules) continue;
1325
+ availableModules = minAvailableModules;
1326
+ }
1327
+
1328
+ // 2. Get the edges at this point of the graph
1329
+ const deps = chunkDependencies.get(chunkGroup);
1330
+ if (!deps) continue;
1331
+ if (deps.length === 0) continue;
1332
+
1333
+ // 3. Create a new Set of available modules at this points
1334
+ newAvailableModules = new Set(availableModules);
1335
+ for (const chunk of chunkGroup.chunks)
1336
+ for (const m of chunk.modulesIterable) newAvailableModules.add(m);
1337
+
1338
+ // 4. Filter edges with available modules
1339
+ const filteredDeps = deps.filter(filterFn);
1340
+
1341
+ // 5. Foreach remaining edge
1342
+ const nextChunkGroups = new Set();
1343
+ for (let i = 0; i < filteredDeps.length; i++) {
1344
+ const dep = filteredDeps[i];
1345
+ const depChunkGroup = dep.chunkGroup;
1346
+ const depBlock = dep.block;
1347
+
1348
+ // 6. Connect block with chunk
1349
+ GraphHelpers.connectDependenciesBlockAndChunkGroup(
1350
+ depBlock,
1351
+ depChunkGroup
1352
+ );
1353
+
1354
+ // 7. Connect chunk with parent
1355
+ GraphHelpers.connectChunkGroupParentAndChild(chunkGroup, depChunkGroup);
1356
+
1357
+ nextChunkGroups.add(depChunkGroup);
1358
+ }
1359
+
1360
+ // 8. Enqueue further traversal
1361
+ for (const nextChunkGroup of nextChunkGroups) {
1362
+ queue2.enqueue({
1363
+ chunkGroup: nextChunkGroup,
1364
+ availableModules: newAvailableModules
1365
+ });
1366
+ }
1367
+ }
1368
+
1369
+ // Remove all unconnected chunk groups
1370
+ for (const chunkGroup of allCreatedChunkGroups) {
1371
+ if (chunkGroup.getNumberOfParents() === 0) {
1372
+ for (const chunk of chunkGroup.chunks) {
1373
+ const idx = this.chunks.indexOf(chunk);
1374
+ if (idx >= 0) this.chunks.splice(idx, 1);
1375
+ chunk.remove("unconnected");
1376
+ }
1377
+ chunkGroup.remove("unconnected");
1378
+ }
1379
+ }
1380
+ }
1381
+
1382
+ removeReasonsOfDependencyBlock(module, block) {
1383
+ const iteratorDependency = d => {
1384
+ if (!d.module) {
1385
+ return;
1386
+ }
1387
+ if (d.module.removeReason(module, d)) {
1388
+ for (const chunk of d.module.chunksIterable) {
1389
+ this.patchChunksAfterReasonRemoval(d.module, chunk);
1390
+ }
1391
+ }
1392
+ };
1393
+
1394
+ if (block.blocks) {
1395
+ iterationOfArrayCallback(block.blocks, block =>
1396
+ this.removeReasonsOfDependencyBlock(module, block)
1397
+ );
1398
+ }
1399
+
1400
+ if (block.dependencies) {
1401
+ iterationOfArrayCallback(block.dependencies, iteratorDependency);
1402
+ }
1403
+
1404
+ if (block.variables) {
1405
+ iterationBlockVariable(block.variables, iteratorDependency);
1406
+ }
1407
+ }
1408
+
1409
+ patchChunksAfterReasonRemoval(module, chunk) {
1410
+ if (!module.hasReasons()) {
1411
+ this.removeReasonsOfDependencyBlock(module, module);
1412
+ }
1413
+ if (!module.hasReasonForChunk(chunk)) {
1414
+ if (module.removeChunk(chunk)) {
1415
+ this.removeChunkFromDependencies(module, chunk);
1416
+ }
1417
+ }
1418
+ }
1419
+
1420
+ removeChunkFromDependencies(block, chunk) {
1421
+ const iteratorDependency = d => {
1422
+ if (!d.module) {
1423
+ return;
1424
+ }
1425
+ this.patchChunksAfterReasonRemoval(d.module, chunk);
1426
+ };
1427
+
1428
+ const blocks = block.blocks;
1429
+ for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) {
1430
+ const chunks = blocks[indexBlock].chunks;
1431
+ for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1432
+ const blockChunk = chunks[indexChunk];
1433
+ chunk.removeChunk(blockChunk);
1434
+ blockChunk.removeParent(chunk);
1435
+ this.removeChunkFromDependencies(chunks, blockChunk);
1436
+ }
1437
+ }
1438
+
1439
+ if (block.dependencies) {
1440
+ iterationOfArrayCallback(block.dependencies, iteratorDependency);
1441
+ }
1442
+
1443
+ if (block.variables) {
1444
+ iterationBlockVariable(block.variables, iteratorDependency);
1445
+ }
1446
+ }
1447
+
1448
+ applyModuleIds() {
1449
+ const unusedIds = [];
1450
+ let nextFreeModuleId = 0;
1451
+ const usedIds = new Set();
1452
+ if (this.usedModuleIds) {
1453
+ for (const id of this.usedModuleIds) {
1454
+ usedIds.add(id);
1455
+ }
1456
+ }
1457
+
1458
+ const modules1 = this.modules;
1459
+ for (let indexModule1 = 0; indexModule1 < modules1.length; indexModule1++) {
1460
+ const module1 = modules1[indexModule1];
1461
+ if (module1.id !== null) {
1462
+ usedIds.add(module1.id);
1463
+ }
1464
+ }
1465
+
1466
+ if (usedIds.size > 0) {
1467
+ let usedIdMax = -1;
1468
+ for (const usedIdKey of usedIds) {
1469
+ if (typeof usedIdKey !== "number") {
1470
+ continue;
1471
+ }
1472
+
1473
+ usedIdMax = Math.max(usedIdMax, usedIdKey);
1474
+ }
1475
+
1476
+ let lengthFreeModules = (nextFreeModuleId = usedIdMax + 1);
1477
+
1478
+ while (lengthFreeModules--) {
1479
+ if (!usedIds.has(lengthFreeModules)) {
1480
+ unusedIds.push(lengthFreeModules);
1481
+ }
1482
+ }
1483
+ }
1484
+
1485
+ const modules2 = this.modules;
1486
+ for (let indexModule2 = 0; indexModule2 < modules2.length; indexModule2++) {
1487
+ const module2 = modules2[indexModule2];
1488
+ if (module2.id === null) {
1489
+ if (unusedIds.length > 0) module2.id = unusedIds.pop();
1490
+ else module2.id = nextFreeModuleId++;
1491
+ }
1492
+ }
1493
+ }
1494
+
1495
+ applyChunkIds() {
1496
+ const usedIds = new Set();
1497
+
1498
+ // Get used ids from usedChunkIds property (i. e. from records)
1499
+ if (this.usedChunkIds) {
1500
+ for (const id of this.usedChunkIds) {
1501
+ if (typeof id !== "number") {
1502
+ continue;
1503
+ }
1504
+
1505
+ usedIds.add(id);
1506
+ }
1507
+ }
1508
+
1509
+ // Get used ids from existing chunks
1510
+ const chunks = this.chunks;
1511
+ for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1512
+ const chunk = chunks[indexChunk];
1513
+ const usedIdValue = chunk.id;
1514
+
1515
+ if (typeof usedIdValue !== "number") {
1516
+ continue;
1517
+ }
1518
+
1519
+ usedIds.add(usedIdValue);
1520
+ }
1521
+
1522
+ // Calculate maximum assigned chunk id
1523
+ let nextFreeChunkId = -1;
1524
+ for (const id of usedIds) {
1525
+ nextFreeChunkId = Math.max(nextFreeChunkId, id);
1526
+ }
1527
+ nextFreeChunkId++;
1528
+
1529
+ // Determine free chunk ids from 0 to maximum
1530
+ const unusedIds = [];
1531
+ if (nextFreeChunkId > 0) {
1532
+ let index = nextFreeChunkId;
1533
+ while (index--) {
1534
+ if (!usedIds.has(index)) {
1535
+ unusedIds.push(index);
1536
+ }
1537
+ }
1538
+ }
1539
+
1540
+ // Assign ids to chunk which has no id
1541
+ for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1542
+ const chunk = chunks[indexChunk];
1543
+ if (chunk.id === null) {
1544
+ if (unusedIds.length > 0) chunk.id = unusedIds.pop();
1545
+ else chunk.id = nextFreeChunkId++;
1546
+ }
1547
+ if (!chunk.ids) {
1548
+ chunk.ids = [chunk.id];
1549
+ }
1550
+ }
1551
+ }
1552
+
1553
+ sortItemsWithModuleIds() {
1554
+ this.modules.sort(byIdOrIdentifier);
1555
+
1556
+ const modules = this.modules;
1557
+ for (let indexModule = 0; indexModule < modules.length; indexModule++) {
1558
+ modules[indexModule].sortItems(false);
1559
+ }
1560
+
1561
+ const chunks = this.chunks;
1562
+ for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1563
+ chunks[indexChunk].sortItems(false);
1564
+ }
1565
+ }
1566
+
1567
+ sortItemsWithChunkIds() {
1568
+ for (const chunkGroup of this.chunkGroups) {
1569
+ chunkGroup.sortItems();
1570
+ }
1571
+
1572
+ this.chunks.sort(byId);
1573
+
1574
+ for (
1575
+ let indexModule = 0;
1576
+ indexModule < this.modules.length;
1577
+ indexModule++
1578
+ ) {
1579
+ this.modules[indexModule].sortItems(true);
1580
+ }
1581
+
1582
+ const chunks = this.chunks;
1583
+ for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1584
+ chunks[indexChunk].sortItems(true);
1585
+ }
1586
+
1587
+ const byMessage = (a, b) => {
1588
+ const ma = `${a.message}`;
1589
+ const mb = `${b.message}`;
1590
+ if (ma < mb) return -1;
1591
+ if (mb < ma) return 1;
1592
+ return 0;
1593
+ };
1594
+
1595
+ this.errors.sort(byMessage);
1596
+ this.warnings.sort(byMessage);
1597
+ }
1598
+
1599
+ summarizeDependencies() {
1600
+ this.fileDependencies = new SortableSet(this.compilationDependencies);
1601
+ this.contextDependencies = new SortableSet();
1602
+ this.missingDependencies = new SortableSet();
1603
+
1604
+ for (
1605
+ let indexChildren = 0;
1606
+ indexChildren < this.children.length;
1607
+ indexChildren++
1608
+ ) {
1609
+ const child = this.children[indexChildren];
1610
+
1611
+ addAllToSet(this.fileDependencies, child.fileDependencies);
1612
+ addAllToSet(this.contextDependencies, child.contextDependencies);
1613
+ addAllToSet(this.missingDependencies, child.missingDependencies);
1614
+ }
1615
+
1616
+ for (
1617
+ let indexModule = 0;
1618
+ indexModule < this.modules.length;
1619
+ indexModule++
1620
+ ) {
1621
+ const module = this.modules[indexModule];
1622
+
1623
+ if (module.buildInfo.fileDependencies) {
1624
+ addAllToSet(this.fileDependencies, module.buildInfo.fileDependencies);
1625
+ }
1626
+ if (module.buildInfo.contextDependencies) {
1627
+ addAllToSet(
1628
+ this.contextDependencies,
1629
+ module.buildInfo.contextDependencies
1630
+ );
1631
+ }
1632
+ }
1633
+ for (const error of this.errors) {
1634
+ if (
1635
+ typeof error.missing === "object" &&
1636
+ error.missing &&
1637
+ error.missing[Symbol.iterator]
1638
+ ) {
1639
+ addAllToSet(this.missingDependencies, error.missing);
1640
+ }
1641
+ }
1642
+ this.fileDependencies.sort();
1643
+ this.contextDependencies.sort();
1644
+ this.missingDependencies.sort();
1645
+ }
1646
+
1647
+ createHash() {
1648
+ const outputOptions = this.outputOptions;
1649
+ const hashFunction = outputOptions.hashFunction;
1650
+ const hashDigest = outputOptions.hashDigest;
1651
+ const hashDigestLength = outputOptions.hashDigestLength;
1652
+ const hash = createHash(hashFunction);
1653
+ if (outputOptions.hashSalt) hash.update(outputOptions.hashSalt);
1654
+ this.mainTemplate.updateHash(hash);
1655
+ this.chunkTemplate.updateHash(hash);
1656
+ for (const key of Object.keys(this.moduleTemplates).sort())
1657
+ this.moduleTemplates[key].updateHash(hash);
1658
+ for (const child of this.children) hash.update(child.hash);
1659
+ for (const warning of this.warnings) hash.update(`${warning.message}`);
1660
+ for (const error of this.errors) hash.update(`${error.message}`);
1661
+ const modules = this.modules;
1662
+ for (let i = 0; i < modules.length; i++) {
1663
+ const module = modules[i];
1664
+ const moduleHash = createHash(hashFunction);
1665
+ module.updateHash(moduleHash);
1666
+ module.hash = moduleHash.digest(hashDigest);
1667
+ module.renderedHash = module.hash.substr(0, hashDigestLength);
1668
+ }
1669
+ // clone needed as sort below is inplace mutation
1670
+ const chunks = this.chunks.slice();
1671
+ /**
1672
+ * sort here will bring all "falsy" values to the beginning
1673
+ * this is needed as the "hasRuntime()" chunks are dependent on the
1674
+ * hashes of the non-runtime chunks.
1675
+ */
1676
+ chunks.sort((a, b) => {
1677
+ const aEntry = a.hasRuntime();
1678
+ const bEntry = b.hasRuntime();
1679
+ if (aEntry && !bEntry) return 1;
1680
+ if (!aEntry && bEntry) return -1;
1681
+ return 0;
1682
+ });
1683
+ for (let i = 0; i < chunks.length; i++) {
1684
+ const chunk = chunks[i];
1685
+ const chunkHash = createHash(hashFunction);
1686
+ if (outputOptions.hashSalt) chunkHash.update(outputOptions.hashSalt);
1687
+ chunk.updateHash(chunkHash);
1688
+ const template = chunk.hasRuntime()
1689
+ ? this.mainTemplate
1690
+ : this.chunkTemplate;
1691
+ template.updateHashForChunk(chunkHash, chunk);
1692
+ this.hooks.chunkHash.call(chunk, chunkHash);
1693
+ chunk.hash = chunkHash.digest(hashDigest);
1694
+ hash.update(chunk.hash);
1695
+ chunk.renderedHash = chunk.hash.substr(0, hashDigestLength);
1696
+ this.hooks.contentHash.call(chunk);
1697
+ }
1698
+ this.fullHash = hash.digest(hashDigest);
1699
+ this.hash = this.fullHash.substr(0, hashDigestLength);
1700
+ }
1701
+
1702
+ modifyHash(update) {
1703
+ const outputOptions = this.outputOptions;
1704
+ const hashFunction = outputOptions.hashFunction;
1705
+ const hashDigest = outputOptions.hashDigest;
1706
+ const hashDigestLength = outputOptions.hashDigestLength;
1707
+ const hash = createHash(hashFunction);
1708
+ hash.update(this.fullHash);
1709
+ hash.update(update);
1710
+ this.fullHash = hash.digest(hashDigest);
1711
+ this.hash = this.fullHash.substr(0, hashDigestLength);
1712
+ }
1713
+
1714
+ createModuleAssets() {
1715
+ for (let i = 0; i < this.modules.length; i++) {
1716
+ const module = this.modules[i];
1717
+ if (module.buildInfo.assets) {
1718
+ for (const assetName of Object.keys(module.buildInfo.assets)) {
1719
+ const fileName = this.getPath(assetName);
1720
+ this.assets[fileName] = module.buildInfo.assets[assetName];
1721
+ this.hooks.moduleAsset.call(module, fileName);
1722
+ }
1723
+ }
1724
+ }
1725
+ }
1726
+
1727
+ createChunkAssets() {
1728
+ const outputOptions = this.outputOptions;
1729
+ const cachedSourceMap = new Map();
1730
+ for (let i = 0; i < this.chunks.length; i++) {
1731
+ const chunk = this.chunks[i];
1732
+ chunk.files = [];
1733
+ let source;
1734
+ let file;
1735
+ let filenameTemplate;
1736
+ try {
1737
+ const template = chunk.hasRuntime()
1738
+ ? this.mainTemplate
1739
+ : this.chunkTemplate;
1740
+ const manifest = template.getRenderManifest({
1741
+ chunk,
1742
+ hash: this.hash,
1743
+ fullHash: this.fullHash,
1744
+ outputOptions,
1745
+ moduleTemplates: this.moduleTemplates,
1746
+ dependencyTemplates: this.dependencyTemplates
1747
+ }); // [{ render(), filenameTemplate, pathOptions, identifier, hash }]
1748
+ for (const fileManifest of manifest) {
1749
+ const cacheName = fileManifest.identifier;
1750
+ const usedHash = fileManifest.hash;
1751
+ filenameTemplate = fileManifest.filenameTemplate;
1752
+ if (
1753
+ this.cache &&
1754
+ this.cache[cacheName] &&
1755
+ this.cache[cacheName].hash === usedHash
1756
+ ) {
1757
+ source = this.cache[cacheName].source;
1758
+ } else {
1759
+ source = fileManifest.render();
1760
+ // Ensure that source is a cached source to avoid additional cost because of repeated access
1761
+ if (!(source instanceof CachedSource)) {
1762
+ const cacheEntry = cachedSourceMap.get(source);
1763
+ if (cacheEntry) {
1764
+ source = cacheEntry;
1765
+ } else {
1766
+ const cachedSource = new CachedSource(source);
1767
+ cachedSourceMap.set(source, cachedSource);
1768
+ source = cachedSource;
1769
+ }
1770
+ }
1771
+ if (this.cache) {
1772
+ this.cache[cacheName] = {
1773
+ hash: usedHash,
1774
+ source
1775
+ };
1776
+ }
1777
+ }
1778
+ file = this.getPath(filenameTemplate, fileManifest.pathOptions);
1779
+ if (this.assets[file] && this.assets[file] !== source)
1780
+ throw new Error(
1781
+ `Conflict: Multiple assets emit to the same filename ${file}`
1782
+ );
1783
+ this.assets[file] = source;
1784
+ chunk.files.push(file);
1785
+ this.hooks.chunkAsset.call(chunk, file);
1786
+ }
1787
+ } catch (err) {
1788
+ this.errors.push(
1789
+ new ChunkRenderError(chunk, file || filenameTemplate, err)
1790
+ );
1791
+ }
1792
+ }
1793
+ }
1794
+
1795
+ getPath(filename, data) {
1796
+ data = data || {};
1797
+ data.hash = data.hash || this.hash;
1798
+ return this.mainTemplate.getAssetPath(filename, data);
1799
+ }
1800
+
1801
+ createChildCompiler(name, outputOptions, plugins) {
1802
+ const idx = this.childrenCounters[name] || 0;
1803
+ this.childrenCounters[name] = idx + 1;
1804
+ return this.compiler.createChildCompiler(
1805
+ this,
1806
+ name,
1807
+ idx,
1808
+ outputOptions,
1809
+ plugins
1810
+ );
1811
+ }
1812
+
1813
+ checkConstraints() {
1814
+ const usedIds = new Set();
1815
+
1816
+ const modules = this.modules;
1817
+ for (let indexModule = 0; indexModule < modules.length; indexModule++) {
1818
+ const moduleId = modules[indexModule].id;
1819
+ if (moduleId === null) continue;
1820
+ if (usedIds.has(moduleId))
1821
+ throw new Error(`checkConstraints: duplicate module id ${moduleId}`);
1822
+ usedIds.add(moduleId);
1823
+ }
1824
+
1825
+ const chunks = this.chunks;
1826
+ for (let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1827
+ const chunk = chunks[indexChunk];
1828
+ if (chunks.indexOf(chunk) !== indexChunk)
1829
+ throw new Error(
1830
+ `checkConstraints: duplicate chunk in compilation ${chunk.debugId}`
1831
+ );
1832
+ }
1833
+
1834
+ for (const chunkGroup of this.chunkGroups) {
1835
+ chunkGroup.checkConstraints();
1836
+ }
1837
+ }
1838
+ }
1839
+
1840
+ // TODO remove in webpack 5
1841
+ Compilation.prototype.applyPlugins = util.deprecate(function(name, ...args) {
1842
+ this.hooks[
1843
+ name.replace(/[- ]([a-z])/g, match => match[1].toUpperCase())
1844
+ ].call(...args);
1845
+ }, "Compilation.applyPlugins is deprecated. Use new API on `.hooks` instead");
1846
+
1847
+ // TODO remove in webpack 5
1848
+ Object.defineProperty(Compilation.prototype, "moduleTemplate", {
1849
+ configurable: false,
1850
+ get: util.deprecate(function() {
1851
+ return this.moduleTemplates.javascript;
1852
+ }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead"),
1853
+ set: util.deprecate(function(value) {
1854
+ this.moduleTemplates.javascript = value;
1855
+ }, "Compilation.moduleTemplate: Use Compilation.moduleTemplates.javascript instead.")
1856
+ });
1857
+
1858
+ module.exports = Compilation;