webpack 4.9.1 → 4.10.2

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