webpack 3.6.0 → 3.8.1

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 (229) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +716 -716
  3. package/bin/convert-argv.js +1 -1
  4. package/bin/webpack.js +6 -0
  5. package/buildin/.eslintrc +7 -7
  6. package/buildin/amd-define.js +3 -3
  7. package/buildin/amd-options.js +2 -2
  8. package/buildin/global.js +21 -21
  9. package/buildin/harmony-module.js +24 -24
  10. package/buildin/module.js +22 -22
  11. package/buildin/system.js +7 -7
  12. package/hot/.eslintrc +9 -9
  13. package/hot/dev-server.js +53 -53
  14. package/hot/emitter.js +2 -2
  15. package/hot/log-apply-result.js +38 -38
  16. package/hot/log.js +44 -44
  17. package/hot/only-dev-server.js +71 -71
  18. package/hot/poll.js +34 -34
  19. package/hot/signal.js +51 -51
  20. package/lib/APIPlugin.js +45 -45
  21. package/lib/AsyncDependenciesBlock.js +43 -43
  22. package/lib/AsyncDependencyToInitialChunkWarning.js +21 -0
  23. package/lib/AutomaticPrefetchPlugin.js +36 -36
  24. package/lib/BasicEvaluatedExpression.js +203 -203
  25. package/lib/CaseSensitiveModulesWarning.js +49 -49
  26. package/lib/Chunk.js +3 -0
  27. package/lib/ChunkRenderError.js +24 -24
  28. package/lib/ChunkTemplate.js +36 -36
  29. package/lib/CompatibilityPlugin.js +57 -57
  30. package/lib/Compilation.js +158 -51
  31. package/lib/Compiler.js +523 -523
  32. package/lib/ConstPlugin.js +60 -60
  33. package/lib/ContextExclusionPlugin.js +17 -0
  34. package/lib/ContextModule.js +431 -431
  35. package/lib/ContextModuleFactory.js +14 -5
  36. package/lib/ContextReplacementPlugin.js +111 -111
  37. package/lib/DefinePlugin.js +123 -123
  38. package/lib/DelegatedModule.js +98 -92
  39. package/lib/DelegatedModuleFactoryPlugin.js +59 -59
  40. package/lib/DelegatedPlugin.js +30 -30
  41. package/lib/DependenciesBlockVariable.js +51 -51
  42. package/lib/DllEntryPlugin.js +37 -37
  43. package/lib/DllModule.js +58 -58
  44. package/lib/DllModuleFactory.js +20 -20
  45. package/lib/DllPlugin.js +38 -38
  46. package/lib/DllReferencePlugin.js +62 -62
  47. package/lib/DynamicEntryPlugin.js +59 -59
  48. package/lib/EntryModuleNotFoundError.js +22 -22
  49. package/lib/EntryOptionPlugin.js +31 -31
  50. package/lib/EnvironmentPlugin.js +50 -50
  51. package/lib/ErrorHelpers.js +31 -31
  52. package/lib/EvalDevToolModulePlugin.js +22 -22
  53. package/lib/EvalDevToolModuleTemplatePlugin.js +33 -33
  54. package/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +75 -75
  55. package/lib/EvalSourceMapDevToolPlugin.js +32 -32
  56. package/lib/ExportPropertyMainTemplatePlugin.js +31 -31
  57. package/lib/ExtendedAPIPlugin.js +47 -47
  58. package/lib/ExternalModule.js +7 -0
  59. package/lib/ExternalModuleFactoryPlugin.js +91 -91
  60. package/lib/ExternalsPlugin.js +21 -21
  61. package/lib/FlagDependencyExportsPlugin.js +101 -101
  62. package/lib/FunctionModulePlugin.js +24 -24
  63. package/lib/FunctionModuleTemplatePlugin.js +7 -3
  64. package/lib/HashedModuleIdsPlugin.js +42 -42
  65. package/lib/HotUpdateChunkTemplate.js +31 -31
  66. package/lib/IgnorePlugin.js +69 -69
  67. package/lib/JsonpExportMainTemplatePlugin.js +37 -37
  68. package/lib/JsonpHotUpdateChunkTemplatePlugin.js +27 -27
  69. package/lib/JsonpMainTemplate.runtime.js +2 -1
  70. package/lib/JsonpMainTemplatePlugin.js +2 -0
  71. package/lib/JsonpTemplatePlugin.js +21 -21
  72. package/lib/LibManifestPlugin.js +63 -63
  73. package/lib/LibraryTemplatePlugin.js +92 -92
  74. package/lib/LoaderOptionsPlugin.js +36 -36
  75. package/lib/LoaderTargetPlugin.js +19 -19
  76. package/lib/MemoryOutputFileSystem.js +5 -5
  77. package/lib/ModuleBuildError.js +42 -42
  78. package/lib/ModuleDependencyError.js +22 -22
  79. package/lib/ModuleDependencyWarning.js +22 -22
  80. package/lib/ModuleError.js +24 -24
  81. package/lib/ModuleFilenameHelpers.js +162 -162
  82. package/lib/ModuleNotFoundError.js +26 -26
  83. package/lib/ModuleParseError.js +1 -1
  84. package/lib/ModuleReason.js +50 -50
  85. package/lib/ModuleTemplate.js +23 -23
  86. package/lib/ModuleWarning.js +24 -24
  87. package/lib/MovedToPluginWarningPlugin.js +21 -21
  88. package/lib/MultiCompiler.js +164 -164
  89. package/lib/MultiEntryPlugin.js +39 -39
  90. package/lib/MultiModuleFactory.js +19 -19
  91. package/lib/MultiStats.js +79 -79
  92. package/lib/MultiWatching.js +32 -32
  93. package/lib/NamedChunksPlugin.js +30 -30
  94. package/lib/NamedModulesPlugin.js +27 -27
  95. package/lib/NewWatchingPlugin.js +15 -15
  96. package/lib/NoEmitOnErrorsPlugin.js +22 -22
  97. package/lib/NoErrorsPlugin.js +29 -29
  98. package/lib/NodeStuffPlugin.js +97 -97
  99. package/lib/NormalModuleReplacementPlugin.js +45 -45
  100. package/lib/NullFactory.js +12 -12
  101. package/lib/OptionsApply.js +10 -10
  102. package/lib/Parser.js +65 -34
  103. package/lib/ParserHelpers.js +85 -85
  104. package/lib/PrefetchPlugin.js +31 -31
  105. package/lib/ProgressPlugin.js +192 -192
  106. package/lib/ProvidePlugin.js +55 -55
  107. package/lib/RawModule.js +54 -54
  108. package/lib/RequestShortener.js +63 -63
  109. package/lib/RequireJsStuffPlugin.js +31 -31
  110. package/lib/RuleSet.js +444 -444
  111. package/lib/SetVarMainTemplatePlugin.js +41 -41
  112. package/lib/SingleEntryPlugin.js +35 -35
  113. package/lib/SizeFormatHelpers.js +18 -18
  114. package/lib/SourceMapDevToolModuleOptionsPlugin.js +37 -37
  115. package/lib/Stats.js +27 -8
  116. package/lib/UmdMainTemplatePlugin.js +1 -1
  117. package/lib/UnsupportedFeatureWarning.js +21 -21
  118. package/lib/UseStrictPlugin.js +34 -34
  119. package/lib/WarnCaseSensitiveModulesPlugin.js +31 -31
  120. package/lib/WatchIgnorePlugin.js +49 -49
  121. package/lib/WebpackError.js +11 -11
  122. package/lib/WebpackOptionsDefaulter.js +129 -129
  123. package/lib/WebpackOptionsValidationError.js +196 -196
  124. package/lib/compareLocations.js +36 -36
  125. package/lib/dependencies/AMDDefineDependency.js +142 -142
  126. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +5 -1
  127. package/lib/dependencies/AMDPlugin.js +119 -119
  128. package/lib/dependencies/AMDRequireArrayDependency.js +2 -0
  129. package/lib/dependencies/AMDRequireContextDependency.js +0 -9
  130. package/lib/dependencies/AMDRequireDependenciesBlock.js +33 -33
  131. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +177 -177
  132. package/lib/dependencies/AMDRequireDependency.js +67 -67
  133. package/lib/dependencies/AMDRequireItemDependency.js +22 -22
  134. package/lib/dependencies/CommonJsRequireContextDependency.js +0 -10
  135. package/lib/dependencies/CommonJsRequireDependency.js +22 -22
  136. package/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +89 -89
  137. package/lib/dependencies/ConstDependency.js +32 -32
  138. package/lib/dependencies/ContextDependency.js +20 -0
  139. package/lib/dependencies/ContextDependencyHelpers.js +71 -71
  140. package/lib/dependencies/ContextElementDependency.js +21 -21
  141. package/lib/dependencies/CriticalDependencyWarning.js +20 -20
  142. package/lib/dependencies/DelegatedExportsDependency.js +33 -33
  143. package/lib/dependencies/DelegatedSourceDependency.js +18 -18
  144. package/lib/dependencies/DllEntryDependency.js +20 -20
  145. package/lib/dependencies/HarmonyCompatibilityDependency.js +30 -30
  146. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +14 -2
  147. package/lib/dependencies/HarmonyExportExpressionDependency.js +0 -7
  148. package/lib/dependencies/HarmonyExportHeaderDependency.js +28 -28
  149. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +45 -45
  150. package/lib/dependencies/HarmonyExportSpecifierDependency.js +0 -13
  151. package/lib/dependencies/HarmonyModulesHelpers.js +0 -53
  152. package/lib/dependencies/ImportContextDependency.js +0 -10
  153. package/lib/dependencies/ImportDependenciesBlock.js +17 -17
  154. package/lib/dependencies/ImportEagerContextDependency.js +22 -22
  155. package/lib/dependencies/ImportLazyContextDependency.js +22 -22
  156. package/lib/dependencies/ImportLazyOnceContextDependency.js +22 -22
  157. package/lib/dependencies/ImportParserPlugin.js +89 -89
  158. package/lib/dependencies/ImportPlugin.js +60 -60
  159. package/lib/dependencies/ImportWeakContextDependency.js +22 -22
  160. package/lib/dependencies/LoaderDependency.js +18 -18
  161. package/lib/dependencies/LoaderPlugin.js +60 -60
  162. package/lib/dependencies/LocalModule.js +23 -23
  163. package/lib/dependencies/LocalModuleDependency.js +24 -24
  164. package/lib/dependencies/LocalModulesHelpers.js +46 -46
  165. package/lib/dependencies/ModuleDependency.js +23 -23
  166. package/lib/dependencies/ModuleHotAcceptDependency.js +23 -23
  167. package/lib/dependencies/ModuleHotDeclineDependency.js +23 -23
  168. package/lib/dependencies/MultiEntryDependency.js +20 -20
  169. package/lib/dependencies/NullDependency.js +24 -24
  170. package/lib/dependencies/PrefetchDependency.js +18 -18
  171. package/lib/dependencies/RequireContextDependency.js +26 -26
  172. package/lib/dependencies/RequireContextDependencyParserPlugin.js +50 -50
  173. package/lib/dependencies/RequireContextPlugin.js +96 -96
  174. package/lib/dependencies/RequireEnsureDependenciesBlock.js +22 -22
  175. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +102 -102
  176. package/lib/dependencies/RequireEnsureDependency.js +38 -38
  177. package/lib/dependencies/RequireEnsureItemDependency.js +21 -21
  178. package/lib/dependencies/RequireEnsurePlugin.js +40 -40
  179. package/lib/dependencies/RequireHeaderDependency.js +26 -26
  180. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +21 -21
  181. package/lib/dependencies/RequireIncludePlugin.js +33 -33
  182. package/lib/dependencies/RequireResolveContextDependency.js +0 -10
  183. package/lib/dependencies/RequireResolveDependency.js +22 -22
  184. package/lib/dependencies/RequireResolveDependencyParserPlugin.js +71 -71
  185. package/lib/dependencies/RequireResolveHeaderDependency.js +26 -26
  186. package/lib/dependencies/SingleEntryDependency.js +18 -18
  187. package/lib/dependencies/SystemPlugin.js +44 -44
  188. package/lib/dependencies/UnsupportedDependency.js +23 -23
  189. package/lib/dependencies/WebpackMissingModule.js +18 -18
  190. package/lib/dependencies/getFunctionExpression.js +44 -44
  191. package/lib/formatLocation.js +54 -54
  192. package/lib/node/NodeChunkTemplatePlugin.js +27 -27
  193. package/lib/node/NodeEnvironmentPlugin.js +25 -25
  194. package/lib/node/NodeHotUpdateChunkTemplatePlugin.js +27 -27
  195. package/lib/node/NodeMainTemplate.runtime.js +24 -24
  196. package/lib/node/NodeMainTemplateAsync.runtime.js +40 -40
  197. package/lib/node/NodeOutputFileSystem.js +22 -22
  198. package/lib/node/NodeSourcePlugin.js +88 -88
  199. package/lib/node/NodeTargetPlugin.js +15 -15
  200. package/lib/node/NodeTemplatePlugin.js +27 -27
  201. package/lib/node/NodeWatchFileSystem.js +72 -72
  202. package/lib/optimize/ChunkModuleIdRangePlugin.js +53 -53
  203. package/lib/optimize/CommonsChunkPlugin.js +40 -19
  204. package/lib/optimize/ConcatenatedModule.js +27 -24
  205. package/lib/optimize/DedupePlugin.js +15 -15
  206. package/lib/optimize/FlagIncludedChunksPlugin.js +35 -35
  207. package/lib/optimize/LimitChunkCountPlugin.js +59 -59
  208. package/lib/optimize/MinChunkSizePlugin.js +65 -65
  209. package/lib/optimize/RemoveEmptyChunksPlugin.js +21 -21
  210. package/lib/optimize/UglifyJsPlugin.js +9 -9
  211. package/lib/performance/AssetsOverSizeLimitWarning.js +23 -23
  212. package/lib/performance/EntrypointsOverSizeLimitWarning.js +28 -28
  213. package/lib/performance/NoAsyncChunksWarning.js +20 -20
  214. package/lib/performance/SizeLimitsPlugin.js +102 -102
  215. package/lib/prepareOptions.js +29 -29
  216. package/lib/removeAndDo.js +15 -15
  217. package/lib/util/Queue.js +42 -0
  218. package/lib/util/Semaphore.js +32 -32
  219. package/lib/util/identifier.js +38 -38
  220. package/lib/validateSchema.js +66 -66
  221. package/lib/web/WebEnvironmentPlugin.js +18 -18
  222. package/lib/webpack.js +1 -0
  223. package/lib/webworker/WebWorkerChunkTemplatePlugin.js +29 -29
  224. package/lib/webworker/WebWorkerHotUpdateChunkTemplatePlugin.js +28 -28
  225. package/lib/webworker/WebWorkerMainTemplate.runtime.js +58 -58
  226. package/lib/webworker/WebWorkerTemplatePlugin.js +20 -20
  227. package/package.json +1 -1
  228. package/schemas/ajv.absolutePath.js +29 -29
  229. package/schemas/webpackOptionsSchema.json +69 -0
@@ -1,57 +1,57 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- */
5
- "use strict";
6
-
7
- const ConstDependency = require("./dependencies/ConstDependency");
8
-
9
- const NullFactory = require("./NullFactory");
10
-
11
- const jsonLoaderPath = require.resolve("json-loader");
12
- const matchJson = /\.json$/i;
13
-
14
- class CompatibilityPlugin {
15
-
16
- apply(compiler) {
17
- compiler.plugin("compilation", (compilation, params) => {
18
- compilation.dependencyFactories.set(ConstDependency, new NullFactory());
19
- compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template());
20
-
21
- params.normalModuleFactory.plugin("parser", (parser, parserOptions) => {
22
-
23
- if(typeof parserOptions.browserify !== "undefined" && !parserOptions.browserify)
24
- return;
25
-
26
- parser.plugin("call require", (expr) => {
27
- // support for browserify style require delegator: "require(o, !0)"
28
- if(expr.arguments.length !== 2) return;
29
- const second = parser.evaluateExpression(expr.arguments[1]);
30
- if(!second.isBoolean()) return;
31
- if(second.asBool() !== true) return;
32
- const dep = new ConstDependency("require", expr.callee.range);
33
- dep.loc = expr.loc;
34
- if(parser.state.current.dependencies.length > 1) {
35
- const last = parser.state.current.dependencies[parser.state.current.dependencies.length - 1];
36
- if(last.critical && last.request === "." && last.userRequest === "." && last.recursive)
37
- parser.state.current.dependencies.pop();
38
- }
39
- parser.state.current.addDependency(dep);
40
- return true;
41
- });
42
- });
43
-
44
- params.normalModuleFactory.plugin("after-resolve", (data, done) => {
45
- // if this is a json file and there are no loaders active, we use the json-loader in order to avoid parse errors
46
- // @see https://github.com/webpack/webpack/issues/3363
47
- if(matchJson.test(data.request) && data.loaders.length === 0) {
48
- data.loaders.push({
49
- loader: jsonLoaderPath
50
- });
51
- }
52
- done(null, data);
53
- });
54
- });
55
- }
56
- }
57
- module.exports = CompatibilityPlugin;
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ "use strict";
6
+
7
+ const ConstDependency = require("./dependencies/ConstDependency");
8
+
9
+ const NullFactory = require("./NullFactory");
10
+
11
+ const jsonLoaderPath = require.resolve("json-loader");
12
+ const matchJson = /\.json$/i;
13
+
14
+ class CompatibilityPlugin {
15
+
16
+ apply(compiler) {
17
+ compiler.plugin("compilation", (compilation, params) => {
18
+ compilation.dependencyFactories.set(ConstDependency, new NullFactory());
19
+ compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template());
20
+
21
+ params.normalModuleFactory.plugin("parser", (parser, parserOptions) => {
22
+
23
+ if(typeof parserOptions.browserify !== "undefined" && !parserOptions.browserify)
24
+ return;
25
+
26
+ parser.plugin("call require", (expr) => {
27
+ // support for browserify style require delegator: "require(o, !0)"
28
+ if(expr.arguments.length !== 2) return;
29
+ const second = parser.evaluateExpression(expr.arguments[1]);
30
+ if(!second.isBoolean()) return;
31
+ if(second.asBool() !== true) return;
32
+ const dep = new ConstDependency("require", expr.callee.range);
33
+ dep.loc = expr.loc;
34
+ if(parser.state.current.dependencies.length > 1) {
35
+ const last = parser.state.current.dependencies[parser.state.current.dependencies.length - 1];
36
+ if(last.critical && last.request === "." && last.userRequest === "." && last.recursive)
37
+ parser.state.current.dependencies.pop();
38
+ }
39
+ parser.state.current.addDependency(dep);
40
+ return true;
41
+ });
42
+ });
43
+
44
+ params.normalModuleFactory.plugin("after-resolve", (data, done) => {
45
+ // if this is a json file and there are no loaders active, we use the json-loader in order to avoid parse errors
46
+ // @see https://github.com/webpack/webpack/issues/3363
47
+ if(matchJson.test(data.request) && data.loaders.length === 0) {
48
+ data.loaders.push({
49
+ loader: jsonLoaderPath
50
+ });
51
+ }
52
+ done(null, data);
53
+ });
54
+ });
55
+ }
56
+ }
57
+ module.exports = CompatibilityPlugin;
@@ -20,9 +20,11 @@ const HotUpdateChunkTemplate = require("./HotUpdateChunkTemplate");
20
20
  const ModuleTemplate = require("./ModuleTemplate");
21
21
  const Dependency = require("./Dependency");
22
22
  const ChunkRenderError = require("./ChunkRenderError");
23
+ const AsyncDependencyToInitialChunkWarning = require("./AsyncDependencyToInitialChunkWarning");
23
24
  const CachedSource = require("webpack-sources").CachedSource;
24
25
  const Stats = require("./Stats");
25
26
  const Semaphore = require("./util/Semaphore");
27
+ const Queue = require("./util/Queue");
26
28
 
27
29
  function byId(a, b) {
28
30
  if(a.id < b.id) return -1;
@@ -232,7 +234,10 @@ class Compilation extends Tapable {
232
234
  callback();
233
235
  };
234
236
 
235
- _this.semaphore.acquire(() => {
237
+ const semaphore = _this.semaphore;
238
+ semaphore.acquire(() => {
239
+ if(_this === null) return semaphore.release();
240
+
236
241
  const factory = item[0];
237
242
  factory.create({
238
243
  contextInfo: {
@@ -242,6 +247,8 @@ class Compilation extends Tapable {
242
247
  context: module.context,
243
248
  dependencies: dependencies
244
249
  }, function factoryCallback(err, dependentModule) {
250
+ if(_this === null) return semaphore.release();
251
+
245
252
  let afterFactory;
246
253
 
247
254
  function isOptional() {
@@ -265,11 +272,11 @@ class Compilation extends Tapable {
265
272
  }
266
273
 
267
274
  if(err) {
268
- _this.semaphore.release();
275
+ semaphore.release();
269
276
  return errorOrWarningAndCallback(new ModuleNotFoundError(module, err, dependencies));
270
277
  }
271
278
  if(!dependentModule) {
272
- _this.semaphore.release();
279
+ semaphore.release();
273
280
  return process.nextTick(callback);
274
281
  }
275
282
  if(_this.profile) {
@@ -302,7 +309,7 @@ class Compilation extends Tapable {
302
309
  }
303
310
  }
304
311
 
305
- _this.semaphore.release();
312
+ semaphore.release();
306
313
  return process.nextTick(callback);
307
314
  }
308
315
 
@@ -322,7 +329,7 @@ class Compilation extends Tapable {
322
329
  module.profile.building = afterBuilding - afterFactory;
323
330
  }
324
331
 
325
- _this.semaphore.release();
332
+ semaphore.release();
326
333
  if(recursive) {
327
334
  return process.nextTick(_this.processModuleDependencies.bind(_this, dependentModule, callback));
328
335
  } else {
@@ -335,8 +342,10 @@ class Compilation extends Tapable {
335
342
  iterationDependencies(dependencies);
336
343
 
337
344
  _this.buildModule(dependentModule, isOptional(), module, dependencies, err => {
345
+ if(_this === null) return semaphore.release();
346
+
338
347
  if(err) {
339
- _this.semaphore.release();
348
+ semaphore.release();
340
349
  return errorOrWarningAndCallback(err);
341
350
  }
342
351
 
@@ -345,7 +354,7 @@ class Compilation extends Tapable {
345
354
  dependentModule.profile.building = afterBuilding - afterFactory;
346
355
  }
347
356
 
348
- _this.semaphore.release();
357
+ semaphore.release();
349
358
  if(recursive) {
350
359
  _this.processModuleDependencies(dependentModule, callback);
351
360
  } else {
@@ -578,8 +587,8 @@ class Compilation extends Tapable {
578
587
  chunk.entryModule = module;
579
588
  self.assignIndex(module);
580
589
  self.assignDepth(module);
581
- self.processDependenciesBlockForChunk(module, chunk);
582
590
  });
591
+ self.processDependenciesBlocksForChunks(self.chunks.slice());
583
592
  self.sortModules(self.modules);
584
593
  self.applyPlugins0("optimize");
585
594
 
@@ -846,62 +855,97 @@ class Compilation extends Tapable {
846
855
  }
847
856
  }
848
857
 
849
- processDependenciesBlockForChunk(module, chunk) {
850
- let block = module;
851
- const initialChunk = chunk;
858
+ // This method creates the Chunk graph from the Module graph
859
+ processDependenciesBlocksForChunks(inputChunks) {
860
+ // Process is splitting into two parts:
861
+ // Part one traverse the module graph and builds a very basic chunks graph
862
+ // in chunkDependencies.
863
+ // Part two traverse every possible way through the basic chunk graph and
864
+ // tracks the available modules. While traversing it connects chunks with
865
+ // eachother and Blocks with Chunks. It stops traversing when all modules
866
+ // for a chunk are already available. So it doesn't connect unneeded chunks.
867
+
852
868
  const chunkDependencies = new Map(); // Map<Chunk, Array<{Module, Chunk}>>
869
+ const allCreatedChunks = new Set();
870
+
871
+ // PART ONE
872
+
873
+ const blockChunks = new Map();
853
874
 
875
+ // Start with the provided modules/chunks
876
+ const queue = inputChunks.map(chunk => ({
877
+ block: chunk.entryModule,
878
+ chunk: chunk
879
+ }));
880
+
881
+ let block, chunk;
882
+
883
+ // For each async Block in graph
854
884
  const iteratorBlock = b => {
855
- let c;
856
- if(!b.chunks) {
857
- c = this.addChunk(b.chunkName, b.module, b.loc);
858
- b.chunks = [c];
859
- c.addBlock(b);
860
- } else {
861
- c = b.chunks[0];
885
+ // 1. We create a chunk for this Block
886
+ // but only once (blockChunks map)
887
+ let c = blockChunks.get(b);
888
+ if(c === undefined) {
889
+ c = this.namedChunks[b.chunkName];
890
+ if(c && c.isInitial()) {
891
+ // TODO webpack 4: convert this to an error
892
+ this.warnings.push(new AsyncDependencyToInitialChunkWarning(b.chunkName, b.module, b.loc));
893
+ c = chunk;
894
+ } else {
895
+ c = this.addChunk(b.chunkName, b.module, b.loc);
896
+ blockChunks.set(b, c);
897
+ allCreatedChunks.add(c);
898
+ // We initialize the chunks property
899
+ // this is later filled with the chunk when needed
900
+ b.chunks = [];
901
+ }
862
902
  }
903
+
904
+ // 2. We store the Block+Chunk mapping as dependency for the chunk
863
905
  let deps = chunkDependencies.get(chunk);
864
906
  if(!deps) chunkDependencies.set(chunk, deps = []);
865
907
  deps.push({
866
- chunk: c,
867
- module
908
+ block: b,
909
+ chunk: c
868
910
  });
911
+
912
+ // 3. We enqueue the DependenciesBlock for traversal
869
913
  queue.push({
870
914
  block: b,
871
- module: null,
872
915
  chunk: c
873
916
  });
874
917
  };
875
918
 
919
+ // For each Dependency in the graph
876
920
  const iteratorDependency = d => {
921
+ // We skip Dependencies without Module pointer
877
922
  if(!d.module) {
878
923
  return;
879
924
  }
925
+ // We skip weak Dependencies
880
926
  if(d.weak) {
881
927
  return;
882
928
  }
929
+ // We connect Module and Chunk when not already done
883
930
  if(chunk.addModule(d.module)) {
884
931
  d.module.addChunk(chunk);
932
+
933
+ // And enqueue the Module for traversal
885
934
  queue.push({
886
935
  block: d.module,
887
- module: d.module,
888
936
  chunk
889
937
  });
890
938
  }
891
939
  };
892
940
 
893
- const queue = [{
894
- block,
895
- module,
896
- chunk
897
- }];
898
-
941
+ // Iterative traversal of the Module graph
942
+ // Recursive would be simpler to write but could result in Stack Overflows
899
943
  while(queue.length) {
900
944
  const queueItem = queue.pop();
901
945
  block = queueItem.block;
902
- module = queueItem.module;
903
946
  chunk = queueItem.chunk;
904
947
 
948
+ // Traverse all variables, Dependencies and Blocks
905
949
  if(block.variables) {
906
950
  iterationBlockVariable(block.variables, iteratorDependency);
907
951
  }
@@ -915,46 +959,109 @@ class Compilation extends Tapable {
915
959
  }
916
960
  }
917
961
 
918
- chunk = initialChunk;
919
- let chunks = new Set();
920
- const queue2 = [{
962
+ // PART TWO
963
+
964
+ let availableModules;
965
+ let newAvailableModules;
966
+ const queue2 = new Queue(inputChunks.map(chunk => ({
921
967
  chunk,
922
- chunks
923
- }];
968
+ availableModules: new Set()
969
+ })));
924
970
 
925
- const filterFn = dep => {
926
- if(chunks.has(dep.chunk)) return false;
927
- for(const chunk of chunks) {
928
- if(chunk.containsModule(dep.module))
971
+ // Helper function to check if all modules of a chunk are available
972
+ const areModulesAvailable = (chunk, availableModules) => {
973
+ for(const module of chunk.modulesIterable) {
974
+ if(!availableModules.has(module))
929
975
  return false;
930
976
  }
931
977
  return true;
932
978
  };
933
979
 
980
+ // For each edge in the basic chunk graph
981
+ const filterFn = dep => {
982
+ // Filter egdes that are not needed because all modules are already available
983
+ // This also filters circular dependencies in the chunks graph
984
+ const depChunk = dep.chunk;
985
+ if(areModulesAvailable(depChunk, newAvailableModules))
986
+ return false; // break all modules are already available
987
+ return true;
988
+ };
989
+
990
+ const minAvailableModulesMap = new Map();
991
+
992
+ // Iterative traversing of the basic chunk graph
934
993
  while(queue2.length) {
935
- const queueItem = queue2.pop();
994
+ const queueItem = queue2.dequeue();
936
995
  chunk = queueItem.chunk;
937
- chunks = queueItem.chunks;
996
+ availableModules = queueItem.availableModules;
997
+
998
+ // 1. Get minimal available modules
999
+ // It doesn't make sense to traverse a chunk again with more available modules.
1000
+ // This step calculates the minimal available modules and skips traversal when
1001
+ // the list didn't shrink.
1002
+ let minAvailableModules = minAvailableModulesMap.get(chunk);
1003
+ if(minAvailableModules === undefined) {
1004
+ minAvailableModulesMap.set(chunk, new Set(availableModules));
1005
+ } else {
1006
+ let deletedModules = false;
1007
+ for(const m of minAvailableModules) {
1008
+ if(!availableModules.has(m)) {
1009
+ minAvailableModules.delete(m);
1010
+ deletedModules = true;
1011
+ }
1012
+ }
1013
+ if(!deletedModules)
1014
+ continue;
1015
+ availableModules = minAvailableModules;
1016
+ }
938
1017
 
1018
+ // 2. Get the edges at this point of the graph
939
1019
  const deps = chunkDependencies.get(chunk);
940
1020
  if(!deps) continue;
1021
+ if(deps.length === 0) continue;
941
1022
 
942
- const depsFiltered = deps.filter(filterFn);
1023
+ // 3. Create a new Set of available modules at this points
1024
+ newAvailableModules = new Set(availableModules);
1025
+ for(const m of chunk.modulesIterable)
1026
+ newAvailableModules.add(m);
943
1027
 
944
- for(let i = 0; i < depsFiltered.length; i++) {
945
- const dep = depsFiltered[i];
1028
+ // 4. Filter edges with available modules
1029
+ const filteredDeps = deps.filter(filterFn);
1030
+
1031
+ // 5. Foreach remaining edge
1032
+ const nextChunks = new Set();
1033
+ for(let i = 0; i < filteredDeps.length; i++) {
1034
+ const dep = filteredDeps[i];
946
1035
  const depChunk = dep.chunk;
947
- chunk.addChunk(depChunk);
948
- depChunk.addParent(chunk);
949
-
950
- const newChunks = depsFiltered.length > 1 ? new Set(chunks) : chunks;
951
- newChunks.add(chunk);
952
- queue2.push({
953
- chunk: depChunk,
954
- chunks: newChunks
1036
+ const depBlock = dep.block;
1037
+
1038
+ // 6. Connnect block with chunk
1039
+ if(depChunk.addBlock(depBlock)) {
1040
+ depBlock.chunks.push(depChunk);
1041
+ }
1042
+
1043
+ // 7. Connect chunk with parent
1044
+ if(chunk.addChunk(depChunk)) {
1045
+ depChunk.addParent(chunk);
1046
+ }
1047
+
1048
+ nextChunks.add(depChunk);
1049
+ }
1050
+
1051
+ // 8. Enqueue further traversal
1052
+ for(const nextChunk of nextChunks) {
1053
+ queue2.enqueue({
1054
+ chunk: nextChunk,
1055
+ availableModules: newAvailableModules
955
1056
  });
956
1057
  }
957
1058
  }
1059
+
1060
+ // Remove all unconnected chunks
1061
+ for(const chunk of allCreatedChunks) {
1062
+ if(chunk.parents.length === 0)
1063
+ chunk.remove("unconnected");
1064
+ }
958
1065
  }
959
1066
 
960
1067
  removeChunkFromDependencies(block, chunk) {