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,457 +1,470 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- */
5
- "use strict";
6
-
7
- const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
8
- const ModuleHotAcceptDependency = require("../dependencies/ModuleHotAcceptDependency");
9
- const ModuleHotDeclineDependency = require("../dependencies/ModuleHotDeclineDependency");
10
- const ConcatenatedModule = require("./ConcatenatedModule");
11
- const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
12
- const StackedSetMap = require("../util/StackedSetMap");
13
-
14
- const formatBailoutReason = msg => {
15
- return "ModuleConcatenation bailout: " + msg;
16
- };
17
-
18
- class ModuleConcatenationPlugin {
19
- constructor(options) {
20
- if (typeof options !== "object") options = {};
21
- this.options = options;
22
- }
23
-
24
- apply(compiler) {
25
- compiler.hooks.compilation.tap(
26
- "ModuleConcatenationPlugin",
27
- (compilation, { normalModuleFactory }) => {
28
- const handler = (parser, parserOptions) => {
29
- parser.hooks.call.for("eval").tap("ModuleConcatenationPlugin", () => {
30
- // Because of variable renaming we can't use modules with eval.
31
- parser.state.module.buildMeta.moduleConcatenationBailout = "eval()";
32
- });
33
- };
34
-
35
- normalModuleFactory.hooks.parser
36
- .for("javascript/auto")
37
- .tap("ModuleConcatenationPlugin", handler);
38
- normalModuleFactory.hooks.parser
39
- .for("javascript/dynamic")
40
- .tap("ModuleConcatenationPlugin", handler);
41
- normalModuleFactory.hooks.parser
42
- .for("javascript/esm")
43
- .tap("ModuleConcatenationPlugin", handler);
44
-
45
- const bailoutReasonMap = new Map();
46
-
47
- const setBailoutReason = (module, reason) => {
48
- bailoutReasonMap.set(module, reason);
49
- module.optimizationBailout.push(
50
- typeof reason === "function"
51
- ? rs => formatBailoutReason(reason(rs))
52
- : formatBailoutReason(reason)
53
- );
54
- };
55
-
56
- const getBailoutReason = (module, requestShortener) => {
57
- const reason = bailoutReasonMap.get(module);
58
- if (typeof reason === "function") return reason(requestShortener);
59
- return reason;
60
- };
61
-
62
- compilation.hooks.optimizeChunkModules.tap(
63
- "ModuleConcatenationPlugin",
64
- (chunks, modules) => {
65
- const relevantModules = [];
66
- const possibleInners = new Set();
67
- for (const module of modules) {
68
- // Only harmony modules are valid for optimization
69
- if (
70
- !module.buildMeta ||
71
- module.buildMeta.exportsType !== "namespace" ||
72
- !module.dependencies.some(
73
- d => d instanceof HarmonyCompatibilityDependency
74
- )
75
- ) {
76
- setBailoutReason(module, "Module is not an ECMAScript module");
77
- continue;
78
- }
79
-
80
- // Some expressions are not compatible with module concatenation
81
- // because they may produce unexpected results. The plugin bails out
82
- // if some were detected upfront.
83
- if (
84
- module.buildMeta &&
85
- module.buildMeta.moduleConcatenationBailout
86
- ) {
87
- setBailoutReason(
88
- module,
89
- `Module uses ${module.buildMeta.moduleConcatenationBailout}`
90
- );
91
- continue;
92
- }
93
-
94
- // Exports must be known (and not dynamic)
95
- if (!Array.isArray(module.buildMeta.providedExports)) {
96
- setBailoutReason(module, "Module exports are unknown");
97
- continue;
98
- }
99
-
100
- // Using dependency variables is not possible as this wraps the code in a function
101
- if (module.variables.length > 0) {
102
- setBailoutReason(
103
- module,
104
- `Module uses injected variables (${module.variables
105
- .map(v => v.name)
106
- .join(", ")})`
107
- );
108
- continue;
109
- }
110
-
111
- // Hot Module Replacement need it's own module to work correctly
112
- if (
113
- module.dependencies.some(
114
- dep =>
115
- dep instanceof ModuleHotAcceptDependency ||
116
- dep instanceof ModuleHotDeclineDependency
117
- )
118
- ) {
119
- setBailoutReason(module, "Module uses Hot Module Replacement");
120
- continue;
121
- }
122
-
123
- relevantModules.push(module);
124
-
125
- // Module must not be the entry points
126
- if (module.isEntryModule()) {
127
- setBailoutReason(module, "Module is an entry point");
128
- continue;
129
- }
130
-
131
- // Module must be in any chunk (we don't want to do useless work)
132
- if (module.getNumberOfChunks() === 0) {
133
- setBailoutReason(module, "Module is not in any chunk");
134
- continue;
135
- }
136
-
137
- // Module must only be used by Harmony Imports
138
- const nonHarmonyReasons = module.reasons.filter(
139
- reason =>
140
- !reason.dependency ||
141
- !(reason.dependency instanceof HarmonyImportDependency)
142
- );
143
- if (nonHarmonyReasons.length > 0) {
144
- const importingModules = new Set(
145
- nonHarmonyReasons.map(r => r.module).filter(Boolean)
146
- );
147
- const importingExplanations = new Set(
148
- nonHarmonyReasons.map(r => r.explanation).filter(Boolean)
149
- );
150
- const importingModuleTypes = new Map(
151
- Array.from(importingModules).map(
152
- m => /** @type {[string, Set]} */ ([
153
- m,
154
- new Set(
155
- nonHarmonyReasons
156
- .filter(r => r.module === m)
157
- .map(r => r.dependency.type)
158
- .sort()
159
- )
160
- ])
161
- )
162
- );
163
- setBailoutReason(module, requestShortener => {
164
- const names = Array.from(importingModules)
165
- .map(
166
- m =>
167
- `${m.readableIdentifier(
168
- requestShortener
169
- )} (referenced with ${Array.from(
170
- importingModuleTypes.get(m)
171
- ).join(", ")})`
172
- )
173
- .sort();
174
- const explanations = Array.from(importingExplanations).sort();
175
- if (names.length > 0 && explanations.length === 0)
176
- return `Module is referenced from these modules with unsupported syntax: ${names.join(
177
- ", "
178
- )}`;
179
- else if (names.length === 0 && explanations.length > 0)
180
- return `Module is referenced by: ${explanations.join(
181
- ", "
182
- )}`;
183
- else if (names.length > 0 && explanations.length > 0)
184
- return `Module is referenced from these modules with unsupported syntax: ${names.join(
185
- ", "
186
- )} and by: ${explanations.join(", ")}`;
187
- else return "Module is referenced in a unsupported way";
188
- });
189
- continue;
190
- }
191
-
192
- possibleInners.add(module);
193
- }
194
- // sort by depth
195
- // modules with lower depth are more likely suited as roots
196
- // this improves performance, because modules already selected as inner are skipped
197
- relevantModules.sort((a, b) => {
198
- return a.depth - b.depth;
199
- });
200
- const concatConfigurations = [];
201
- const usedAsInner = new Set();
202
- for (const currentRoot of relevantModules) {
203
- // when used by another configuration as inner:
204
- // the other configuration is better and we can skip this one
205
- if (usedAsInner.has(currentRoot)) continue;
206
-
207
- // create a configuration with the root
208
- const currentConfiguration = new ConcatConfiguration(currentRoot);
209
-
210
- // cache failures to add modules
211
- const failureCache = new Map();
212
-
213
- // try to add all imports
214
- for (const imp of this.getImports(currentRoot)) {
215
- const problem = this.tryToAdd(
216
- currentConfiguration,
217
- imp,
218
- possibleInners,
219
- failureCache
220
- );
221
- if (problem) {
222
- failureCache.set(imp, problem);
223
- currentConfiguration.addWarning(imp, problem);
224
- }
225
- }
226
- if (!currentConfiguration.isEmpty()) {
227
- concatConfigurations.push(currentConfiguration);
228
- for (const module of currentConfiguration.getModules()) {
229
- if (module !== currentConfiguration.rootModule)
230
- usedAsInner.add(module);
231
- }
232
- }
233
- }
234
- // HACK: Sort configurations by length and start with the longest one
235
- // to get the biggers groups possible. Used modules are marked with usedModules
236
- // TODO: Allow to reuse existing configuration while trying to add dependencies.
237
- // This would improve performance. O(n^2) -> O(n)
238
- concatConfigurations.sort((a, b) => {
239
- return b.modules.size - a.modules.size;
240
- });
241
- const usedModules = new Set();
242
- for (const concatConfiguration of concatConfigurations) {
243
- if (usedModules.has(concatConfiguration.rootModule)) continue;
244
- const modules = concatConfiguration.getModules();
245
- const newModule = new ConcatenatedModule(
246
- concatConfiguration.rootModule,
247
- modules
248
- );
249
- for (const warning of concatConfiguration.getWarningsSorted()) {
250
- newModule.optimizationBailout.push(requestShortener => {
251
- const reason = getBailoutReason(warning[0], requestShortener);
252
- const reasonWithPrefix = reason ? ` (<- ${reason})` : "";
253
- if (warning[0] === warning[1])
254
- return formatBailoutReason(
255
- `Cannot concat with ${warning[0].readableIdentifier(
256
- requestShortener
257
- )}${reasonWithPrefix}`
258
- );
259
- else
260
- return formatBailoutReason(
261
- `Cannot concat with ${warning[0].readableIdentifier(
262
- requestShortener
263
- )} because of ${warning[1].readableIdentifier(
264
- requestShortener
265
- )}${reasonWithPrefix}`
266
- );
267
- });
268
- }
269
- const chunks = concatConfiguration.rootModule.getChunks();
270
- for (const m of modules) {
271
- usedModules.add(m);
272
- for (const chunk of chunks) {
273
- chunk.removeModule(m);
274
- }
275
- }
276
- for (const chunk of chunks) {
277
- chunk.addModule(newModule);
278
- newModule.addChunk(chunk);
279
- if (chunk.entryModule === concatConfiguration.rootModule)
280
- chunk.entryModule = newModule;
281
- }
282
- compilation.modules.push(newModule);
283
- for (const reason of newModule.reasons) {
284
- reason.dependency.module = newModule;
285
- }
286
- // TODO: remove when LTS node version contains fixed v8 version
287
- // @see https://github.com/webpack/webpack/pull/6613
288
- // Turbofan does not correctly inline for-of loops with polymorphic input arrays.
289
- // Work around issue by using a standard for loop and assigning dep.module.reasons
290
- for (let i = 0; i < newModule.dependencies.length; i++) {
291
- let dep = newModule.dependencies[i];
292
- if (dep.module) {
293
- let reasons = dep.module.reasons;
294
- for (let j = 0; j < reasons.length; j++) {
295
- let reason = reasons[j];
296
- if (reason.dependency === dep) reason.module = newModule;
297
- }
298
- }
299
- }
300
- }
301
- compilation.modules = compilation.modules.filter(
302
- m => !usedModules.has(m)
303
- );
304
- }
305
- );
306
- }
307
- );
308
- }
309
-
310
- getImports(module) {
311
- return Array.from(
312
- new Set(
313
- module.dependencies
314
-
315
- // Only harmony Dependencies
316
- .filter(dep => dep instanceof HarmonyImportDependency && dep.module)
317
-
318
- // Get reference info for this dependency
319
- .map(dep => dep.getReference())
320
-
321
- // Reference is valid and has a module
322
- .filter(ref => ref && ref.module)
323
-
324
- // Dependencies are simple enough to concat them
325
- .filter(
326
- ref =>
327
- Array.isArray(ref.importedNames) ||
328
- Array.isArray(ref.module.buildMeta.providedExports)
329
- )
330
-
331
- // Take the imported module
332
- .map(ref => ref.module)
333
- )
334
- );
335
- }
336
-
337
- tryToAdd(config, module, possibleModules, failureCache) {
338
- const cacheEntry = failureCache.get(module);
339
- if (cacheEntry) {
340
- return cacheEntry;
341
- }
342
-
343
- // Already added?
344
- if (config.has(module)) {
345
- return null;
346
- }
347
-
348
- // Not possible to add?
349
- if (!possibleModules.has(module)) {
350
- failureCache.set(module, module); // cache failures for performance
351
- return module;
352
- }
353
-
354
- // module must be in the same chunks
355
- if (!config.rootModule.hasEqualsChunks(module)) {
356
- failureCache.set(module, module); // cache failures for performance
357
- return module;
358
- }
359
-
360
- // Clone config to make experimental changes
361
- const testConfig = config.clone();
362
-
363
- // Add the module
364
- testConfig.add(module);
365
-
366
- // Every module which depends on the added module must be in the configuration too.
367
- for (const reason of module.reasons) {
368
- // Modules that are not used can be ignored
369
- if (
370
- reason.module.factoryMeta.sideEffectFree &&
371
- reason.module.used === false
372
- )
373
- continue;
374
-
375
- const problem = this.tryToAdd(
376
- testConfig,
377
- reason.module,
378
- possibleModules,
379
- failureCache
380
- );
381
- if (problem) {
382
- failureCache.set(module, problem); // cache failures for performance
383
- return problem;
384
- }
385
- }
386
-
387
- // Commit experimental changes
388
- config.set(testConfig);
389
-
390
- // Eagerly try to add imports too if possible
391
- for (const imp of this.getImports(module)) {
392
- const problem = this.tryToAdd(config, imp, possibleModules, failureCache);
393
- if (problem) {
394
- config.addWarning(imp, problem);
395
- }
396
- }
397
- return null;
398
- }
399
- }
400
-
401
- class ConcatConfiguration {
402
- constructor(rootModule, cloneFrom) {
403
- this.rootModule = rootModule;
404
- if (cloneFrom) {
405
- this.modules = cloneFrom.modules.createChild(5);
406
- this.warnings = cloneFrom.warnings.createChild(5);
407
- } else {
408
- this.modules = new StackedSetMap();
409
- this.modules.add(rootModule);
410
- this.warnings = new StackedSetMap();
411
- }
412
- }
413
-
414
- add(module) {
415
- this.modules.add(module);
416
- }
417
-
418
- has(module) {
419
- return this.modules.has(module);
420
- }
421
-
422
- isEmpty() {
423
- return this.modules.size === 1;
424
- }
425
-
426
- addWarning(module, problem) {
427
- this.warnings.set(module, problem);
428
- }
429
-
430
- getWarningsSorted() {
431
- return new Map(
432
- this.warnings.asPairArray().sort((a, b) => {
433
- const ai = a[0].identifier();
434
- const bi = b[0].identifier();
435
- if (ai < bi) return -1;
436
- if (ai > bi) return 1;
437
- return 0;
438
- })
439
- );
440
- }
441
-
442
- getModules() {
443
- return this.modules.asArray();
444
- }
445
-
446
- clone() {
447
- return new ConcatConfiguration(this.rootModule, this);
448
- }
449
-
450
- set(config) {
451
- this.rootModule = config.rootModule;
452
- this.modules = config.modules;
453
- this.warnings = config.warnings;
454
- }
455
- }
456
-
457
- module.exports = ModuleConcatenationPlugin;
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ "use strict";
6
+
7
+ const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
8
+ const ModuleHotAcceptDependency = require("../dependencies/ModuleHotAcceptDependency");
9
+ const ModuleHotDeclineDependency = require("../dependencies/ModuleHotDeclineDependency");
10
+ const ConcatenatedModule = require("./ConcatenatedModule");
11
+ const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
12
+ const StackedSetMap = require("../util/StackedSetMap");
13
+
14
+ const formatBailoutReason = msg => {
15
+ return "ModuleConcatenation bailout: " + msg;
16
+ };
17
+
18
+ class ModuleConcatenationPlugin {
19
+ constructor(options) {
20
+ if (typeof options !== "object") options = {};
21
+ this.options = options;
22
+ }
23
+
24
+ apply(compiler) {
25
+ compiler.hooks.compilation.tap(
26
+ "ModuleConcatenationPlugin",
27
+ (compilation, { normalModuleFactory }) => {
28
+ const handler = (parser, parserOptions) => {
29
+ parser.hooks.call.for("eval").tap("ModuleConcatenationPlugin", () => {
30
+ // Because of variable renaming we can't use modules with eval.
31
+ parser.state.module.buildMeta.moduleConcatenationBailout = "eval()";
32
+ });
33
+ };
34
+
35
+ normalModuleFactory.hooks.parser
36
+ .for("javascript/auto")
37
+ .tap("ModuleConcatenationPlugin", handler);
38
+ normalModuleFactory.hooks.parser
39
+ .for("javascript/dynamic")
40
+ .tap("ModuleConcatenationPlugin", handler);
41
+ normalModuleFactory.hooks.parser
42
+ .for("javascript/esm")
43
+ .tap("ModuleConcatenationPlugin", handler);
44
+
45
+ const bailoutReasonMap = new Map();
46
+
47
+ const setBailoutReason = (module, reason) => {
48
+ bailoutReasonMap.set(module, reason);
49
+ module.optimizationBailout.push(
50
+ typeof reason === "function"
51
+ ? rs => formatBailoutReason(reason(rs))
52
+ : formatBailoutReason(reason)
53
+ );
54
+ };
55
+
56
+ const getBailoutReason = (module, requestShortener) => {
57
+ const reason = bailoutReasonMap.get(module);
58
+ if (typeof reason === "function") return reason(requestShortener);
59
+ return reason;
60
+ };
61
+
62
+ compilation.hooks.optimizeChunkModules.tap(
63
+ "ModuleConcatenationPlugin",
64
+ (chunks, modules) => {
65
+ const relevantModules = [];
66
+ const possibleInners = new Set();
67
+ for (const module of modules) {
68
+ // Only harmony modules are valid for optimization
69
+ if (
70
+ !module.buildMeta ||
71
+ module.buildMeta.exportsType !== "namespace" ||
72
+ !module.dependencies.some(
73
+ d => d instanceof HarmonyCompatibilityDependency
74
+ )
75
+ ) {
76
+ setBailoutReason(module, "Module is not an ECMAScript module");
77
+ continue;
78
+ }
79
+
80
+ // Some expressions are not compatible with module concatenation
81
+ // because they may produce unexpected results. The plugin bails out
82
+ // if some were detected upfront.
83
+ if (
84
+ module.buildMeta &&
85
+ module.buildMeta.moduleConcatenationBailout
86
+ ) {
87
+ setBailoutReason(
88
+ module,
89
+ `Module uses ${module.buildMeta.moduleConcatenationBailout}`
90
+ );
91
+ continue;
92
+ }
93
+
94
+ // Exports must be known (and not dynamic)
95
+ if (!Array.isArray(module.buildMeta.providedExports)) {
96
+ setBailoutReason(module, "Module exports are unknown");
97
+ continue;
98
+ }
99
+
100
+ // Using dependency variables is not possible as this wraps the code in a function
101
+ if (module.variables.length > 0) {
102
+ setBailoutReason(
103
+ module,
104
+ `Module uses injected variables (${module.variables
105
+ .map(v => v.name)
106
+ .join(", ")})`
107
+ );
108
+ continue;
109
+ }
110
+
111
+ // Hot Module Replacement need it's own module to work correctly
112
+ if (
113
+ module.dependencies.some(
114
+ dep =>
115
+ dep instanceof ModuleHotAcceptDependency ||
116
+ dep instanceof ModuleHotDeclineDependency
117
+ )
118
+ ) {
119
+ setBailoutReason(module, "Module uses Hot Module Replacement");
120
+ continue;
121
+ }
122
+
123
+ relevantModules.push(module);
124
+
125
+ // Module must not be the entry points
126
+ if (module.isEntryModule()) {
127
+ setBailoutReason(module, "Module is an entry point");
128
+ continue;
129
+ }
130
+
131
+ // Module must be in any chunk (we don't want to do useless work)
132
+ if (module.getNumberOfChunks() === 0) {
133
+ setBailoutReason(module, "Module is not in any chunk");
134
+ continue;
135
+ }
136
+
137
+ // Module must only be used by Harmony Imports
138
+ const nonHarmonyReasons = module.reasons.filter(
139
+ reason =>
140
+ !reason.dependency ||
141
+ !(reason.dependency instanceof HarmonyImportDependency)
142
+ );
143
+ if (nonHarmonyReasons.length > 0) {
144
+ const importingModules = new Set(
145
+ nonHarmonyReasons.map(r => r.module).filter(Boolean)
146
+ );
147
+ const importingExplanations = new Set(
148
+ nonHarmonyReasons.map(r => r.explanation).filter(Boolean)
149
+ );
150
+ const importingModuleTypes = new Map(
151
+ Array.from(importingModules).map(
152
+ m => /** @type {[string, Set]} */ ([
153
+ m,
154
+ new Set(
155
+ nonHarmonyReasons
156
+ .filter(r => r.module === m)
157
+ .map(r => r.dependency.type)
158
+ .sort()
159
+ )
160
+ ])
161
+ )
162
+ );
163
+ setBailoutReason(module, requestShortener => {
164
+ const names = Array.from(importingModules)
165
+ .map(
166
+ m =>
167
+ `${m.readableIdentifier(
168
+ requestShortener
169
+ )} (referenced with ${Array.from(
170
+ importingModuleTypes.get(m)
171
+ ).join(", ")})`
172
+ )
173
+ .sort();
174
+ const explanations = Array.from(importingExplanations).sort();
175
+ if (names.length > 0 && explanations.length === 0) {
176
+ return `Module is referenced from these modules with unsupported syntax: ${names.join(
177
+ ", "
178
+ )}`;
179
+ } else if (names.length === 0 && explanations.length > 0) {
180
+ return `Module is referenced by: ${explanations.join(
181
+ ", "
182
+ )}`;
183
+ } else if (names.length > 0 && explanations.length > 0) {
184
+ return `Module is referenced from these modules with unsupported syntax: ${names.join(
185
+ ", "
186
+ )} and by: ${explanations.join(", ")}`;
187
+ } else {
188
+ return "Module is referenced in a unsupported way";
189
+ }
190
+ });
191
+ continue;
192
+ }
193
+
194
+ possibleInners.add(module);
195
+ }
196
+ // sort by depth
197
+ // modules with lower depth are more likely suited as roots
198
+ // this improves performance, because modules already selected as inner are skipped
199
+ relevantModules.sort((a, b) => {
200
+ return a.depth - b.depth;
201
+ });
202
+ const concatConfigurations = [];
203
+ const usedAsInner = new Set();
204
+ for (const currentRoot of relevantModules) {
205
+ // when used by another configuration as inner:
206
+ // the other configuration is better and we can skip this one
207
+ if (usedAsInner.has(currentRoot)) continue;
208
+
209
+ // create a configuration with the root
210
+ const currentConfiguration = new ConcatConfiguration(currentRoot);
211
+
212
+ // cache failures to add modules
213
+ const failureCache = new Map();
214
+
215
+ // try to add all imports
216
+ for (const imp of this.getImports(currentRoot)) {
217
+ const problem = this.tryToAdd(
218
+ currentConfiguration,
219
+ imp,
220
+ possibleInners,
221
+ failureCache
222
+ );
223
+ if (problem) {
224
+ failureCache.set(imp, problem);
225
+ currentConfiguration.addWarning(imp, problem);
226
+ }
227
+ }
228
+ if (!currentConfiguration.isEmpty()) {
229
+ concatConfigurations.push(currentConfiguration);
230
+ for (const module of currentConfiguration.getModules()) {
231
+ if (module !== currentConfiguration.rootModule) {
232
+ usedAsInner.add(module);
233
+ }
234
+ }
235
+ }
236
+ }
237
+ // HACK: Sort configurations by length and start with the longest one
238
+ // to get the biggers groups possible. Used modules are marked with usedModules
239
+ // TODO: Allow to reuse existing configuration while trying to add dependencies.
240
+ // This would improve performance. O(n^2) -> O(n)
241
+ concatConfigurations.sort((a, b) => {
242
+ return b.modules.size - a.modules.size;
243
+ });
244
+ const usedModules = new Set();
245
+ for (const concatConfiguration of concatConfigurations) {
246
+ if (usedModules.has(concatConfiguration.rootModule)) continue;
247
+ const modules = concatConfiguration.getModules();
248
+ const newModule = new ConcatenatedModule(
249
+ concatConfiguration.rootModule,
250
+ modules
251
+ );
252
+ for (const warning of concatConfiguration.getWarningsSorted()) {
253
+ newModule.optimizationBailout.push(requestShortener => {
254
+ const reason = getBailoutReason(warning[0], requestShortener);
255
+ const reasonWithPrefix = reason ? ` (<- ${reason})` : "";
256
+ if (warning[0] === warning[1]) {
257
+ return formatBailoutReason(
258
+ `Cannot concat with ${warning[0].readableIdentifier(
259
+ requestShortener
260
+ )}${reasonWithPrefix}`
261
+ );
262
+ } else {
263
+ return formatBailoutReason(
264
+ `Cannot concat with ${warning[0].readableIdentifier(
265
+ requestShortener
266
+ )} because of ${warning[1].readableIdentifier(
267
+ requestShortener
268
+ )}${reasonWithPrefix}`
269
+ );
270
+ }
271
+ });
272
+ }
273
+ const chunks = concatConfiguration.rootModule.getChunks();
274
+ for (const m of modules) {
275
+ usedModules.add(m);
276
+ for (const chunk of chunks) {
277
+ chunk.removeModule(m);
278
+ }
279
+ }
280
+ for (const chunk of chunks) {
281
+ chunk.addModule(newModule);
282
+ newModule.addChunk(chunk);
283
+ if (chunk.entryModule === concatConfiguration.rootModule) {
284
+ chunk.entryModule = newModule;
285
+ }
286
+ }
287
+ compilation.modules.push(newModule);
288
+ for (const reason of newModule.reasons) {
289
+ if (reason.dependency.module === concatConfiguration.rootModule)
290
+ reason.dependency.module = newModule;
291
+ if (
292
+ reason.dependency.redirectedModule ===
293
+ concatConfiguration.rootModule
294
+ )
295
+ reason.dependency.redirectedModule = newModule;
296
+ }
297
+ // TODO: remove when LTS node version contains fixed v8 version
298
+ // @see https://github.com/webpack/webpack/pull/6613
299
+ // Turbofan does not correctly inline for-of loops with polymorphic input arrays.
300
+ // Work around issue by using a standard for loop and assigning dep.module.reasons
301
+ for (let i = 0; i < newModule.dependencies.length; i++) {
302
+ let dep = newModule.dependencies[i];
303
+ if (dep.module) {
304
+ let reasons = dep.module.reasons;
305
+ for (let j = 0; j < reasons.length; j++) {
306
+ let reason = reasons[j];
307
+ if (reason.dependency === dep) {
308
+ reason.module = newModule;
309
+ }
310
+ }
311
+ }
312
+ }
313
+ }
314
+ compilation.modules = compilation.modules.filter(
315
+ m => !usedModules.has(m)
316
+ );
317
+ }
318
+ );
319
+ }
320
+ );
321
+ }
322
+
323
+ getImports(module) {
324
+ return Array.from(
325
+ new Set(
326
+ module.dependencies
327
+
328
+ // Only harmony Dependencies
329
+ .filter(dep => dep instanceof HarmonyImportDependency)
330
+
331
+ // Get reference info for this dependency
332
+ .map(dep => dep.getReference())
333
+
334
+ // Reference is valid and has a module
335
+ .filter(ref => ref && ref.module)
336
+
337
+ // Dependencies are simple enough to concat them
338
+ .filter(
339
+ ref =>
340
+ Array.isArray(ref.importedNames) ||
341
+ Array.isArray(ref.module.buildMeta.providedExports)
342
+ )
343
+
344
+ // Take the imported module
345
+ .map(ref => ref.module)
346
+ )
347
+ );
348
+ }
349
+
350
+ tryToAdd(config, module, possibleModules, failureCache) {
351
+ const cacheEntry = failureCache.get(module);
352
+ if (cacheEntry) {
353
+ return cacheEntry;
354
+ }
355
+
356
+ // Already added?
357
+ if (config.has(module)) {
358
+ return null;
359
+ }
360
+
361
+ // Not possible to add?
362
+ if (!possibleModules.has(module)) {
363
+ failureCache.set(module, module); // cache failures for performance
364
+ return module;
365
+ }
366
+
367
+ // module must be in the same chunks
368
+ if (!config.rootModule.hasEqualsChunks(module)) {
369
+ failureCache.set(module, module); // cache failures for performance
370
+ return module;
371
+ }
372
+
373
+ // Clone config to make experimental changes
374
+ const testConfig = config.clone();
375
+
376
+ // Add the module
377
+ testConfig.add(module);
378
+
379
+ // Every module which depends on the added module must be in the configuration too.
380
+ for (const reason of module.reasons) {
381
+ // Modules that are not used can be ignored
382
+ if (
383
+ reason.module.factoryMeta.sideEffectFree &&
384
+ reason.module.used === false
385
+ )
386
+ continue;
387
+
388
+ const problem = this.tryToAdd(
389
+ testConfig,
390
+ reason.module,
391
+ possibleModules,
392
+ failureCache
393
+ );
394
+ if (problem) {
395
+ failureCache.set(module, problem); // cache failures for performance
396
+ return problem;
397
+ }
398
+ }
399
+
400
+ // Commit experimental changes
401
+ config.set(testConfig);
402
+
403
+ // Eagerly try to add imports too if possible
404
+ for (const imp of this.getImports(module)) {
405
+ const problem = this.tryToAdd(config, imp, possibleModules, failureCache);
406
+ if (problem) {
407
+ config.addWarning(imp, problem);
408
+ }
409
+ }
410
+ return null;
411
+ }
412
+ }
413
+
414
+ class ConcatConfiguration {
415
+ constructor(rootModule, cloneFrom) {
416
+ this.rootModule = rootModule;
417
+ if (cloneFrom) {
418
+ this.modules = cloneFrom.modules.createChild(5);
419
+ this.warnings = cloneFrom.warnings.createChild(5);
420
+ } else {
421
+ this.modules = new StackedSetMap();
422
+ this.modules.add(rootModule);
423
+ this.warnings = new StackedSetMap();
424
+ }
425
+ }
426
+
427
+ add(module) {
428
+ this.modules.add(module);
429
+ }
430
+
431
+ has(module) {
432
+ return this.modules.has(module);
433
+ }
434
+
435
+ isEmpty() {
436
+ return this.modules.size === 1;
437
+ }
438
+
439
+ addWarning(module, problem) {
440
+ this.warnings.set(module, problem);
441
+ }
442
+
443
+ getWarningsSorted() {
444
+ return new Map(
445
+ this.warnings.asPairArray().sort((a, b) => {
446
+ const ai = a[0].identifier();
447
+ const bi = b[0].identifier();
448
+ if (ai < bi) return -1;
449
+ if (ai > bi) return 1;
450
+ return 0;
451
+ })
452
+ );
453
+ }
454
+
455
+ getModules() {
456
+ return this.modules.asArray();
457
+ }
458
+
459
+ clone() {
460
+ return new ConcatConfiguration(this.rootModule, this);
461
+ }
462
+
463
+ set(config) {
464
+ this.rootModule = config.rootModule;
465
+ this.modules = config.modules;
466
+ this.warnings = config.warnings;
467
+ }
468
+ }
469
+
470
+ module.exports = ModuleConcatenationPlugin;