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.
- package/README.md +755 -755
- package/SECURITY.md +9 -9
- package/buildin/global.js +20 -20
- package/buildin/harmony-module.js +24 -24
- package/buildin/module.js +22 -22
- package/hot/dev-server.js +61 -61
- package/hot/log-apply-result.js +44 -44
- package/hot/log.js +45 -45
- package/hot/only-dev-server.js +105 -105
- package/hot/poll.js +37 -37
- package/hot/signal.js +62 -62
- package/lib/APIPlugin.js +84 -84
- package/lib/AmdMainTemplatePlugin.js +87 -75
- package/lib/AsyncDependenciesBlock.js +66 -66
- package/lib/AsyncDependencyToInitialChunkError.js +31 -21
- package/lib/AutomaticPrefetchPlugin.js +50 -50
- package/lib/BannerPlugin.js +3 -1
- package/lib/BasicEvaluatedExpression.js +211 -208
- package/lib/CachePlugin.js +102 -95
- package/lib/CaseSensitiveModulesWarning.js +71 -53
- package/lib/Chunk.js +750 -722
- package/lib/ChunkGroup.js +13 -5
- package/lib/ChunkRenderError.js +32 -32
- package/lib/CompatibilityPlugin.js +63 -63
- package/lib/Compilation.js +1947 -1905
- package/lib/Compiler.js +508 -496
- package/lib/ConcurrentCompilationError.js +19 -19
- package/lib/ConstPlugin.js +258 -242
- package/lib/ContextExclusionPlugin.js +17 -17
- package/lib/ContextModule.js +749 -710
- package/lib/ContextModuleFactory.js +256 -245
- package/lib/ContextReplacementPlugin.js +133 -126
- package/lib/DefinePlugin.js +206 -197
- package/lib/DelegatedModule.js +101 -101
- package/lib/DelegatedModuleFactoryPlugin.js +89 -89
- package/lib/DelegatedPlugin.js +39 -39
- package/lib/DependenciesBlock.js +89 -87
- package/lib/DependenciesBlockVariable.js +52 -51
- package/lib/Dependency.js +51 -51
- package/lib/DllEntryPlugin.js +51 -51
- package/lib/DllModule.js +54 -54
- package/lib/DllModuleFactory.js +29 -29
- package/lib/DllPlugin.js +44 -42
- package/lib/DllReferencePlugin.js +84 -84
- package/lib/DynamicEntryPlugin.js +73 -71
- package/lib/EntryOptionPlugin.js +33 -33
- package/lib/EnvironmentPlugin.js +65 -65
- package/lib/ErrorHelpers.js +60 -57
- package/lib/EvalDevToolModulePlugin.js +27 -27
- package/lib/EvalDevToolModuleTemplatePlugin.js +61 -61
- package/lib/EvalSourceMapDevToolPlugin.js +41 -40
- package/lib/ExportPropertyMainTemplatePlugin.js +53 -40
- package/lib/ExtendedAPIPlugin.js +84 -84
- package/lib/ExternalModule.js +159 -159
- package/lib/ExternalModuleFactoryPlugin.js +110 -110
- package/lib/ExternalsPlugin.js +23 -23
- package/lib/FlagDependencyExportsPlugin.js +146 -146
- package/lib/FlagDependencyUsagePlugin.js +110 -104
- package/lib/FlagInitialModulesAsUsedPlugin.js +36 -36
- package/lib/FunctionModulePlugin.js +19 -19
- package/lib/FunctionModuleTemplatePlugin.js +100 -98
- package/lib/GraphHelpers.js +64 -64
- package/lib/HarmonyLinkingError.js +18 -18
- package/lib/HashedModuleIdsPlugin.js +53 -53
- package/lib/HotModuleReplacement.runtime.js +7 -3
- package/lib/HotModuleReplacementPlugin.js +413 -406
- package/lib/HotUpdateChunk.js +16 -16
- package/lib/HotUpdateChunkTemplate.js +78 -78
- package/lib/IgnorePlugin.js +71 -71
- package/lib/JavascriptGenerator.js +229 -228
- package/lib/JavascriptModulesPlugin.js +179 -184
- package/lib/JsonGenerator.js +42 -42
- package/lib/JsonModulesPlugin.js +30 -30
- package/lib/JsonParser.js +27 -26
- package/lib/LibManifestPlugin.js +86 -86
- package/lib/LibraryTemplatePlugin.js +153 -119
- package/lib/LoaderOptionsPlugin.js +53 -52
- package/lib/LoaderTargetPlugin.js +24 -24
- package/lib/MainTemplate.js +34 -9
- package/lib/Module.js +381 -377
- package/lib/ModuleBuildError.js +42 -42
- package/lib/ModuleDependencyError.js +35 -25
- package/lib/ModuleDependencyWarning.js +25 -25
- package/lib/ModuleError.js +28 -28
- package/lib/ModuleFilenameHelpers.js +178 -166
- package/lib/ModuleParseError.js +44 -44
- package/lib/ModuleReason.js +40 -40
- package/lib/ModuleTemplate.js +84 -84
- package/lib/ModuleWarning.js +30 -30
- package/lib/MultiCompiler.js +283 -271
- package/lib/MultiEntryPlugin.js +58 -58
- package/lib/MultiModule.js +81 -78
- package/lib/MultiModuleFactory.js +23 -23
- package/lib/MultiStats.js +92 -92
- package/lib/MultiWatching.js +38 -38
- package/lib/NamedChunksPlugin.js +29 -29
- package/lib/NamedModulesPlugin.js +57 -57
- package/lib/NoEmitOnErrorsPlugin.js +20 -20
- package/lib/NoModeWarning.js +23 -23
- package/lib/NodeStuffPlugin.js +179 -178
- package/lib/NormalModule.js +497 -490
- package/lib/NormalModuleFactory.js +501 -483
- package/lib/NormalModuleReplacementPlugin.js +51 -51
- package/lib/OptionsDefaulter.js +84 -80
- package/lib/Parser.js +2164 -2086
- package/lib/ParserHelpers.js +103 -100
- package/lib/PrefetchPlugin.js +37 -37
- package/lib/ProgressPlugin.js +231 -231
- package/lib/ProvidePlugin.js +86 -86
- package/lib/RawModule.js +56 -54
- package/lib/RecordIdsPlugin.js +166 -162
- package/lib/RemovedPluginError.js +13 -13
- package/lib/RequestShortener.js +81 -74
- package/lib/RequireJsStuffPlugin.js +69 -69
- package/lib/ResolverFactory.js +64 -64
- package/lib/RuleSet.js +555 -534
- package/lib/RuntimeTemplate.js +320 -277
- package/lib/SetVarMainTemplatePlugin.js +69 -57
- package/lib/SingleEntryPlugin.js +44 -44
- package/lib/SizeFormatHelpers.js +24 -24
- package/lib/SourceMapDevToolModuleOptionsPlugin.js +49 -49
- package/lib/SourceMapDevToolPlugin.js +301 -300
- package/lib/Stats.js +1408 -1367
- package/lib/Template.js +4 -2
- package/lib/TemplatedPathPlugin.js +173 -170
- package/lib/UmdMainTemplatePlugin.js +304 -264
- package/lib/UseStrictPlugin.js +48 -48
- package/lib/WarnCaseSensitiveModulesPlugin.js +37 -36
- package/lib/WarnNoModeSetPlugin.js +17 -17
- package/lib/WatchIgnorePlugin.js +100 -100
- package/lib/Watching.js +194 -193
- package/lib/WebpackError.js +25 -19
- package/lib/WebpackOptionsApply.js +421 -405
- package/lib/WebpackOptionsDefaulter.js +347 -344
- package/lib/WebpackOptionsValidationError.js +345 -316
- package/lib/compareLocations.js +56 -56
- package/lib/dependencies/AMDDefineDependency.js +137 -137
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +336 -327
- package/lib/dependencies/AMDPlugin.js +250 -250
- package/lib/dependencies/AMDRequireArrayDependency.js +49 -49
- package/lib/dependencies/AMDRequireContextDependency.js +20 -20
- package/lib/dependencies/AMDRequireDependenciesBlock.js +43 -43
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +273 -270
- package/lib/dependencies/AMDRequireDependency.js +135 -135
- package/lib/dependencies/CommonJsPlugin.js +161 -161
- package/lib/dependencies/CommonJsRequireContextDependency.js +23 -23
- package/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +130 -130
- package/lib/dependencies/ConstDependency.js +33 -33
- package/lib/dependencies/ContextDependency.js +68 -68
- package/lib/dependencies/ContextDependencyTemplateAsId.js +42 -42
- package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +38 -38
- package/lib/dependencies/ContextElementDependency.js +21 -21
- package/lib/dependencies/DelegatedExportsDependency.js +33 -33
- package/lib/dependencies/DependencyReference.js +18 -18
- package/lib/dependencies/HarmonyAcceptDependency.js +45 -45
- package/lib/dependencies/HarmonyAcceptImportDependency.js +23 -23
- package/lib/dependencies/HarmonyCompatibilityDependency.js +31 -31
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +92 -90
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +139 -139
- package/lib/dependencies/HarmonyExportExpressionDependency.js +53 -53
- package/lib/dependencies/HarmonyExportHeaderDependency.js +30 -30
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +620 -603
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +54 -54
- package/lib/dependencies/HarmonyImportDependency.js +104 -94
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +217 -214
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +31 -31
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +166 -156
- package/lib/dependencies/HarmonyInitDependency.js +60 -60
- package/lib/dependencies/HarmonyModulesPlugin.js +146 -146
- package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +26 -26
- package/lib/dependencies/ImportContextDependency.js +23 -23
- package/lib/dependencies/ImportDependenciesBlock.js +18 -18
- package/lib/dependencies/ImportDependency.js +34 -34
- package/lib/dependencies/ImportEagerDependency.js +32 -32
- package/lib/dependencies/ImportParserPlugin.js +233 -232
- package/lib/dependencies/ImportPlugin.js +82 -82
- package/lib/dependencies/ImportWeakDependency.js +34 -34
- package/lib/dependencies/JsonExportsDependency.js +26 -26
- package/lib/dependencies/LoaderPlugin.js +98 -93
- package/lib/dependencies/LocalModuleDependency.js +28 -28
- package/lib/dependencies/LocalModulesHelpers.js +52 -45
- package/lib/dependencies/ModuleDependency.js +20 -20
- package/lib/dependencies/ModuleDependencyTemplateAsId.js +17 -17
- package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +17 -17
- package/lib/dependencies/MultiEntryDependency.js +20 -20
- package/lib/dependencies/NullDependency.js +20 -20
- package/lib/dependencies/RequireContextDependency.js +22 -22
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +56 -56
- package/lib/dependencies/RequireContextPlugin.js +143 -141
- package/lib/dependencies/RequireEnsureDependenciesBlock.js +33 -33
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +116 -112
- package/lib/dependencies/RequireEnsureDependency.js +58 -58
- package/lib/dependencies/RequireEnsurePlugin.js +74 -74
- package/lib/dependencies/RequireHeaderDependency.js +26 -26
- package/lib/dependencies/RequireIncludeDependency.js +39 -39
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +23 -23
- package/lib/dependencies/RequireIncludePlugin.js +61 -61
- package/lib/dependencies/RequireResolveContextDependency.js +23 -23
- package/lib/dependencies/RequireResolveDependencyParserPlugin.js +85 -85
- package/lib/dependencies/RequireResolveHeaderDependency.js +26 -26
- package/lib/dependencies/SingleEntryDependency.js +18 -18
- package/lib/dependencies/SystemPlugin.js +125 -125
- package/lib/dependencies/UnsupportedDependency.js +27 -27
- package/lib/dependencies/WebAssemblyImportDependency.js +48 -44
- package/lib/dependencies/WebpackMissingModule.js +20 -20
- package/lib/dependencies/getFunctionExpression.js +52 -52
- package/lib/formatLocation.js +61 -53
- package/lib/node/NodeChunkTemplatePlugin.js +31 -31
- package/lib/node/NodeEnvironmentPlugin.js +28 -28
- package/lib/node/NodeHotUpdateChunkTemplatePlugin.js +36 -36
- package/lib/node/NodeMainTemplate.runtime.js +27 -27
- package/lib/node/NodeMainTemplateAsync.runtime.js +44 -44
- package/lib/node/NodeMainTemplatePlugin.js +323 -320
- package/lib/node/NodeSourcePlugin.js +144 -140
- package/lib/node/NodeTargetPlugin.js +18 -18
- package/lib/node/NodeTemplatePlugin.js +31 -31
- package/lib/node/NodeWatchFileSystem.js +99 -82
- package/lib/node/ReadFileCompileWasmTemplatePlugin.js +52 -52
- package/lib/optimize/AggressiveMergingPlugin.js +87 -87
- package/lib/optimize/AggressiveSplittingPlugin.js +287 -281
- package/lib/optimize/ChunkModuleIdRangePlugin.js +68 -68
- package/lib/optimize/ConcatenatedModule.js +1420 -1413
- package/lib/optimize/EnsureChunkConditionsPlugin.js +70 -70
- package/lib/optimize/FlagIncludedChunksPlugin.js +99 -99
- package/lib/optimize/LimitChunkCountPlugin.js +66 -66
- package/lib/optimize/MergeDuplicateChunksPlugin.js +78 -75
- package/lib/optimize/MinChunkSizePlugin.js +77 -77
- package/lib/optimize/ModuleConcatenationPlugin.js +470 -457
- package/lib/optimize/OccurrenceOrderPlugin.js +133 -126
- package/lib/optimize/RemoveParentModulesPlugin.js +127 -117
- package/lib/optimize/RuntimeChunkPlugin.js +41 -41
- package/lib/optimize/SideEffectsFlagPlugin.js +158 -156
- package/lib/optimize/SplitChunksPlugin.js +709 -696
- package/lib/performance/AssetsOverSizeLimitWarning.js +30 -30
- package/lib/performance/EntrypointsOverSizeLimitWarning.js +31 -31
- package/lib/performance/NoAsyncChunksWarning.js +21 -21
- package/lib/performance/SizeLimitsPlugin.js +105 -105
- package/lib/util/Semaphore.js +41 -41
- package/lib/util/SortableSet.js +5 -2
- package/lib/util/StackedSetMap.js +12 -5
- package/lib/util/TrackingSet.js +35 -35
- package/lib/util/cachedMerge.js +35 -35
- package/lib/util/createHash.js +77 -77
- package/lib/util/identifier.js +76 -76
- package/lib/validateSchema.js +67 -67
- package/lib/wasm/UnsupportedWebAssemblyFeatureError.js +18 -18
- package/lib/wasm/WasmMainTemplatePlugin.js +310 -304
- package/lib/wasm/WebAssemblyGenerator.js +143 -19
- package/lib/wasm/WebAssemblyJavascriptGenerator.js +90 -107
- package/lib/wasm/WebAssemblyModulesPlugin.js +80 -80
- package/lib/wasm/WebAssemblyParser.js +28 -5
- package/lib/wasm/WebAssemblyUtils.js +48 -0
- package/lib/web/FetchCompileWasmTemplatePlugin.js +25 -25
- package/lib/web/JsonpChunkTemplatePlugin.js +47 -47
- package/lib/web/JsonpExportMainTemplatePlugin.js +47 -47
- package/lib/web/JsonpHotUpdateChunkTemplatePlugin.js +39 -39
- package/lib/web/JsonpMainTemplate.runtime.js +65 -64
- package/lib/web/JsonpMainTemplatePlugin.js +576 -574
- package/lib/web/JsonpTemplatePlugin.js +23 -23
- package/lib/webpack.js +183 -182
- package/lib/webpack.web.js +31 -31
- package/lib/webworker/WebWorkerChunkTemplatePlugin.js +35 -35
- package/lib/webworker/WebWorkerHotUpdateChunkTemplatePlugin.js +40 -40
- package/lib/webworker/WebWorkerMainTemplate.runtime.js +65 -64
- package/lib/webworker/WebWorkerMainTemplatePlugin.js +179 -179
- package/lib/webworker/WebWorkerTemplatePlugin.js +25 -25
- package/package.json +9 -8
- package/schemas/WebpackOptions.json +1988 -1988
- package/schemas/ajv.absolutePath.js +55 -55
- package/schemas/plugins/DllPlugin.json +32 -32
- package/schemas/plugins/DllReferencePlugin.json +99 -99
- package/schemas/plugins/HashedModuleIdsPlugin.json +24 -24
- package/schemas/plugins/LoaderOptionsPlugin.json +26 -26
- package/schemas/plugins/SourceMapDevToolPlugin.json +187 -187
- package/schemas/plugins/WatchIgnorePlugin.json +16 -16
- package/schemas/plugins/debug/ProfilingPlugin.json +12 -12
- package/schemas/plugins/optimize/AggressiveSplittingPlugin.json +22 -22
- package/schemas/plugins/optimize/LimitChunkCountPlugin.json +15 -15
- package/schemas/plugins/optimize/MinChunkSizePlugin.json +13 -13
@@ -1,696 +1,709 @@
|
|
1
|
-
/*
|
2
|
-
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
-
Author Tobias Koppers @sokra
|
4
|
-
*/
|
5
|
-
"use strict";
|
6
|
-
|
7
|
-
const crypto = require("crypto");
|
8
|
-
const SortableSet = require("../util/SortableSet");
|
9
|
-
const GraphHelpers = require("../GraphHelpers");
|
10
|
-
const { isSubset } = require("../util/SetHelpers");
|
11
|
-
|
12
|
-
/** @typedef {import("../Chunk")} Chunk */
|
13
|
-
/** @typedef {import("../Module")} Module */
|
14
|
-
|
15
|
-
const hashFilename = name => {
|
16
|
-
return crypto
|
17
|
-
.createHash("md4")
|
18
|
-
.update(name)
|
19
|
-
.digest("hex")
|
20
|
-
.slice(0, 8);
|
21
|
-
};
|
22
|
-
|
23
|
-
const sortByIdentifier = (a, b) => {
|
24
|
-
if (a.identifier() > b.identifier()) return 1;
|
25
|
-
if (a.identifier() < b.identifier()) return -1;
|
26
|
-
return 0;
|
27
|
-
};
|
28
|
-
|
29
|
-
const getRequests = chunk => {
|
30
|
-
let requests = 0;
|
31
|
-
for (const chunkGroup of chunk.groupsIterable) {
|
32
|
-
requests = Math.max(requests, chunkGroup.chunks.length);
|
33
|
-
}
|
34
|
-
return requests;
|
35
|
-
};
|
36
|
-
|
37
|
-
const getModulesSize = modules => {
|
38
|
-
let sum = 0;
|
39
|
-
for (const m of modules)
|
40
|
-
|
41
|
-
}
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
const
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
const
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
const
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
const
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
}
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
//
|
139
|
-
//
|
140
|
-
//
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
)
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
return test(module);
|
245
|
-
}
|
246
|
-
if (typeof test === "boolean") return test;
|
247
|
-
if (typeof test === "string") {
|
248
|
-
if (
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
const
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
* @
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
const
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
* @
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
const
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
//
|
415
|
-
|
416
|
-
//
|
417
|
-
const
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
cacheGroupSource.
|
497
|
-
? cacheGroupSource.
|
498
|
-
:
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
if (
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
)
|
569
|
-
newChunk = chunk;
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
}
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
);
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
1
|
+
/*
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
+
Author Tobias Koppers @sokra
|
4
|
+
*/
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
const crypto = require("crypto");
|
8
|
+
const SortableSet = require("../util/SortableSet");
|
9
|
+
const GraphHelpers = require("../GraphHelpers");
|
10
|
+
const { isSubset } = require("../util/SetHelpers");
|
11
|
+
|
12
|
+
/** @typedef {import("../Chunk")} Chunk */
|
13
|
+
/** @typedef {import("../Module")} Module */
|
14
|
+
|
15
|
+
const hashFilename = name => {
|
16
|
+
return crypto
|
17
|
+
.createHash("md4")
|
18
|
+
.update(name)
|
19
|
+
.digest("hex")
|
20
|
+
.slice(0, 8);
|
21
|
+
};
|
22
|
+
|
23
|
+
const sortByIdentifier = (a, b) => {
|
24
|
+
if (a.identifier() > b.identifier()) return 1;
|
25
|
+
if (a.identifier() < b.identifier()) return -1;
|
26
|
+
return 0;
|
27
|
+
};
|
28
|
+
|
29
|
+
const getRequests = chunk => {
|
30
|
+
let requests = 0;
|
31
|
+
for (const chunkGroup of chunk.groupsIterable) {
|
32
|
+
requests = Math.max(requests, chunkGroup.chunks.length);
|
33
|
+
}
|
34
|
+
return requests;
|
35
|
+
};
|
36
|
+
|
37
|
+
const getModulesSize = modules => {
|
38
|
+
let sum = 0;
|
39
|
+
for (const m of modules) {
|
40
|
+
sum += m.size();
|
41
|
+
}
|
42
|
+
return sum;
|
43
|
+
};
|
44
|
+
|
45
|
+
const isOverlap = (a, b) => {
|
46
|
+
for (const item of a.keys()) {
|
47
|
+
if (b.has(item)) return true;
|
48
|
+
}
|
49
|
+
return false;
|
50
|
+
};
|
51
|
+
|
52
|
+
const compareEntries = (a, b) => {
|
53
|
+
// 1. by priority
|
54
|
+
const diffPriority = a.cacheGroup.priority - b.cacheGroup.priority;
|
55
|
+
if (diffPriority) return diffPriority;
|
56
|
+
// 2. by number of chunks
|
57
|
+
const diffCount = a.chunks.size - b.chunks.size;
|
58
|
+
if (diffCount) return diffCount;
|
59
|
+
// 3. by size reduction
|
60
|
+
const aSizeReduce = a.size * (a.chunks.size - 1);
|
61
|
+
const bSizeReduce = b.size * (b.chunks.size - 1);
|
62
|
+
const diffSizeReduce = aSizeReduce - bSizeReduce;
|
63
|
+
if (diffSizeReduce) return diffSizeReduce;
|
64
|
+
// 4. by number of modules (to be able to compare by identifier)
|
65
|
+
const modulesA = a.modules;
|
66
|
+
const modulesB = b.modules;
|
67
|
+
const diff = modulesA.size - modulesB.size;
|
68
|
+
if (diff) return diff;
|
69
|
+
// 5. by module identifiers
|
70
|
+
modulesA.sort();
|
71
|
+
modulesB.sort();
|
72
|
+
const aI = modulesA[Symbol.iterator]();
|
73
|
+
const bI = modulesB[Symbol.iterator]();
|
74
|
+
// eslint-disable-next-line no-constant-condition
|
75
|
+
while (true) {
|
76
|
+
const aItem = aI.next();
|
77
|
+
const bItem = bI.next();
|
78
|
+
if (aItem.done) return 0;
|
79
|
+
const aModuleIdentifier = aItem.value.identifier();
|
80
|
+
const bModuleIdentifier = bItem.value.identifier();
|
81
|
+
if (aModuleIdentifier > bModuleIdentifier) return -1;
|
82
|
+
if (aModuleIdentifier < bModuleIdentifier) return 1;
|
83
|
+
}
|
84
|
+
};
|
85
|
+
|
86
|
+
const INITIAL_CHUNK_FILTER = chunk => chunk.canBeInitial();
|
87
|
+
const ASYNC_CHUNK_FILTER = chunk => !chunk.canBeInitial();
|
88
|
+
const ALL_CHUNK_FILTER = chunk => true;
|
89
|
+
|
90
|
+
module.exports = class SplitChunksPlugin {
|
91
|
+
constructor(options) {
|
92
|
+
this.options = SplitChunksPlugin.normalizeOptions(options);
|
93
|
+
}
|
94
|
+
|
95
|
+
static normalizeOptions(options = {}) {
|
96
|
+
return {
|
97
|
+
chunksFilter: SplitChunksPlugin.normalizeChunksFilter(
|
98
|
+
options.chunks || "all"
|
99
|
+
),
|
100
|
+
minSize: options.minSize || 0,
|
101
|
+
minChunks: options.minChunks || 1,
|
102
|
+
maxAsyncRequests: options.maxAsyncRequests || 1,
|
103
|
+
maxInitialRequests: options.maxInitialRequests || 1,
|
104
|
+
getName:
|
105
|
+
SplitChunksPlugin.normalizeName({
|
106
|
+
name: options.name,
|
107
|
+
automaticNameDelimiter: options.automaticNameDelimiter
|
108
|
+
}) || (() => {}),
|
109
|
+
filename: options.filename || undefined,
|
110
|
+
getCacheGroups: SplitChunksPlugin.normalizeCacheGroups({
|
111
|
+
cacheGroups: options.cacheGroups,
|
112
|
+
automaticNameDelimiter: options.automaticNameDelimiter
|
113
|
+
})
|
114
|
+
};
|
115
|
+
}
|
116
|
+
|
117
|
+
static normalizeName({ name, automaticNameDelimiter }) {
|
118
|
+
if (name === true) {
|
119
|
+
const cache = new Map();
|
120
|
+
const fn = (module, chunks, cacheGroup) => {
|
121
|
+
let cacheEntry = cache.get(chunks);
|
122
|
+
if (cacheEntry === undefined) {
|
123
|
+
cacheEntry = {};
|
124
|
+
cache.set(chunks, cacheEntry);
|
125
|
+
} else if (cacheGroup in cacheEntry) {
|
126
|
+
return cacheEntry[cacheGroup];
|
127
|
+
}
|
128
|
+
const names = chunks.map(c => c.name);
|
129
|
+
if (!names.every(Boolean)) {
|
130
|
+
cacheEntry[cacheGroup] = undefined;
|
131
|
+
return;
|
132
|
+
}
|
133
|
+
names.sort();
|
134
|
+
let name =
|
135
|
+
(cacheGroup && cacheGroup !== "default"
|
136
|
+
? cacheGroup + automaticNameDelimiter
|
137
|
+
: "") + names.join(automaticNameDelimiter);
|
138
|
+
// Filenames and paths can't be too long otherwise an
|
139
|
+
// ENAMETOOLONG error is raised. If the generated name if too
|
140
|
+
// long, it is truncated and a hash is appended. The limit has
|
141
|
+
// been set to 100 to prevent `[name].[chunkhash].[ext]` from
|
142
|
+
// generating a 256+ character string.
|
143
|
+
if (name.length > 100) {
|
144
|
+
name =
|
145
|
+
name.slice(0, 100) + automaticNameDelimiter + hashFilename(name);
|
146
|
+
}
|
147
|
+
cacheEntry[cacheGroup] = name;
|
148
|
+
return name;
|
149
|
+
};
|
150
|
+
return fn;
|
151
|
+
}
|
152
|
+
if (typeof name === "string") {
|
153
|
+
const fn = () => {
|
154
|
+
return name;
|
155
|
+
};
|
156
|
+
return fn;
|
157
|
+
}
|
158
|
+
if (typeof name === "function") return name;
|
159
|
+
}
|
160
|
+
|
161
|
+
static normalizeChunksFilter(chunks) {
|
162
|
+
if (chunks === "initial") {
|
163
|
+
return INITIAL_CHUNK_FILTER;
|
164
|
+
}
|
165
|
+
if (chunks === "async") {
|
166
|
+
return ASYNC_CHUNK_FILTER;
|
167
|
+
}
|
168
|
+
if (chunks === "all") {
|
169
|
+
return ALL_CHUNK_FILTER;
|
170
|
+
}
|
171
|
+
if (typeof chunks === "function") return chunks;
|
172
|
+
}
|
173
|
+
|
174
|
+
static normalizeCacheGroups({ cacheGroups, automaticNameDelimiter }) {
|
175
|
+
if (typeof cacheGroups === "function") {
|
176
|
+
// TODO webpack 5 remove this
|
177
|
+
if (cacheGroups.length !== 1) {
|
178
|
+
return module => cacheGroups(module, module.getChunks());
|
179
|
+
}
|
180
|
+
return cacheGroups;
|
181
|
+
}
|
182
|
+
if (cacheGroups && typeof cacheGroups === "object") {
|
183
|
+
const fn = module => {
|
184
|
+
let results;
|
185
|
+
for (const key of Object.keys(cacheGroups)) {
|
186
|
+
let option = cacheGroups[key];
|
187
|
+
if (option === false) continue;
|
188
|
+
if (option instanceof RegExp || typeof option === "string") {
|
189
|
+
option = {
|
190
|
+
test: option
|
191
|
+
};
|
192
|
+
}
|
193
|
+
if (typeof option === "function") {
|
194
|
+
let result = option(module);
|
195
|
+
if (result) {
|
196
|
+
if (results === undefined) results = [];
|
197
|
+
for (const r of Array.isArray(result) ? result : [result]) {
|
198
|
+
const result = Object.assign({ key }, r);
|
199
|
+
if (result.name) result.getName = () => result.name;
|
200
|
+
if (result.chunks) {
|
201
|
+
result.chunksFilter = SplitChunksPlugin.normalizeChunksFilter(
|
202
|
+
result.chunks
|
203
|
+
);
|
204
|
+
}
|
205
|
+
results.push(result);
|
206
|
+
}
|
207
|
+
}
|
208
|
+
} else if (SplitChunksPlugin.checkTest(option.test, module)) {
|
209
|
+
if (results === undefined) results = [];
|
210
|
+
results.push({
|
211
|
+
key: key,
|
212
|
+
priority: option.priority,
|
213
|
+
getName: SplitChunksPlugin.normalizeName({
|
214
|
+
name: option.name,
|
215
|
+
automaticNameDelimiter
|
216
|
+
}),
|
217
|
+
chunksFilter: SplitChunksPlugin.normalizeChunksFilter(
|
218
|
+
option.chunks
|
219
|
+
),
|
220
|
+
enforce: option.enforce,
|
221
|
+
minSize: option.minSize,
|
222
|
+
minChunks: option.minChunks,
|
223
|
+
maxAsyncRequests: option.maxAsyncRequests,
|
224
|
+
maxInitialRequests: option.maxInitialRequests,
|
225
|
+
filename: option.filename,
|
226
|
+
reuseExistingChunk: option.reuseExistingChunk
|
227
|
+
});
|
228
|
+
}
|
229
|
+
}
|
230
|
+
return results;
|
231
|
+
};
|
232
|
+
return fn;
|
233
|
+
}
|
234
|
+
const fn = () => {};
|
235
|
+
return fn;
|
236
|
+
}
|
237
|
+
|
238
|
+
static checkTest(test, module) {
|
239
|
+
if (test === undefined) return true;
|
240
|
+
if (typeof test === "function") {
|
241
|
+
if (test.length !== 1) {
|
242
|
+
return test(module, module.getChunks());
|
243
|
+
}
|
244
|
+
return test(module);
|
245
|
+
}
|
246
|
+
if (typeof test === "boolean") return test;
|
247
|
+
if (typeof test === "string") {
|
248
|
+
if (
|
249
|
+
module.nameForCondition &&
|
250
|
+
module.nameForCondition().startsWith(test)
|
251
|
+
) {
|
252
|
+
return true;
|
253
|
+
}
|
254
|
+
for (const chunk of module.chunksIterable) {
|
255
|
+
if (chunk.name && chunk.name.startsWith(test)) {
|
256
|
+
return true;
|
257
|
+
}
|
258
|
+
}
|
259
|
+
return false;
|
260
|
+
}
|
261
|
+
if (test instanceof RegExp) {
|
262
|
+
if (module.nameForCondition && test.test(module.nameForCondition())) {
|
263
|
+
return true;
|
264
|
+
}
|
265
|
+
for (const chunk of module.chunksIterable) {
|
266
|
+
if (chunk.name && test.test(chunk.name)) {
|
267
|
+
return true;
|
268
|
+
}
|
269
|
+
}
|
270
|
+
return false;
|
271
|
+
}
|
272
|
+
return false;
|
273
|
+
}
|
274
|
+
|
275
|
+
apply(compiler) {
|
276
|
+
compiler.hooks.thisCompilation.tap("SplitChunksPlugin", compilation => {
|
277
|
+
let alreadyOptimized = false;
|
278
|
+
compilation.hooks.unseal.tap("SplitChunksPlugin", () => {
|
279
|
+
alreadyOptimized = false;
|
280
|
+
});
|
281
|
+
compilation.hooks.optimizeChunksAdvanced.tap(
|
282
|
+
"SplitChunksPlugin",
|
283
|
+
chunks => {
|
284
|
+
if (alreadyOptimized) return;
|
285
|
+
alreadyOptimized = true;
|
286
|
+
// Give each selected chunk an index (to create strings from chunks)
|
287
|
+
const indexMap = new Map();
|
288
|
+
let index = 1;
|
289
|
+
for (const chunk of chunks) {
|
290
|
+
indexMap.set(chunk, index++);
|
291
|
+
}
|
292
|
+
const getKey = chunks => {
|
293
|
+
return Array.from(chunks, c => indexMap.get(c))
|
294
|
+
.sort()
|
295
|
+
.join();
|
296
|
+
};
|
297
|
+
/** @type {Map<string, Set<Chunk>>} */
|
298
|
+
const chunkSetsInGraph = new Map();
|
299
|
+
for (const module of compilation.modules) {
|
300
|
+
const chunksKey = getKey(module.chunksIterable);
|
301
|
+
if (!chunkSetsInGraph.has(chunksKey)) {
|
302
|
+
chunkSetsInGraph.set(chunksKey, new Set(module.chunksIterable));
|
303
|
+
}
|
304
|
+
}
|
305
|
+
|
306
|
+
// group these set of chunks by count
|
307
|
+
// to allow to check less sets via isSubset
|
308
|
+
// (only smaller sets can be subset)
|
309
|
+
/** @type {Map<number, Array<Set<Chunk>>>} */
|
310
|
+
const chunkSetsByCount = new Map();
|
311
|
+
for (const chunksSet of chunkSetsInGraph.values()) {
|
312
|
+
const count = chunksSet.size;
|
313
|
+
let array = chunkSetsByCount.get(count);
|
314
|
+
if (array === undefined) {
|
315
|
+
array = [];
|
316
|
+
chunkSetsByCount.set(count, array);
|
317
|
+
}
|
318
|
+
array.push(chunksSet);
|
319
|
+
}
|
320
|
+
|
321
|
+
// Create a list of possible combinations
|
322
|
+
const combinationsCache = new Map(); // Map<string, Set<Chunk>[]>
|
323
|
+
|
324
|
+
const getCombinations = key => {
|
325
|
+
const chunksSet = chunkSetsInGraph.get(key);
|
326
|
+
var array = [chunksSet];
|
327
|
+
if (chunksSet.size > 1) {
|
328
|
+
for (const [count, setArray] of chunkSetsByCount) {
|
329
|
+
// "equal" is not needed because they would have been merge in the first step
|
330
|
+
if (count < chunksSet.size) {
|
331
|
+
for (const set of setArray) {
|
332
|
+
if (isSubset(chunksSet, set)) {
|
333
|
+
array.push(set);
|
334
|
+
}
|
335
|
+
}
|
336
|
+
}
|
337
|
+
}
|
338
|
+
}
|
339
|
+
return array;
|
340
|
+
};
|
341
|
+
|
342
|
+
/**
|
343
|
+
* @typedef {Object} SelectedChunksResult
|
344
|
+
* @property {Chunk[]} chunks the list of chunks
|
345
|
+
* @property {string} key a key of the list
|
346
|
+
*/
|
347
|
+
|
348
|
+
/**
|
349
|
+
* @typedef {function(Chunk): boolean} ChunkFilterFunction
|
350
|
+
*/
|
351
|
+
|
352
|
+
/** @type {WeakMap<Set<Chunk>, WeakMap<ChunkFilterFunction, SelectedChunksResult>>} */
|
353
|
+
const selectedChunksCacheByChunksSet = new WeakMap();
|
354
|
+
|
355
|
+
/**
|
356
|
+
* get list and key by applying the filter function to the list
|
357
|
+
* It is cached for performance reasons
|
358
|
+
* @param {Set<Chunk>} chunks list of chunks
|
359
|
+
* @param {ChunkFilterFunction} chunkFilter filter function for chunks
|
360
|
+
* @returns {SelectedChunksResult} list and key
|
361
|
+
*/
|
362
|
+
const getSelectedChunks = (chunks, chunkFilter) => {
|
363
|
+
let entry = selectedChunksCacheByChunksSet.get(chunks);
|
364
|
+
if (entry === undefined) {
|
365
|
+
entry = new WeakMap();
|
366
|
+
selectedChunksCacheByChunksSet.set(chunks, entry);
|
367
|
+
}
|
368
|
+
/** @type {SelectedChunksResult} */
|
369
|
+
let entry2 = entry.get(chunkFilter);
|
370
|
+
if (entry2 === undefined) {
|
371
|
+
/** @type {Chunk[]} */
|
372
|
+
const selectedChunks = [];
|
373
|
+
for (const chunk of chunks) {
|
374
|
+
if (chunkFilter(chunk)) selectedChunks.push(chunk);
|
375
|
+
}
|
376
|
+
entry2 = {
|
377
|
+
chunks: selectedChunks,
|
378
|
+
key: getKey(selectedChunks)
|
379
|
+
};
|
380
|
+
entry.set(chunkFilter, entry2);
|
381
|
+
}
|
382
|
+
return entry2;
|
383
|
+
};
|
384
|
+
|
385
|
+
/**
|
386
|
+
* @typedef {Object} ChunksInfoItem
|
387
|
+
* @property {SortableSet} modules
|
388
|
+
* @property {TODO} cacheGroup
|
389
|
+
* @property {string} name
|
390
|
+
* @property {number} size
|
391
|
+
* @property {Map<Chunk, number>} chunks
|
392
|
+
* @property {Set<Chunk>} reuseableChunks
|
393
|
+
* @property {Set<string>} chunksKeys
|
394
|
+
*/
|
395
|
+
|
396
|
+
// Map a list of chunks to a list of modules
|
397
|
+
// For the key the chunk "index" is used, the value is a SortableSet of modules
|
398
|
+
/** @type {Map<string, ChunksInfoItem>} */
|
399
|
+
const chunksInfoMap = new Map();
|
400
|
+
|
401
|
+
/**
|
402
|
+
* @param {TODO} cacheGroup the current cache group
|
403
|
+
* @param {Chunk[]} selectedChunks chunks selected for this module
|
404
|
+
* @param {string} selectedChunksKey a key of selectedChunks
|
405
|
+
* @param {Module} module the current module
|
406
|
+
* @returns {void}
|
407
|
+
*/
|
408
|
+
const addModuleToChunksInfoMap = (
|
409
|
+
cacheGroup,
|
410
|
+
selectedChunks,
|
411
|
+
selectedChunksKey,
|
412
|
+
module
|
413
|
+
) => {
|
414
|
+
// Break if minimum number of chunks is not reached
|
415
|
+
if (selectedChunks.length < cacheGroup.minChunks) return;
|
416
|
+
// Determine name for split chunk
|
417
|
+
const name = cacheGroup.getName(
|
418
|
+
module,
|
419
|
+
selectedChunks,
|
420
|
+
cacheGroup.key
|
421
|
+
);
|
422
|
+
// Create key for maps
|
423
|
+
// When it has a name we use the name as key
|
424
|
+
// Elsewise we create the key from chunks and cache group key
|
425
|
+
// This automatically merges equal names
|
426
|
+
const key =
|
427
|
+
(name && `name:${name}`) ||
|
428
|
+
`chunks:${selectedChunksKey} key:${cacheGroup.key}`;
|
429
|
+
// Add module to maps
|
430
|
+
let info = chunksInfoMap.get(key);
|
431
|
+
if (info === undefined) {
|
432
|
+
chunksInfoMap.set(
|
433
|
+
key,
|
434
|
+
(info = {
|
435
|
+
modules: new SortableSet(undefined, sortByIdentifier),
|
436
|
+
cacheGroup,
|
437
|
+
name,
|
438
|
+
size: 0,
|
439
|
+
chunks: new Map(),
|
440
|
+
reuseableChunks: new Set(),
|
441
|
+
chunksKeys: new Set()
|
442
|
+
})
|
443
|
+
);
|
444
|
+
}
|
445
|
+
info.modules.add(module);
|
446
|
+
info.size += module.size();
|
447
|
+
if (!info.chunksKeys.has(selectedChunksKey)) {
|
448
|
+
info.chunksKeys.add(selectedChunksKey);
|
449
|
+
for (const chunk of selectedChunks) {
|
450
|
+
info.chunks.set(chunk, chunk.getNumberOfModules());
|
451
|
+
}
|
452
|
+
}
|
453
|
+
};
|
454
|
+
|
455
|
+
// Walk through all modules
|
456
|
+
for (const module of compilation.modules) {
|
457
|
+
// Get cache group
|
458
|
+
let cacheGroups = this.options.getCacheGroups(module);
|
459
|
+
if (!Array.isArray(cacheGroups) || cacheGroups.length === 0) {
|
460
|
+
continue;
|
461
|
+
}
|
462
|
+
|
463
|
+
// Prepare some values
|
464
|
+
const chunksKey = getKey(module.chunksIterable);
|
465
|
+
let combs = combinationsCache.get(chunksKey);
|
466
|
+
if (combs === undefined) {
|
467
|
+
combs = getCombinations(chunksKey);
|
468
|
+
combinationsCache.set(chunksKey, combs);
|
469
|
+
}
|
470
|
+
|
471
|
+
for (const cacheGroupSource of cacheGroups) {
|
472
|
+
const cacheGroup = {
|
473
|
+
key: cacheGroupSource.key,
|
474
|
+
priority: cacheGroupSource.priority || 0,
|
475
|
+
chunksFilter:
|
476
|
+
cacheGroupSource.chunksFilter || this.options.chunksFilter,
|
477
|
+
minSize:
|
478
|
+
cacheGroupSource.minSize !== undefined
|
479
|
+
? cacheGroupSource.minSize
|
480
|
+
: cacheGroupSource.enforce
|
481
|
+
? 0
|
482
|
+
: this.options.minSize,
|
483
|
+
minChunks:
|
484
|
+
cacheGroupSource.minChunks !== undefined
|
485
|
+
? cacheGroupSource.minChunks
|
486
|
+
: cacheGroupSource.enforce
|
487
|
+
? 1
|
488
|
+
: this.options.minChunks,
|
489
|
+
maxAsyncRequests:
|
490
|
+
cacheGroupSource.maxAsyncRequests !== undefined
|
491
|
+
? cacheGroupSource.maxAsyncRequests
|
492
|
+
: cacheGroupSource.enforce
|
493
|
+
? Infinity
|
494
|
+
: this.options.maxAsyncRequests,
|
495
|
+
maxInitialRequests:
|
496
|
+
cacheGroupSource.maxInitialRequests !== undefined
|
497
|
+
? cacheGroupSource.maxInitialRequests
|
498
|
+
: cacheGroupSource.enforce
|
499
|
+
? Infinity
|
500
|
+
: this.options.maxInitialRequests,
|
501
|
+
getName:
|
502
|
+
cacheGroupSource.getName !== undefined
|
503
|
+
? cacheGroupSource.getName
|
504
|
+
: this.options.getName,
|
505
|
+
filename:
|
506
|
+
cacheGroupSource.filename !== undefined
|
507
|
+
? cacheGroupSource.filename
|
508
|
+
: this.options.filename,
|
509
|
+
reuseExistingChunk: cacheGroupSource.reuseExistingChunk
|
510
|
+
};
|
511
|
+
// For all combination of chunk selection
|
512
|
+
for (const chunkCombination of combs) {
|
513
|
+
// Break if minimum number of chunks is not reached
|
514
|
+
if (chunkCombination.size < cacheGroup.minChunks) continue;
|
515
|
+
// Select chunks by configuration
|
516
|
+
const {
|
517
|
+
chunks: selectedChunks,
|
518
|
+
key: selectedChunksKey
|
519
|
+
} = getSelectedChunks(
|
520
|
+
chunkCombination,
|
521
|
+
cacheGroup.chunksFilter
|
522
|
+
);
|
523
|
+
|
524
|
+
addModuleToChunksInfoMap(
|
525
|
+
cacheGroup,
|
526
|
+
selectedChunks,
|
527
|
+
selectedChunksKey,
|
528
|
+
module
|
529
|
+
);
|
530
|
+
}
|
531
|
+
}
|
532
|
+
}
|
533
|
+
|
534
|
+
while (chunksInfoMap.size > 0) {
|
535
|
+
// Find best matching entry
|
536
|
+
let bestEntryKey;
|
537
|
+
let bestEntry;
|
538
|
+
for (const pair of chunksInfoMap) {
|
539
|
+
const key = pair[0];
|
540
|
+
const info = pair[1];
|
541
|
+
if (info.size >= info.cacheGroup.minSize) {
|
542
|
+
if (bestEntry === undefined) {
|
543
|
+
bestEntry = info;
|
544
|
+
bestEntryKey = key;
|
545
|
+
} else if (compareEntries(bestEntry, info) < 0) {
|
546
|
+
bestEntry = info;
|
547
|
+
bestEntryKey = key;
|
548
|
+
}
|
549
|
+
}
|
550
|
+
}
|
551
|
+
|
552
|
+
// No suitable item left
|
553
|
+
if (bestEntry === undefined) break;
|
554
|
+
|
555
|
+
const item = bestEntry;
|
556
|
+
chunksInfoMap.delete(bestEntryKey);
|
557
|
+
|
558
|
+
let chunkName = item.name;
|
559
|
+
// Variable for the new chunk (lazy created)
|
560
|
+
let newChunk;
|
561
|
+
// When no chunk name, check if we can reuse a chunk instead of creating a new one
|
562
|
+
let isReused = false;
|
563
|
+
if (item.cacheGroup.reuseExistingChunk) {
|
564
|
+
for (const pair of item.chunks) {
|
565
|
+
if (pair[1] === item.modules.size) {
|
566
|
+
const chunk = pair[0];
|
567
|
+
if (chunk.hasEntryModule()) continue;
|
568
|
+
if (!newChunk || !newChunk.name) {
|
569
|
+
newChunk = chunk;
|
570
|
+
} else if (
|
571
|
+
chunk.name &&
|
572
|
+
chunk.name.length < newChunk.name.length
|
573
|
+
) {
|
574
|
+
newChunk = chunk;
|
575
|
+
} else if (
|
576
|
+
chunk.name &&
|
577
|
+
chunk.name.length === newChunk.name.length &&
|
578
|
+
chunk.name < newChunk.name
|
579
|
+
) {
|
580
|
+
newChunk = chunk;
|
581
|
+
}
|
582
|
+
chunkName = undefined;
|
583
|
+
isReused = true;
|
584
|
+
}
|
585
|
+
}
|
586
|
+
}
|
587
|
+
// Check if maxRequests condition can be fullfilled
|
588
|
+
|
589
|
+
const usedChunks = Array.from(item.chunks.keys()).filter(chunk => {
|
590
|
+
// skip if we address ourself
|
591
|
+
return (
|
592
|
+
(!chunkName || chunk.name !== chunkName) && chunk !== newChunk
|
593
|
+
);
|
594
|
+
});
|
595
|
+
|
596
|
+
// Skip when no chunk selected
|
597
|
+
if (usedChunks.length === 0) continue;
|
598
|
+
|
599
|
+
const chunkInLimit = usedChunks.filter(chunk => {
|
600
|
+
// respect max requests when not enforced
|
601
|
+
const maxRequests = chunk.isOnlyInitial()
|
602
|
+
? item.cacheGroup.maxInitialRequests
|
603
|
+
: chunk.canBeInitial()
|
604
|
+
? Math.min(
|
605
|
+
item.cacheGroup.maxInitialRequests,
|
606
|
+
item.cacheGroup.maxAsyncRequests
|
607
|
+
)
|
608
|
+
: item.cacheGroup.maxAsyncRequests;
|
609
|
+
return !isFinite(maxRequests) || getRequests(chunk) < maxRequests;
|
610
|
+
});
|
611
|
+
|
612
|
+
if (chunkInLimit.length < usedChunks.length) {
|
613
|
+
for (const module of item.modules) {
|
614
|
+
addModuleToChunksInfoMap(
|
615
|
+
item.cacheGroup,
|
616
|
+
chunkInLimit,
|
617
|
+
getKey(chunkInLimit),
|
618
|
+
module
|
619
|
+
);
|
620
|
+
}
|
621
|
+
continue;
|
622
|
+
}
|
623
|
+
|
624
|
+
// Create the new chunk if not reusing one
|
625
|
+
if (!isReused) {
|
626
|
+
newChunk = compilation.addChunk(chunkName);
|
627
|
+
}
|
628
|
+
// Walk through all chunks
|
629
|
+
for (const chunk of usedChunks) {
|
630
|
+
// Add graph connections for splitted chunk
|
631
|
+
chunk.split(newChunk);
|
632
|
+
}
|
633
|
+
|
634
|
+
// Add a note to the chunk
|
635
|
+
newChunk.chunkReason = isReused
|
636
|
+
? "reused as split chunk"
|
637
|
+
: "split chunk";
|
638
|
+
if (item.cacheGroup.key) {
|
639
|
+
newChunk.chunkReason += ` (cache group: ${item.cacheGroup.key})`;
|
640
|
+
}
|
641
|
+
if (chunkName) {
|
642
|
+
newChunk.chunkReason += ` (name: ${chunkName})`;
|
643
|
+
// If the chosen name is already an entry point we remove the entry point
|
644
|
+
const entrypoint = compilation.entrypoints.get(chunkName);
|
645
|
+
if (entrypoint) {
|
646
|
+
compilation.entrypoints.delete(chunkName);
|
647
|
+
entrypoint.remove();
|
648
|
+
newChunk.entryModule = undefined;
|
649
|
+
}
|
650
|
+
}
|
651
|
+
if (item.cacheGroup.filename) {
|
652
|
+
if (!newChunk.isOnlyInitial()) {
|
653
|
+
throw new Error(
|
654
|
+
"SplitChunksPlugin: You are trying to set a filename for a chunk which is (also) loaded on demand. " +
|
655
|
+
"The runtime can only handle loading of chunks which match the chunkFilename schema. " +
|
656
|
+
"Using a custom filename would fail at runtime. " +
|
657
|
+
`(cache group: ${item.cacheGroup.key})`
|
658
|
+
);
|
659
|
+
}
|
660
|
+
newChunk.filenameTemplate = item.cacheGroup.filename;
|
661
|
+
}
|
662
|
+
if (!isReused) {
|
663
|
+
// Add all modules to the new chunk
|
664
|
+
for (const module of item.modules) {
|
665
|
+
if (typeof module.chunkCondition === "function") {
|
666
|
+
if (!module.chunkCondition(newChunk)) continue;
|
667
|
+
}
|
668
|
+
// Add module to new chunk
|
669
|
+
GraphHelpers.connectChunkAndModule(newChunk, module);
|
670
|
+
// Remove module from used chunks
|
671
|
+
for (const chunk of usedChunks) {
|
672
|
+
chunk.removeModule(module);
|
673
|
+
module.rewriteChunkInReasons(chunk, [newChunk]);
|
674
|
+
}
|
675
|
+
}
|
676
|
+
} else {
|
677
|
+
// Remove all modules from used chunks
|
678
|
+
for (const module of item.modules) {
|
679
|
+
for (const chunk of usedChunks) {
|
680
|
+
chunk.removeModule(module);
|
681
|
+
module.rewriteChunkInReasons(chunk, [newChunk]);
|
682
|
+
}
|
683
|
+
}
|
684
|
+
}
|
685
|
+
// remove all modules from other entries and update size
|
686
|
+
for (const [key, info] of chunksInfoMap) {
|
687
|
+
if (isOverlap(info.chunks, item.chunks)) {
|
688
|
+
const oldSize = info.modules.size;
|
689
|
+
for (const module of item.modules) {
|
690
|
+
info.modules.delete(module);
|
691
|
+
}
|
692
|
+
if (info.modules.size === 0) {
|
693
|
+
chunksInfoMap.delete(key);
|
694
|
+
continue;
|
695
|
+
}
|
696
|
+
if (info.modules.size !== oldSize) {
|
697
|
+
info.size = getModulesSize(info.modules);
|
698
|
+
if (info.size < info.cacheGroup.minSize) {
|
699
|
+
chunksInfoMap.delete(key);
|
700
|
+
}
|
701
|
+
}
|
702
|
+
}
|
703
|
+
}
|
704
|
+
}
|
705
|
+
}
|
706
|
+
);
|
707
|
+
});
|
708
|
+
}
|
709
|
+
};
|