webpack 4.15.0 → 4.16.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/LICENSE +20 -20
- package/README.md +761 -758
- package/SECURITY.md +9 -9
- package/buildin/amd-define.js +3 -3
- package/buildin/amd-options.js +2 -2
- package/buildin/global.js +20 -20
- package/buildin/harmony-module.js +24 -24
- package/buildin/module.js +22 -22
- package/buildin/system.js +7 -7
- package/hot/dev-server.js +61 -61
- package/hot/emitter.js +2 -2
- 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 +40 -37
- package/hot/signal.js +62 -62
- package/lib/APIPlugin.js +84 -84
- package/lib/AmdMainTemplatePlugin.js +87 -87
- package/lib/AsyncDependencyToInitialChunkError.js +31 -31
- package/lib/AutomaticPrefetchPlugin.js +1 -1
- package/lib/BannerPlugin.js +117 -117
- package/lib/BasicEvaluatedExpression.js +211 -211
- package/lib/CachePlugin.js +102 -102
- package/lib/CaseSensitiveModulesWarning.js +67 -67
- package/lib/Chunk.js +833 -811
- package/lib/ChunkGroup.js +4 -4
- package/lib/ChunkRenderError.js +32 -32
- package/lib/CommentCompilationWarning.js +2 -2
- package/lib/CompatibilityPlugin.js +70 -70
- package/lib/Compilation.js +46 -15
- package/lib/ConcurrentCompilationError.js +19 -19
- package/lib/ConstPlugin.js +258 -258
- package/lib/ContextExclusionPlugin.js +28 -17
- package/lib/ContextModule.js +844 -739
- package/lib/ContextModuleFactory.js +262 -256
- package/lib/ContextReplacementPlugin.js +133 -133
- package/lib/DefinePlugin.js +49 -0
- package/lib/DelegatedModule.js +5 -0
- package/lib/DelegatedModuleFactoryPlugin.js +95 -89
- package/lib/DelegatedPlugin.js +39 -39
- package/lib/DependenciesBlock.js +1 -1
- package/lib/Dependency.js +10 -4
- package/lib/DllModule.js +60 -54
- package/lib/DllModuleFactory.js +29 -29
- package/lib/DllPlugin.js +44 -44
- package/lib/DllReferencePlugin.js +132 -84
- package/lib/EntryModuleNotFoundError.js +21 -21
- package/lib/Entrypoint.js +54 -54
- package/lib/EnvironmentPlugin.js +72 -65
- package/lib/ErrorHelpers.js +60 -60
- package/lib/EvalDevToolModulePlugin.js +27 -27
- package/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +115 -115
- package/lib/EvalSourceMapDevToolPlugin.js +41 -41
- package/lib/ExportPropertyMainTemplatePlugin.js +53 -53
- package/lib/ExternalModule.js +165 -159
- package/lib/ExternalsPlugin.js +23 -23
- package/lib/FlagDependencyExportsPlugin.js +146 -146
- package/lib/FlagInitialModulesAsUsedPlugin.js +36 -36
- package/lib/FunctionModuleTemplatePlugin.js +100 -100
- package/lib/Generator.js +60 -52
- package/lib/HarmonyLinkingError.js +17 -17
- package/lib/HashedModuleIdsPlugin.js +53 -53
- package/lib/HotModuleReplacementPlugin.js +411 -413
- package/lib/IgnorePlugin.js +90 -90
- package/lib/JavascriptGenerator.js +229 -229
- package/lib/JavascriptModulesPlugin.js +179 -179
- package/lib/JsonGenerator.js +55 -55
- package/lib/JsonModulesPlugin.js +30 -30
- package/lib/JsonParser.js +27 -27
- package/lib/LibManifestPlugin.js +86 -86
- package/lib/LibraryTemplatePlugin.js +153 -153
- package/lib/LoaderOptionsPlugin.js +53 -53
- package/lib/LoaderTargetPlugin.js +24 -24
- package/lib/MemoryOutputFileSystem.js +5 -5
- package/lib/Module.js +431 -391
- package/lib/ModuleBuildError.js +52 -52
- package/lib/ModuleDependencyError.js +35 -35
- package/lib/ModuleDependencyWarning.js +25 -25
- package/lib/ModuleError.js +36 -36
- package/lib/ModuleFilenameHelpers.js +178 -178
- package/lib/ModuleNotFoundError.js +23 -23
- package/lib/ModuleParseError.js +57 -57
- package/lib/ModuleTemplate.js +93 -93
- package/lib/ModuleWarning.js +36 -36
- package/lib/MultiCompiler.js +283 -283
- package/lib/MultiModule.js +87 -81
- 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 +197 -179
- package/lib/NormalModule.js +542 -536
- package/lib/NormalModuleFactory.js +526 -526
- package/lib/NormalModuleReplacementPlugin.js +51 -51
- package/lib/NullFactory.js +12 -12
- package/lib/OptionsApply.js +10 -10
- package/lib/OptionsDefaulter.js +84 -84
- package/lib/Parser.js +2202 -2193
- package/lib/ParserHelpers.js +103 -103
- package/lib/PrefetchPlugin.js +37 -37
- package/lib/ProgressPlugin.js +246 -246
- package/lib/ProvidePlugin.js +86 -86
- package/lib/RawModule.js +56 -56
- package/lib/RecordIdsPlugin.js +230 -230
- package/lib/RemovedPluginError.js +11 -11
- package/lib/RequestShortener.js +83 -83
- package/lib/RequireJsStuffPlugin.js +69 -69
- package/lib/ResolverFactory.js +64 -64
- package/lib/RuntimeTemplate.js +12 -0
- package/lib/SetVarMainTemplatePlugin.js +69 -69
- package/lib/SingleEntryPlugin.js +6 -1
- package/lib/SizeFormatHelpers.js +24 -24
- package/lib/SourceMapDevToolModuleOptionsPlugin.js +49 -49
- package/lib/SourceMapDevToolPlugin.js +301 -301
- package/lib/Stats.js +28 -5
- package/lib/TemplatedPathPlugin.js +173 -173
- package/lib/UnsupportedFeatureWarning.js +22 -22
- package/lib/UseStrictPlugin.js +54 -54
- package/lib/WarnCaseSensitiveModulesPlugin.js +37 -37
- package/lib/WarnNoModeSetPlugin.js +17 -17
- package/lib/WatchIgnorePlugin.js +100 -100
- package/lib/Watching.js +194 -194
- package/lib/WebpackOptionsApply.js +92 -10
- package/lib/WebpackOptionsDefaulter.js +368 -354
- package/lib/debug/ProfilingPlugin.js +430 -430
- package/lib/dependencies/AMDPlugin.js +250 -250
- package/lib/dependencies/AMDRequireArrayDependency.js +49 -49
- package/lib/dependencies/AMDRequireContextDependency.js +20 -20
- package/lib/dependencies/AMDRequireDependency.js +135 -135
- package/lib/dependencies/AMDRequireItemDependency.js +22 -22
- package/lib/dependencies/CommonJsPlugin.js +161 -161
- package/lib/dependencies/CommonJsRequireContextDependency.js +23 -23
- package/lib/dependencies/CommonJsRequireDependency.js +22 -22
- package/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +6 -0
- package/lib/dependencies/ConstDependency.js +33 -33
- package/lib/dependencies/ContextDependency.js +68 -68
- package/lib/dependencies/ContextDependencyHelpers.js +142 -142
- package/lib/dependencies/ContextDependencyTemplateAsId.js +42 -42
- package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +38 -38
- package/lib/dependencies/ContextElementDependency.js +21 -21
- package/lib/dependencies/CriticalDependencyWarning.js +20 -20
- package/lib/dependencies/DelegatedSourceDependency.js +18 -18
- package/lib/dependencies/DllEntryDependency.js +20 -20
- package/lib/dependencies/HarmonyAcceptDependency.js +45 -45
- package/lib/dependencies/HarmonyCompatibilityDependency.js +31 -31
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +92 -92
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +139 -139
- package/lib/dependencies/HarmonyExportHeaderDependency.js +30 -30
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +2 -1
- package/lib/dependencies/HarmonyImportDependency.js +109 -109
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +222 -222
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +31 -31
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +167 -167
- 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 +263 -263
- package/lib/dependencies/ImportPlugin.js +82 -82
- package/lib/dependencies/ImportWeakDependency.js +34 -34
- package/lib/dependencies/LoaderPlugin.js +18 -1
- package/lib/dependencies/LocalModule.js +23 -23
- package/lib/dependencies/LocalModulesHelpers.js +52 -52
- package/lib/dependencies/ModuleDependencyTemplateAsId.js +17 -17
- package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +17 -17
- package/lib/dependencies/ModuleHotAcceptDependency.js +23 -23
- package/lib/dependencies/ModuleHotDeclineDependency.js +23 -23
- package/lib/dependencies/NullDependency.js +20 -20
- package/lib/dependencies/PrefetchDependency.js +18 -18
- package/lib/dependencies/RequireContextDependency.js +22 -22
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +56 -56
- package/lib/dependencies/RequireContextPlugin.js +143 -143
- package/lib/dependencies/RequireEnsureDependenciesBlock.js +33 -33
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +116 -116
- package/lib/dependencies/RequireEnsureDependency.js +58 -58
- package/lib/dependencies/RequireEnsureItemDependency.js +21 -21
- package/lib/dependencies/RequireEnsurePlugin.js +74 -74
- package/lib/dependencies/RequireHeaderDependency.js +26 -26
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +23 -23
- package/lib/dependencies/RequireIncludePlugin.js +61 -61
- package/lib/dependencies/RequireResolveContextDependency.js +23 -23
- package/lib/dependencies/RequireResolveDependency.js +22 -22
- package/lib/dependencies/RequireResolveDependencyParserPlugin.js +85 -85
- package/lib/dependencies/RequireResolveHeaderDependency.js +26 -26
- package/lib/dependencies/SystemPlugin.js +125 -125
- package/lib/dependencies/UnsupportedDependency.js +27 -27
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +29 -29
- package/lib/dependencies/WebAssemblyImportDependency.js +48 -48
- package/lib/dependencies/WebpackMissingModule.js +20 -20
- package/lib/formatLocation.js +75 -61
- 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/NodeMainTemplatePlugin.js +323 -323
- package/lib/node/NodeOutputFileSystem.js +22 -22
- package/lib/node/NodeSourcePlugin.js +144 -144
- package/lib/node/NodeTargetPlugin.js +18 -18
- package/lib/node/NodeTemplatePlugin.js +31 -31
- package/lib/node/NodeWatchFileSystem.js +99 -99
- package/lib/node/ReadFileCompileWasmTemplatePlugin.js +61 -61
- package/lib/optimize/AggressiveMergingPlugin.js +87 -87
- package/lib/optimize/AggressiveSplittingPlugin.js +287 -287
- package/lib/optimize/ConcatenatedModule.js +5 -0
- 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 -78
- package/lib/optimize/MinChunkSizePlugin.js +77 -77
- package/lib/optimize/NaturalChunkOrderPlugin.js +41 -0
- package/lib/optimize/OccurrenceChunkOrderPlugin.js +61 -0
- package/lib/optimize/OccurrenceModuleOrderPlugin.js +103 -0
- package/lib/optimize/OccurrenceOrderPlugin.js +135 -133
- package/lib/optimize/RemoveEmptyChunksPlugin.js +42 -42
- package/lib/optimize/RemoveParentModulesPlugin.js +127 -127
- package/lib/optimize/RuntimeChunkPlugin.js +41 -41
- package/lib/optimize/SideEffectsFlagPlugin.js +168 -168
- package/lib/optimize/SplitChunksPlugin.js +866 -850
- package/lib/performance/AssetsOverSizeLimitWarning.js +30 -30
- package/lib/performance/EntrypointsOverSizeLimitWarning.js +30 -30
- package/lib/performance/NoAsyncChunksWarning.js +21 -21
- package/lib/performance/SizeLimitsPlugin.js +105 -105
- package/lib/util/SortableSet.js +1 -0
- package/lib/util/StackedSetMap.js +144 -135
- package/lib/util/TrackingSet.js +35 -35
- package/lib/util/cachedMerge.js +35 -35
- package/lib/util/deterministicGrouping.js +251 -251
- package/lib/util/identifier.js +103 -103
- package/lib/util/objectToMap.js +16 -16
- package/lib/validateSchema.js +67 -67
- package/lib/wasm/UnsupportedWebAssemblyFeatureError.js +17 -17
- package/lib/wasm/WasmFinalizeExportsPlugin.js +1 -1
- package/lib/wasm/WebAssemblyGenerator.js +16 -2
- package/lib/wasm/WebAssemblyJavascriptGenerator.js +147 -133
- package/lib/wasm/WebAssemblyParser.js +174 -174
- package/lib/wasm/WebAssemblyUtils.js +59 -59
- package/lib/web/FetchCompileWasmTemplatePlugin.js +37 -37
- package/lib/web/JsonpExportMainTemplatePlugin.js +47 -47
- package/lib/web/JsonpHotUpdateChunkTemplatePlugin.js +39 -39
- package/lib/web/JsonpMainTemplate.runtime.js +65 -65
- package/lib/web/JsonpMainTemplatePlugin.js +1 -1
- package/lib/web/JsonpTemplatePlugin.js +23 -23
- package/lib/web/WebEnvironmentPlugin.js +18 -18
- package/lib/webpack.js +5 -0
- package/lib/webworker/WebWorkerChunkTemplatePlugin.js +35 -35
- package/lib/webworker/WebWorkerHotUpdateChunkTemplatePlugin.js +40 -40
- package/lib/webworker/WebWorkerMainTemplate.runtime.js +65 -65
- package/lib/webworker/WebWorkerMainTemplatePlugin.js +196 -196
- package/lib/webworker/WebWorkerTemplatePlugin.js +25 -25
- package/package.json +22 -13
- package/schemas/WebpackOptions.json +2062 -2036
- package/schemas/ajv.absolutePath.js +55 -55
- package/schemas/plugins/BannerPlugin.json +96 -96
- 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
- package/schemas/plugins/optimize/OccurrenceOrderChunkIdsPlugin.json +10 -0
- package/schemas/plugins/optimize/OccurrenceOrderModuleIdsPlugin.json +10 -0
@@ -1,850 +1,866 @@
|
|
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
|
-
const deterministicGrouping = require("../util/deterministicGrouping");
|
12
|
-
const contextify = require("../util/identifier").contextify;
|
13
|
-
|
14
|
-
/** @typedef {import("../Compiler")} Compiler */
|
15
|
-
/** @typedef {import("../Chunk")} Chunk */
|
16
|
-
/** @typedef {import("../Module")} Module */
|
17
|
-
/** @typedef {import("../util/deterministicGrouping").Options<Module>} DeterministicGroupingOptionsForModule */
|
18
|
-
/** @typedef {import("../util/deterministicGrouping").GroupedItems<Module>} DeterministicGroupingGroupedItemsForModule */
|
19
|
-
|
20
|
-
const deterministicGroupingForModules = /** @type {function(DeterministicGroupingOptionsForModule): DeterministicGroupingGroupedItemsForModule[]} */ (deterministicGrouping);
|
21
|
-
|
22
|
-
const hashFilename = name => {
|
23
|
-
return crypto
|
24
|
-
.createHash("md4")
|
25
|
-
.update(name)
|
26
|
-
.digest("hex")
|
27
|
-
.slice(0, 8);
|
28
|
-
};
|
29
|
-
|
30
|
-
const sortByIdentifier = (a, b) => {
|
31
|
-
if (a.identifier() > b.identifier()) return 1;
|
32
|
-
if (a.identifier() < b.identifier()) return -1;
|
33
|
-
return 0;
|
34
|
-
};
|
35
|
-
|
36
|
-
const getRequests = chunk => {
|
37
|
-
let requests = 0;
|
38
|
-
for (const chunkGroup of chunk.groupsIterable) {
|
39
|
-
requests = Math.max(requests, chunkGroup.chunks.length);
|
40
|
-
}
|
41
|
-
return requests;
|
42
|
-
};
|
43
|
-
|
44
|
-
const getModulesSize = modules => {
|
45
|
-
let sum = 0;
|
46
|
-
for (const m of modules) {
|
47
|
-
sum += m.size();
|
48
|
-
}
|
49
|
-
return sum;
|
50
|
-
};
|
51
|
-
|
52
|
-
/**
|
53
|
-
* @template T
|
54
|
-
* @param {Set<T>} a set
|
55
|
-
* @param {Set<T>} b other set
|
56
|
-
* @returns {boolean} true if at least one item of a is in b
|
57
|
-
*/
|
58
|
-
const isOverlap = (a, b) => {
|
59
|
-
for (const item of a) {
|
60
|
-
if (b.has(item)) return true;
|
61
|
-
}
|
62
|
-
return false;
|
63
|
-
};
|
64
|
-
|
65
|
-
const compareEntries = (a, b) => {
|
66
|
-
// 1. by priority
|
67
|
-
const diffPriority = a.cacheGroup.priority - b.cacheGroup.priority;
|
68
|
-
if (diffPriority) return diffPriority;
|
69
|
-
// 2. by number of chunks
|
70
|
-
const diffCount = a.chunks.size - b.chunks.size;
|
71
|
-
if (diffCount) return diffCount;
|
72
|
-
// 3. by size reduction
|
73
|
-
const aSizeReduce = a.size * (a.chunks.size - 1);
|
74
|
-
const bSizeReduce = b.size * (b.chunks.size - 1);
|
75
|
-
const diffSizeReduce = aSizeReduce - bSizeReduce;
|
76
|
-
if (diffSizeReduce) return diffSizeReduce;
|
77
|
-
// 4. by number of modules (to be able to compare by identifier)
|
78
|
-
const modulesA = a.modules;
|
79
|
-
const modulesB = b.modules;
|
80
|
-
const diff = modulesA.size - modulesB.size;
|
81
|
-
if (diff) return diff;
|
82
|
-
// 5. by module identifiers
|
83
|
-
modulesA.sort();
|
84
|
-
modulesB.sort();
|
85
|
-
const aI = modulesA[Symbol.iterator]();
|
86
|
-
const bI = modulesB[Symbol.iterator]();
|
87
|
-
// eslint-disable-next-line no-constant-condition
|
88
|
-
while (true) {
|
89
|
-
const aItem = aI.next();
|
90
|
-
const bItem = bI.next();
|
91
|
-
if (aItem.done) return 0;
|
92
|
-
const aModuleIdentifier = aItem.value.identifier();
|
93
|
-
const bModuleIdentifier = bItem.value.identifier();
|
94
|
-
if (aModuleIdentifier > bModuleIdentifier) return -1;
|
95
|
-
if (aModuleIdentifier < bModuleIdentifier) return 1;
|
96
|
-
}
|
97
|
-
};
|
98
|
-
|
99
|
-
const INITIAL_CHUNK_FILTER = chunk => chunk.canBeInitial();
|
100
|
-
const ASYNC_CHUNK_FILTER = chunk => !chunk.canBeInitial();
|
101
|
-
const ALL_CHUNK_FILTER = chunk => true;
|
102
|
-
|
103
|
-
module.exports = class SplitChunksPlugin {
|
104
|
-
constructor(options) {
|
105
|
-
this.options = SplitChunksPlugin.normalizeOptions(options);
|
106
|
-
}
|
107
|
-
|
108
|
-
static normalizeOptions(options = {}) {
|
109
|
-
return {
|
110
|
-
chunksFilter: SplitChunksPlugin.normalizeChunksFilter(
|
111
|
-
options.chunks || "all"
|
112
|
-
),
|
113
|
-
minSize: options.minSize || 0,
|
114
|
-
maxSize: options.maxSize || 0,
|
115
|
-
minChunks: options.minChunks || 1,
|
116
|
-
maxAsyncRequests: options.maxAsyncRequests || 1,
|
117
|
-
maxInitialRequests: options.maxInitialRequests || 1,
|
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
|
-
// Filenames and paths can't be too long otherwise an
|
158
|
-
// ENAMETOOLONG error is raised. If the generated name if too
|
159
|
-
// long, it is truncated and a hash is appended. The limit has
|
160
|
-
// been set to 100 to prevent `[name].[chunkhash].[ext]` from
|
161
|
-
// generating a 256+ character string.
|
162
|
-
if (name.length > 100) {
|
163
|
-
name =
|
164
|
-
name.slice(0, 100) + automaticNameDelimiter + hashFilename(name);
|
165
|
-
}
|
166
|
-
cacheEntry[cacheGroup] = name;
|
167
|
-
return name;
|
168
|
-
};
|
169
|
-
return fn;
|
170
|
-
}
|
171
|
-
if (typeof name === "string") {
|
172
|
-
const fn = () => {
|
173
|
-
return name;
|
174
|
-
};
|
175
|
-
return fn;
|
176
|
-
}
|
177
|
-
if (typeof name === "function") return name;
|
178
|
-
}
|
179
|
-
|
180
|
-
static normalizeChunksFilter(chunks) {
|
181
|
-
if (chunks === "initial") {
|
182
|
-
return INITIAL_CHUNK_FILTER;
|
183
|
-
}
|
184
|
-
if (chunks === "async") {
|
185
|
-
return ASYNC_CHUNK_FILTER;
|
186
|
-
}
|
187
|
-
if (chunks === "all") {
|
188
|
-
return ALL_CHUNK_FILTER;
|
189
|
-
}
|
190
|
-
if (typeof chunks === "function") return chunks;
|
191
|
-
}
|
192
|
-
|
193
|
-
static normalizeFallbackCacheGroup(
|
194
|
-
{
|
195
|
-
minSize = undefined,
|
196
|
-
maxSize = undefined,
|
197
|
-
automaticNameDelimiter = undefined
|
198
|
-
},
|
199
|
-
{
|
200
|
-
minSize: defaultMinSize = undefined,
|
201
|
-
maxSize: defaultMaxSize = undefined,
|
202
|
-
automaticNameDelimiter: defaultAutomaticNameDelimiter = undefined
|
203
|
-
}
|
204
|
-
) {
|
205
|
-
return {
|
206
|
-
minSize: typeof minSize === "number" ? minSize : defaultMinSize || 0,
|
207
|
-
maxSize: typeof maxSize === "number" ? maxSize : defaultMaxSize || 0,
|
208
|
-
automaticNameDelimiter:
|
209
|
-
automaticNameDelimiter || defaultAutomaticNameDelimiter || "~"
|
210
|
-
};
|
211
|
-
}
|
212
|
-
|
213
|
-
static normalizeCacheGroups({ cacheGroups, automaticNameDelimiter }) {
|
214
|
-
if (typeof cacheGroups === "function") {
|
215
|
-
// TODO webpack 5 remove this
|
216
|
-
if (cacheGroups.length !== 1) {
|
217
|
-
return module => cacheGroups(module, module.getChunks());
|
218
|
-
}
|
219
|
-
return cacheGroups;
|
220
|
-
}
|
221
|
-
if (cacheGroups && typeof cacheGroups === "object") {
|
222
|
-
const fn = module => {
|
223
|
-
let results;
|
224
|
-
for (const key of Object.keys(cacheGroups)) {
|
225
|
-
let option = cacheGroups[key];
|
226
|
-
if (option === false) continue;
|
227
|
-
if (option instanceof RegExp || typeof option === "string") {
|
228
|
-
option = {
|
229
|
-
test: option
|
230
|
-
};
|
231
|
-
}
|
232
|
-
if (typeof option === "function") {
|
233
|
-
let result = option(module);
|
234
|
-
if (result) {
|
235
|
-
if (results === undefined) results = [];
|
236
|
-
for (const r of Array.isArray(result) ? result : [result]) {
|
237
|
-
const result = Object.assign({ key }, r);
|
238
|
-
if (result.name) result.getName = () => result.name;
|
239
|
-
if (result.chunks) {
|
240
|
-
result.chunksFilter = SplitChunksPlugin.normalizeChunksFilter(
|
241
|
-
result.chunks
|
242
|
-
);
|
243
|
-
}
|
244
|
-
results.push(result);
|
245
|
-
}
|
246
|
-
}
|
247
|
-
} else if (SplitChunksPlugin.checkTest(option.test, module)) {
|
248
|
-
if (results === undefined) results = [];
|
249
|
-
results.push({
|
250
|
-
key: key,
|
251
|
-
priority: option.priority,
|
252
|
-
getName:
|
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
|
-
|
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
|
-
const
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
}
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
array.
|
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
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
* @
|
436
|
-
* @property {
|
437
|
-
* @property {
|
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
|
-
|
497
|
-
|
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
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
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
|
-
if (
|
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
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
}
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
module.
|
737
|
-
}
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
}
|
754
|
-
}
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
newPart =
|
842
|
-
chunk.
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
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
|
+
const deterministicGrouping = require("../util/deterministicGrouping");
|
12
|
+
const contextify = require("../util/identifier").contextify;
|
13
|
+
|
14
|
+
/** @typedef {import("../Compiler")} Compiler */
|
15
|
+
/** @typedef {import("../Chunk")} Chunk */
|
16
|
+
/** @typedef {import("../Module")} Module */
|
17
|
+
/** @typedef {import("../util/deterministicGrouping").Options<Module>} DeterministicGroupingOptionsForModule */
|
18
|
+
/** @typedef {import("../util/deterministicGrouping").GroupedItems<Module>} DeterministicGroupingGroupedItemsForModule */
|
19
|
+
|
20
|
+
const deterministicGroupingForModules = /** @type {function(DeterministicGroupingOptionsForModule): DeterministicGroupingGroupedItemsForModule[]} */ (deterministicGrouping);
|
21
|
+
|
22
|
+
const hashFilename = name => {
|
23
|
+
return crypto
|
24
|
+
.createHash("md4")
|
25
|
+
.update(name)
|
26
|
+
.digest("hex")
|
27
|
+
.slice(0, 8);
|
28
|
+
};
|
29
|
+
|
30
|
+
const sortByIdentifier = (a, b) => {
|
31
|
+
if (a.identifier() > b.identifier()) return 1;
|
32
|
+
if (a.identifier() < b.identifier()) return -1;
|
33
|
+
return 0;
|
34
|
+
};
|
35
|
+
|
36
|
+
const getRequests = chunk => {
|
37
|
+
let requests = 0;
|
38
|
+
for (const chunkGroup of chunk.groupsIterable) {
|
39
|
+
requests = Math.max(requests, chunkGroup.chunks.length);
|
40
|
+
}
|
41
|
+
return requests;
|
42
|
+
};
|
43
|
+
|
44
|
+
const getModulesSize = modules => {
|
45
|
+
let sum = 0;
|
46
|
+
for (const m of modules) {
|
47
|
+
sum += m.size();
|
48
|
+
}
|
49
|
+
return sum;
|
50
|
+
};
|
51
|
+
|
52
|
+
/**
|
53
|
+
* @template T
|
54
|
+
* @param {Set<T>} a set
|
55
|
+
* @param {Set<T>} b other set
|
56
|
+
* @returns {boolean} true if at least one item of a is in b
|
57
|
+
*/
|
58
|
+
const isOverlap = (a, b) => {
|
59
|
+
for (const item of a) {
|
60
|
+
if (b.has(item)) return true;
|
61
|
+
}
|
62
|
+
return false;
|
63
|
+
};
|
64
|
+
|
65
|
+
const compareEntries = (a, b) => {
|
66
|
+
// 1. by priority
|
67
|
+
const diffPriority = a.cacheGroup.priority - b.cacheGroup.priority;
|
68
|
+
if (diffPriority) return diffPriority;
|
69
|
+
// 2. by number of chunks
|
70
|
+
const diffCount = a.chunks.size - b.chunks.size;
|
71
|
+
if (diffCount) return diffCount;
|
72
|
+
// 3. by size reduction
|
73
|
+
const aSizeReduce = a.size * (a.chunks.size - 1);
|
74
|
+
const bSizeReduce = b.size * (b.chunks.size - 1);
|
75
|
+
const diffSizeReduce = aSizeReduce - bSizeReduce;
|
76
|
+
if (diffSizeReduce) return diffSizeReduce;
|
77
|
+
// 4. by number of modules (to be able to compare by identifier)
|
78
|
+
const modulesA = a.modules;
|
79
|
+
const modulesB = b.modules;
|
80
|
+
const diff = modulesA.size - modulesB.size;
|
81
|
+
if (diff) return diff;
|
82
|
+
// 5. by module identifiers
|
83
|
+
modulesA.sort();
|
84
|
+
modulesB.sort();
|
85
|
+
const aI = modulesA[Symbol.iterator]();
|
86
|
+
const bI = modulesB[Symbol.iterator]();
|
87
|
+
// eslint-disable-next-line no-constant-condition
|
88
|
+
while (true) {
|
89
|
+
const aItem = aI.next();
|
90
|
+
const bItem = bI.next();
|
91
|
+
if (aItem.done) return 0;
|
92
|
+
const aModuleIdentifier = aItem.value.identifier();
|
93
|
+
const bModuleIdentifier = bItem.value.identifier();
|
94
|
+
if (aModuleIdentifier > bModuleIdentifier) return -1;
|
95
|
+
if (aModuleIdentifier < bModuleIdentifier) return 1;
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
const INITIAL_CHUNK_FILTER = chunk => chunk.canBeInitial();
|
100
|
+
const ASYNC_CHUNK_FILTER = chunk => !chunk.canBeInitial();
|
101
|
+
const ALL_CHUNK_FILTER = chunk => true;
|
102
|
+
|
103
|
+
module.exports = class SplitChunksPlugin {
|
104
|
+
constructor(options) {
|
105
|
+
this.options = SplitChunksPlugin.normalizeOptions(options);
|
106
|
+
}
|
107
|
+
|
108
|
+
static normalizeOptions(options = {}) {
|
109
|
+
return {
|
110
|
+
chunksFilter: SplitChunksPlugin.normalizeChunksFilter(
|
111
|
+
options.chunks || "all"
|
112
|
+
),
|
113
|
+
minSize: options.minSize || 0,
|
114
|
+
maxSize: options.maxSize || 0,
|
115
|
+
minChunks: options.minChunks || 1,
|
116
|
+
maxAsyncRequests: options.maxAsyncRequests || 1,
|
117
|
+
maxInitialRequests: options.maxInitialRequests || 1,
|
118
|
+
hidePathInfo: options.hidePathInfo || false,
|
119
|
+
filename: options.filename || undefined,
|
120
|
+
getCacheGroups: SplitChunksPlugin.normalizeCacheGroups({
|
121
|
+
cacheGroups: options.cacheGroups,
|
122
|
+
name: options.name,
|
123
|
+
automaticNameDelimiter: options.automaticNameDelimiter
|
124
|
+
}),
|
125
|
+
automaticNameDelimiter: options.automaticNameDelimiter,
|
126
|
+
fallbackCacheGroup: SplitChunksPlugin.normalizeFallbackCacheGroup(
|
127
|
+
options.fallbackCacheGroup || {},
|
128
|
+
options
|
129
|
+
)
|
130
|
+
};
|
131
|
+
}
|
132
|
+
|
133
|
+
static normalizeName({ name, automaticNameDelimiter, automaticNamePrefix }) {
|
134
|
+
if (name === true) {
|
135
|
+
/** @type {WeakMap<Chunk[], Record<string, string>>} */
|
136
|
+
const cache = new WeakMap();
|
137
|
+
const fn = (module, chunks, cacheGroup) => {
|
138
|
+
let cacheEntry = cache.get(chunks);
|
139
|
+
if (cacheEntry === undefined) {
|
140
|
+
cacheEntry = {};
|
141
|
+
cache.set(chunks, cacheEntry);
|
142
|
+
} else if (cacheGroup in cacheEntry) {
|
143
|
+
return cacheEntry[cacheGroup];
|
144
|
+
}
|
145
|
+
const names = chunks.map(c => c.name);
|
146
|
+
if (!names.every(Boolean)) {
|
147
|
+
cacheEntry[cacheGroup] = undefined;
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
names.sort();
|
151
|
+
const prefix =
|
152
|
+
typeof automaticNamePrefix === "string"
|
153
|
+
? automaticNamePrefix
|
154
|
+
: cacheGroup;
|
155
|
+
const namePrefix = prefix ? prefix + automaticNameDelimiter : "";
|
156
|
+
let name = namePrefix + names.join(automaticNameDelimiter);
|
157
|
+
// Filenames and paths can't be too long otherwise an
|
158
|
+
// ENAMETOOLONG error is raised. If the generated name if too
|
159
|
+
// long, it is truncated and a hash is appended. The limit has
|
160
|
+
// been set to 100 to prevent `[name].[chunkhash].[ext]` from
|
161
|
+
// generating a 256+ character string.
|
162
|
+
if (name.length > 100) {
|
163
|
+
name =
|
164
|
+
name.slice(0, 100) + automaticNameDelimiter + hashFilename(name);
|
165
|
+
}
|
166
|
+
cacheEntry[cacheGroup] = name;
|
167
|
+
return name;
|
168
|
+
};
|
169
|
+
return fn;
|
170
|
+
}
|
171
|
+
if (typeof name === "string") {
|
172
|
+
const fn = () => {
|
173
|
+
return name;
|
174
|
+
};
|
175
|
+
return fn;
|
176
|
+
}
|
177
|
+
if (typeof name === "function") return name;
|
178
|
+
}
|
179
|
+
|
180
|
+
static normalizeChunksFilter(chunks) {
|
181
|
+
if (chunks === "initial") {
|
182
|
+
return INITIAL_CHUNK_FILTER;
|
183
|
+
}
|
184
|
+
if (chunks === "async") {
|
185
|
+
return ASYNC_CHUNK_FILTER;
|
186
|
+
}
|
187
|
+
if (chunks === "all") {
|
188
|
+
return ALL_CHUNK_FILTER;
|
189
|
+
}
|
190
|
+
if (typeof chunks === "function") return chunks;
|
191
|
+
}
|
192
|
+
|
193
|
+
static normalizeFallbackCacheGroup(
|
194
|
+
{
|
195
|
+
minSize = undefined,
|
196
|
+
maxSize = undefined,
|
197
|
+
automaticNameDelimiter = undefined
|
198
|
+
},
|
199
|
+
{
|
200
|
+
minSize: defaultMinSize = undefined,
|
201
|
+
maxSize: defaultMaxSize = undefined,
|
202
|
+
automaticNameDelimiter: defaultAutomaticNameDelimiter = undefined
|
203
|
+
}
|
204
|
+
) {
|
205
|
+
return {
|
206
|
+
minSize: typeof minSize === "number" ? minSize : defaultMinSize || 0,
|
207
|
+
maxSize: typeof maxSize === "number" ? maxSize : defaultMaxSize || 0,
|
208
|
+
automaticNameDelimiter:
|
209
|
+
automaticNameDelimiter || defaultAutomaticNameDelimiter || "~"
|
210
|
+
};
|
211
|
+
}
|
212
|
+
|
213
|
+
static normalizeCacheGroups({ cacheGroups, name, automaticNameDelimiter }) {
|
214
|
+
if (typeof cacheGroups === "function") {
|
215
|
+
// TODO webpack 5 remove this
|
216
|
+
if (cacheGroups.length !== 1) {
|
217
|
+
return module => cacheGroups(module, module.getChunks());
|
218
|
+
}
|
219
|
+
return cacheGroups;
|
220
|
+
}
|
221
|
+
if (cacheGroups && typeof cacheGroups === "object") {
|
222
|
+
const fn = module => {
|
223
|
+
let results;
|
224
|
+
for (const key of Object.keys(cacheGroups)) {
|
225
|
+
let option = cacheGroups[key];
|
226
|
+
if (option === false) continue;
|
227
|
+
if (option instanceof RegExp || typeof option === "string") {
|
228
|
+
option = {
|
229
|
+
test: option
|
230
|
+
};
|
231
|
+
}
|
232
|
+
if (typeof option === "function") {
|
233
|
+
let result = option(module);
|
234
|
+
if (result) {
|
235
|
+
if (results === undefined) results = [];
|
236
|
+
for (const r of Array.isArray(result) ? result : [result]) {
|
237
|
+
const result = Object.assign({ key }, r);
|
238
|
+
if (result.name) result.getName = () => result.name;
|
239
|
+
if (result.chunks) {
|
240
|
+
result.chunksFilter = SplitChunksPlugin.normalizeChunksFilter(
|
241
|
+
result.chunks
|
242
|
+
);
|
243
|
+
}
|
244
|
+
results.push(result);
|
245
|
+
}
|
246
|
+
}
|
247
|
+
} else if (SplitChunksPlugin.checkTest(option.test, module)) {
|
248
|
+
if (results === undefined) results = [];
|
249
|
+
results.push({
|
250
|
+
key: key,
|
251
|
+
priority: option.priority,
|
252
|
+
getName:
|
253
|
+
SplitChunksPlugin.normalizeName({
|
254
|
+
name: option.name || name,
|
255
|
+
automaticNameDelimiter:
|
256
|
+
typeof option.automaticNameDelimiter === "string"
|
257
|
+
? option.automaticNameDelimiter
|
258
|
+
: automaticNameDelimiter,
|
259
|
+
automaticNamePrefix: option.automaticNamePrefix
|
260
|
+
}) || (() => {}),
|
261
|
+
chunksFilter: SplitChunksPlugin.normalizeChunksFilter(
|
262
|
+
option.chunks
|
263
|
+
),
|
264
|
+
enforce: option.enforce,
|
265
|
+
minSize: option.minSize,
|
266
|
+
maxSize: option.maxSize,
|
267
|
+
minChunks: option.minChunks,
|
268
|
+
maxAsyncRequests: option.maxAsyncRequests,
|
269
|
+
maxInitialRequests: option.maxInitialRequests,
|
270
|
+
filename: option.filename,
|
271
|
+
reuseExistingChunk: option.reuseExistingChunk
|
272
|
+
});
|
273
|
+
}
|
274
|
+
}
|
275
|
+
return results;
|
276
|
+
};
|
277
|
+
return fn;
|
278
|
+
}
|
279
|
+
const fn = () => {};
|
280
|
+
return fn;
|
281
|
+
}
|
282
|
+
|
283
|
+
static checkTest(test, module) {
|
284
|
+
if (test === undefined) return true;
|
285
|
+
if (typeof test === "function") {
|
286
|
+
if (test.length !== 1) {
|
287
|
+
return test(module, module.getChunks());
|
288
|
+
}
|
289
|
+
return test(module);
|
290
|
+
}
|
291
|
+
if (typeof test === "boolean") return test;
|
292
|
+
if (typeof test === "string") {
|
293
|
+
if (
|
294
|
+
module.nameForCondition &&
|
295
|
+
module.nameForCondition().startsWith(test)
|
296
|
+
) {
|
297
|
+
return true;
|
298
|
+
}
|
299
|
+
for (const chunk of module.chunksIterable) {
|
300
|
+
if (chunk.name && chunk.name.startsWith(test)) {
|
301
|
+
return true;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
return false;
|
305
|
+
}
|
306
|
+
if (test instanceof RegExp) {
|
307
|
+
if (module.nameForCondition && test.test(module.nameForCondition())) {
|
308
|
+
return true;
|
309
|
+
}
|
310
|
+
for (const chunk of module.chunksIterable) {
|
311
|
+
if (chunk.name && test.test(chunk.name)) {
|
312
|
+
return true;
|
313
|
+
}
|
314
|
+
}
|
315
|
+
return false;
|
316
|
+
}
|
317
|
+
return false;
|
318
|
+
}
|
319
|
+
|
320
|
+
/**
|
321
|
+
* @param {Compiler} compiler webpack compiler
|
322
|
+
* @returns {void}
|
323
|
+
*/
|
324
|
+
apply(compiler) {
|
325
|
+
compiler.hooks.thisCompilation.tap("SplitChunksPlugin", compilation => {
|
326
|
+
let alreadyOptimized = false;
|
327
|
+
compilation.hooks.unseal.tap("SplitChunksPlugin", () => {
|
328
|
+
alreadyOptimized = false;
|
329
|
+
});
|
330
|
+
compilation.hooks.optimizeChunksAdvanced.tap(
|
331
|
+
"SplitChunksPlugin",
|
332
|
+
chunks => {
|
333
|
+
if (alreadyOptimized) return;
|
334
|
+
alreadyOptimized = true;
|
335
|
+
// Give each selected chunk an index (to create strings from chunks)
|
336
|
+
const indexMap = new Map();
|
337
|
+
let index = 1;
|
338
|
+
for (const chunk of chunks) {
|
339
|
+
indexMap.set(chunk, index++);
|
340
|
+
}
|
341
|
+
const getKey = chunks => {
|
342
|
+
return Array.from(chunks, c => indexMap.get(c))
|
343
|
+
.sort()
|
344
|
+
.join();
|
345
|
+
};
|
346
|
+
/** @type {Map<string, Set<Chunk>>} */
|
347
|
+
const chunkSetsInGraph = new Map();
|
348
|
+
for (const module of compilation.modules) {
|
349
|
+
const chunksKey = getKey(module.chunksIterable);
|
350
|
+
if (!chunkSetsInGraph.has(chunksKey)) {
|
351
|
+
chunkSetsInGraph.set(chunksKey, new Set(module.chunksIterable));
|
352
|
+
}
|
353
|
+
}
|
354
|
+
|
355
|
+
// group these set of chunks by count
|
356
|
+
// to allow to check less sets via isSubset
|
357
|
+
// (only smaller sets can be subset)
|
358
|
+
/** @type {Map<number, Array<Set<Chunk>>>} */
|
359
|
+
const chunkSetsByCount = new Map();
|
360
|
+
for (const chunksSet of chunkSetsInGraph.values()) {
|
361
|
+
const count = chunksSet.size;
|
362
|
+
let array = chunkSetsByCount.get(count);
|
363
|
+
if (array === undefined) {
|
364
|
+
array = [];
|
365
|
+
chunkSetsByCount.set(count, array);
|
366
|
+
}
|
367
|
+
array.push(chunksSet);
|
368
|
+
}
|
369
|
+
|
370
|
+
// Create a list of possible combinations
|
371
|
+
const combinationsCache = new Map(); // Map<string, Set<Chunk>[]>
|
372
|
+
|
373
|
+
const getCombinations = key => {
|
374
|
+
const chunksSet = chunkSetsInGraph.get(key);
|
375
|
+
var array = [chunksSet];
|
376
|
+
if (chunksSet.size > 1) {
|
377
|
+
for (const [count, setArray] of chunkSetsByCount) {
|
378
|
+
// "equal" is not needed because they would have been merge in the first step
|
379
|
+
if (count < chunksSet.size) {
|
380
|
+
for (const set of setArray) {
|
381
|
+
if (isSubset(chunksSet, set)) {
|
382
|
+
array.push(set);
|
383
|
+
}
|
384
|
+
}
|
385
|
+
}
|
386
|
+
}
|
387
|
+
}
|
388
|
+
return array;
|
389
|
+
};
|
390
|
+
|
391
|
+
/**
|
392
|
+
* @typedef {Object} SelectedChunksResult
|
393
|
+
* @property {Chunk[]} chunks the list of chunks
|
394
|
+
* @property {string} key a key of the list
|
395
|
+
*/
|
396
|
+
|
397
|
+
/**
|
398
|
+
* @typedef {function(Chunk): boolean} ChunkFilterFunction
|
399
|
+
*/
|
400
|
+
|
401
|
+
/** @type {WeakMap<Set<Chunk>, WeakMap<ChunkFilterFunction, SelectedChunksResult>>} */
|
402
|
+
const selectedChunksCacheByChunksSet = new WeakMap();
|
403
|
+
|
404
|
+
/**
|
405
|
+
* get list and key by applying the filter function to the list
|
406
|
+
* It is cached for performance reasons
|
407
|
+
* @param {Set<Chunk>} chunks list of chunks
|
408
|
+
* @param {ChunkFilterFunction} chunkFilter filter function for chunks
|
409
|
+
* @returns {SelectedChunksResult} list and key
|
410
|
+
*/
|
411
|
+
const getSelectedChunks = (chunks, chunkFilter) => {
|
412
|
+
let entry = selectedChunksCacheByChunksSet.get(chunks);
|
413
|
+
if (entry === undefined) {
|
414
|
+
entry = new WeakMap();
|
415
|
+
selectedChunksCacheByChunksSet.set(chunks, entry);
|
416
|
+
}
|
417
|
+
/** @type {SelectedChunksResult} */
|
418
|
+
let entry2 = entry.get(chunkFilter);
|
419
|
+
if (entry2 === undefined) {
|
420
|
+
/** @type {Chunk[]} */
|
421
|
+
const selectedChunks = [];
|
422
|
+
for (const chunk of chunks) {
|
423
|
+
if (chunkFilter(chunk)) selectedChunks.push(chunk);
|
424
|
+
}
|
425
|
+
entry2 = {
|
426
|
+
chunks: selectedChunks,
|
427
|
+
key: getKey(selectedChunks)
|
428
|
+
};
|
429
|
+
entry.set(chunkFilter, entry2);
|
430
|
+
}
|
431
|
+
return entry2;
|
432
|
+
};
|
433
|
+
|
434
|
+
/**
|
435
|
+
* @typedef {Object} ChunksInfoItem
|
436
|
+
* @property {SortableSet} modules
|
437
|
+
* @property {TODO} cacheGroup
|
438
|
+
* @property {string} name
|
439
|
+
* @property {number} size
|
440
|
+
* @property {Set<Chunk>} chunks
|
441
|
+
* @property {Set<Chunk>} reuseableChunks
|
442
|
+
* @property {Set<string>} chunksKeys
|
443
|
+
*/
|
444
|
+
|
445
|
+
// Map a list of chunks to a list of modules
|
446
|
+
// For the key the chunk "index" is used, the value is a SortableSet of modules
|
447
|
+
/** @type {Map<string, ChunksInfoItem>} */
|
448
|
+
const chunksInfoMap = new Map();
|
449
|
+
|
450
|
+
/**
|
451
|
+
* @param {TODO} cacheGroup the current cache group
|
452
|
+
* @param {Chunk[]} selectedChunks chunks selected for this module
|
453
|
+
* @param {string} selectedChunksKey a key of selectedChunks
|
454
|
+
* @param {Module} module the current module
|
455
|
+
* @returns {void}
|
456
|
+
*/
|
457
|
+
const addModuleToChunksInfoMap = (
|
458
|
+
cacheGroup,
|
459
|
+
selectedChunks,
|
460
|
+
selectedChunksKey,
|
461
|
+
module
|
462
|
+
) => {
|
463
|
+
// Break if minimum number of chunks is not reached
|
464
|
+
if (selectedChunks.length < cacheGroup.minChunks) return;
|
465
|
+
// Determine name for split chunk
|
466
|
+
const name = cacheGroup.getName(
|
467
|
+
module,
|
468
|
+
selectedChunks,
|
469
|
+
cacheGroup.key
|
470
|
+
);
|
471
|
+
// Create key for maps
|
472
|
+
// When it has a name we use the name as key
|
473
|
+
// Elsewise we create the key from chunks and cache group key
|
474
|
+
// This automatically merges equal names
|
475
|
+
const key =
|
476
|
+
(name && `name:${name}`) ||
|
477
|
+
`chunks:${selectedChunksKey} key:${cacheGroup.key}`;
|
478
|
+
// Add module to maps
|
479
|
+
let info = chunksInfoMap.get(key);
|
480
|
+
if (info === undefined) {
|
481
|
+
chunksInfoMap.set(
|
482
|
+
key,
|
483
|
+
(info = {
|
484
|
+
modules: new SortableSet(undefined, sortByIdentifier),
|
485
|
+
cacheGroup,
|
486
|
+
name,
|
487
|
+
size: 0,
|
488
|
+
chunks: new Set(),
|
489
|
+
reuseableChunks: new Set(),
|
490
|
+
chunksKeys: new Set()
|
491
|
+
})
|
492
|
+
);
|
493
|
+
} else {
|
494
|
+
if (info.cacheGroup !== cacheGroup) {
|
495
|
+
if (info.cacheGroup.priority < cacheGroup.priority) {
|
496
|
+
info.cacheGroup = cacheGroup;
|
497
|
+
}
|
498
|
+
}
|
499
|
+
}
|
500
|
+
info.modules.add(module);
|
501
|
+
info.size += module.size();
|
502
|
+
if (!info.chunksKeys.has(selectedChunksKey)) {
|
503
|
+
info.chunksKeys.add(selectedChunksKey);
|
504
|
+
for (const chunk of selectedChunks) {
|
505
|
+
info.chunks.add(chunk);
|
506
|
+
}
|
507
|
+
}
|
508
|
+
};
|
509
|
+
|
510
|
+
// Walk through all modules
|
511
|
+
for (const module of compilation.modules) {
|
512
|
+
// Get cache group
|
513
|
+
let cacheGroups = this.options.getCacheGroups(module);
|
514
|
+
if (!Array.isArray(cacheGroups) || cacheGroups.length === 0) {
|
515
|
+
continue;
|
516
|
+
}
|
517
|
+
|
518
|
+
// Prepare some values
|
519
|
+
const chunksKey = getKey(module.chunksIterable);
|
520
|
+
let combs = combinationsCache.get(chunksKey);
|
521
|
+
if (combs === undefined) {
|
522
|
+
combs = getCombinations(chunksKey);
|
523
|
+
combinationsCache.set(chunksKey, combs);
|
524
|
+
}
|
525
|
+
|
526
|
+
for (const cacheGroupSource of cacheGroups) {
|
527
|
+
const cacheGroup = {
|
528
|
+
key: cacheGroupSource.key,
|
529
|
+
priority: cacheGroupSource.priority || 0,
|
530
|
+
chunksFilter:
|
531
|
+
cacheGroupSource.chunksFilter || this.options.chunksFilter,
|
532
|
+
minSize:
|
533
|
+
cacheGroupSource.minSize !== undefined
|
534
|
+
? cacheGroupSource.minSize
|
535
|
+
: cacheGroupSource.enforce
|
536
|
+
? 0
|
537
|
+
: this.options.minSize,
|
538
|
+
maxSize:
|
539
|
+
cacheGroupSource.maxSize !== undefined
|
540
|
+
? cacheGroupSource.maxSize
|
541
|
+
: cacheGroupSource.enforce
|
542
|
+
? 0
|
543
|
+
: this.options.maxSize,
|
544
|
+
minChunks:
|
545
|
+
cacheGroupSource.minChunks !== undefined
|
546
|
+
? cacheGroupSource.minChunks
|
547
|
+
: cacheGroupSource.enforce
|
548
|
+
? 1
|
549
|
+
: this.options.minChunks,
|
550
|
+
maxAsyncRequests:
|
551
|
+
cacheGroupSource.maxAsyncRequests !== undefined
|
552
|
+
? cacheGroupSource.maxAsyncRequests
|
553
|
+
: cacheGroupSource.enforce
|
554
|
+
? Infinity
|
555
|
+
: this.options.maxAsyncRequests,
|
556
|
+
maxInitialRequests:
|
557
|
+
cacheGroupSource.maxInitialRequests !== undefined
|
558
|
+
? cacheGroupSource.maxInitialRequests
|
559
|
+
: cacheGroupSource.enforce
|
560
|
+
? Infinity
|
561
|
+
: this.options.maxInitialRequests,
|
562
|
+
getName:
|
563
|
+
cacheGroupSource.getName !== undefined
|
564
|
+
? cacheGroupSource.getName
|
565
|
+
: this.options.getName,
|
566
|
+
filename:
|
567
|
+
cacheGroupSource.filename !== undefined
|
568
|
+
? cacheGroupSource.filename
|
569
|
+
: this.options.filename,
|
570
|
+
automaticNameDelimiter:
|
571
|
+
cacheGroupSource.automaticNameDelimiter !== undefined
|
572
|
+
? cacheGroupSource.automaticNameDelimiter
|
573
|
+
: this.options.automaticNameDelimiter,
|
574
|
+
reuseExistingChunk: cacheGroupSource.reuseExistingChunk
|
575
|
+
};
|
576
|
+
// For all combination of chunk selection
|
577
|
+
for (const chunkCombination of combs) {
|
578
|
+
// Break if minimum number of chunks is not reached
|
579
|
+
if (chunkCombination.size < cacheGroup.minChunks) continue;
|
580
|
+
// Select chunks by configuration
|
581
|
+
const {
|
582
|
+
chunks: selectedChunks,
|
583
|
+
key: selectedChunksKey
|
584
|
+
} = getSelectedChunks(
|
585
|
+
chunkCombination,
|
586
|
+
cacheGroup.chunksFilter
|
587
|
+
);
|
588
|
+
|
589
|
+
addModuleToChunksInfoMap(
|
590
|
+
cacheGroup,
|
591
|
+
selectedChunks,
|
592
|
+
selectedChunksKey,
|
593
|
+
module
|
594
|
+
);
|
595
|
+
}
|
596
|
+
}
|
597
|
+
}
|
598
|
+
|
599
|
+
/** @type {Map<Chunk, {minSize: number, maxSize: number, automaticNameDelimiter: string}>} */
|
600
|
+
const maxSizeQueueMap = new Map();
|
601
|
+
|
602
|
+
while (chunksInfoMap.size > 0) {
|
603
|
+
// Find best matching entry
|
604
|
+
let bestEntryKey;
|
605
|
+
let bestEntry;
|
606
|
+
for (const pair of chunksInfoMap) {
|
607
|
+
const key = pair[0];
|
608
|
+
const info = pair[1];
|
609
|
+
if (info.size >= info.cacheGroup.minSize) {
|
610
|
+
if (bestEntry === undefined) {
|
611
|
+
bestEntry = info;
|
612
|
+
bestEntryKey = key;
|
613
|
+
} else if (compareEntries(bestEntry, info) < 0) {
|
614
|
+
bestEntry = info;
|
615
|
+
bestEntryKey = key;
|
616
|
+
}
|
617
|
+
}
|
618
|
+
}
|
619
|
+
|
620
|
+
// No suitable item left
|
621
|
+
if (bestEntry === undefined) break;
|
622
|
+
|
623
|
+
const item = bestEntry;
|
624
|
+
chunksInfoMap.delete(bestEntryKey);
|
625
|
+
|
626
|
+
let chunkName = item.name;
|
627
|
+
// Variable for the new chunk (lazy created)
|
628
|
+
/** @type {Chunk} */
|
629
|
+
let newChunk;
|
630
|
+
// When no chunk name, check if we can reuse a chunk instead of creating a new one
|
631
|
+
let isReused = false;
|
632
|
+
if (item.cacheGroup.reuseExistingChunk) {
|
633
|
+
outer: for (const chunk of item.chunks) {
|
634
|
+
if (chunk.getNumberOfModules() !== item.modules.size) continue;
|
635
|
+
if (chunk.hasEntryModule()) continue;
|
636
|
+
for (const module of item.modules) {
|
637
|
+
if (!chunk.containsModule(module)) continue outer;
|
638
|
+
}
|
639
|
+
if (!newChunk || !newChunk.name) {
|
640
|
+
newChunk = chunk;
|
641
|
+
} else if (
|
642
|
+
chunk.name &&
|
643
|
+
chunk.name.length < newChunk.name.length
|
644
|
+
) {
|
645
|
+
newChunk = chunk;
|
646
|
+
} else if (
|
647
|
+
chunk.name &&
|
648
|
+
chunk.name.length === newChunk.name.length &&
|
649
|
+
chunk.name < newChunk.name
|
650
|
+
) {
|
651
|
+
newChunk = chunk;
|
652
|
+
}
|
653
|
+
chunkName = undefined;
|
654
|
+
isReused = true;
|
655
|
+
}
|
656
|
+
}
|
657
|
+
// Check if maxRequests condition can be fulfilled
|
658
|
+
|
659
|
+
const usedChunks = Array.from(item.chunks).filter(chunk => {
|
660
|
+
// skip if we address ourself
|
661
|
+
return (
|
662
|
+
(!chunkName || chunk.name !== chunkName) && chunk !== newChunk
|
663
|
+
);
|
664
|
+
});
|
665
|
+
|
666
|
+
// Skip when no chunk selected
|
667
|
+
if (usedChunks.length === 0) continue;
|
668
|
+
|
669
|
+
const chunkInLimit = usedChunks.filter(chunk => {
|
670
|
+
// respect max requests when not enforced
|
671
|
+
const maxRequests = chunk.isOnlyInitial()
|
672
|
+
? item.cacheGroup.maxInitialRequests
|
673
|
+
: chunk.canBeInitial()
|
674
|
+
? Math.min(
|
675
|
+
item.cacheGroup.maxInitialRequests,
|
676
|
+
item.cacheGroup.maxAsyncRequests
|
677
|
+
)
|
678
|
+
: item.cacheGroup.maxAsyncRequests;
|
679
|
+
return !isFinite(maxRequests) || getRequests(chunk) < maxRequests;
|
680
|
+
});
|
681
|
+
|
682
|
+
if (chunkInLimit.length < usedChunks.length) {
|
683
|
+
for (const module of item.modules) {
|
684
|
+
addModuleToChunksInfoMap(
|
685
|
+
item.cacheGroup,
|
686
|
+
chunkInLimit,
|
687
|
+
getKey(chunkInLimit),
|
688
|
+
module
|
689
|
+
);
|
690
|
+
}
|
691
|
+
continue;
|
692
|
+
}
|
693
|
+
|
694
|
+
// Create the new chunk if not reusing one
|
695
|
+
if (!isReused) {
|
696
|
+
newChunk = compilation.addChunk(chunkName);
|
697
|
+
}
|
698
|
+
// Walk through all chunks
|
699
|
+
for (const chunk of usedChunks) {
|
700
|
+
// Add graph connections for splitted chunk
|
701
|
+
chunk.split(newChunk);
|
702
|
+
}
|
703
|
+
|
704
|
+
// Add a note to the chunk
|
705
|
+
newChunk.chunkReason = isReused
|
706
|
+
? "reused as split chunk"
|
707
|
+
: "split chunk";
|
708
|
+
if (item.cacheGroup.key) {
|
709
|
+
newChunk.chunkReason += ` (cache group: ${item.cacheGroup.key})`;
|
710
|
+
}
|
711
|
+
if (chunkName) {
|
712
|
+
newChunk.chunkReason += ` (name: ${chunkName})`;
|
713
|
+
// If the chosen name is already an entry point we remove the entry point
|
714
|
+
const entrypoint = compilation.entrypoints.get(chunkName);
|
715
|
+
if (entrypoint) {
|
716
|
+
compilation.entrypoints.delete(chunkName);
|
717
|
+
entrypoint.remove();
|
718
|
+
newChunk.entryModule = undefined;
|
719
|
+
}
|
720
|
+
}
|
721
|
+
if (item.cacheGroup.filename) {
|
722
|
+
if (!newChunk.isOnlyInitial()) {
|
723
|
+
throw new Error(
|
724
|
+
"SplitChunksPlugin: You are trying to set a filename for a chunk which is (also) loaded on demand. " +
|
725
|
+
"The runtime can only handle loading of chunks which match the chunkFilename schema. " +
|
726
|
+
"Using a custom filename would fail at runtime. " +
|
727
|
+
`(cache group: ${item.cacheGroup.key})`
|
728
|
+
);
|
729
|
+
}
|
730
|
+
newChunk.filenameTemplate = item.cacheGroup.filename;
|
731
|
+
}
|
732
|
+
if (!isReused) {
|
733
|
+
// Add all modules to the new chunk
|
734
|
+
for (const module of item.modules) {
|
735
|
+
if (typeof module.chunkCondition === "function") {
|
736
|
+
if (!module.chunkCondition(newChunk)) continue;
|
737
|
+
}
|
738
|
+
// Add module to new chunk
|
739
|
+
GraphHelpers.connectChunkAndModule(newChunk, module);
|
740
|
+
// Remove module from used chunks
|
741
|
+
for (const chunk of usedChunks) {
|
742
|
+
chunk.removeModule(module);
|
743
|
+
module.rewriteChunkInReasons(chunk, [newChunk]);
|
744
|
+
}
|
745
|
+
}
|
746
|
+
} else {
|
747
|
+
// Remove all modules from used chunks
|
748
|
+
for (const module of item.modules) {
|
749
|
+
for (const chunk of usedChunks) {
|
750
|
+
chunk.removeModule(module);
|
751
|
+
module.rewriteChunkInReasons(chunk, [newChunk]);
|
752
|
+
}
|
753
|
+
}
|
754
|
+
}
|
755
|
+
|
756
|
+
if (item.cacheGroup.maxSize > 0) {
|
757
|
+
const oldMaxSizeSettings = maxSizeQueueMap.get(newChunk);
|
758
|
+
maxSizeQueueMap.set(newChunk, {
|
759
|
+
minSize: Math.max(
|
760
|
+
oldMaxSizeSettings ? oldMaxSizeSettings.minSize : 0,
|
761
|
+
item.cacheGroup.minSize
|
762
|
+
),
|
763
|
+
maxSize: Math.min(
|
764
|
+
oldMaxSizeSettings ? oldMaxSizeSettings.maxSize : Infinity,
|
765
|
+
item.cacheGroup.maxSize
|
766
|
+
),
|
767
|
+
automaticNameDelimiter: item.cacheGroup.automaticNameDelimiter
|
768
|
+
});
|
769
|
+
}
|
770
|
+
|
771
|
+
// remove all modules from other entries and update size
|
772
|
+
for (const [key, info] of chunksInfoMap) {
|
773
|
+
if (isOverlap(info.chunks, item.chunks)) {
|
774
|
+
const oldSize = info.modules.size;
|
775
|
+
for (const module of item.modules) {
|
776
|
+
info.modules.delete(module);
|
777
|
+
}
|
778
|
+
if (info.modules.size === 0) {
|
779
|
+
chunksInfoMap.delete(key);
|
780
|
+
continue;
|
781
|
+
}
|
782
|
+
if (info.modules.size !== oldSize) {
|
783
|
+
info.size = getModulesSize(info.modules);
|
784
|
+
if (info.size < info.cacheGroup.minSize) {
|
785
|
+
chunksInfoMap.delete(key);
|
786
|
+
}
|
787
|
+
}
|
788
|
+
}
|
789
|
+
}
|
790
|
+
}
|
791
|
+
|
792
|
+
// Make sure that maxSize is fulfilled
|
793
|
+
for (const chunk of compilation.chunks.slice()) {
|
794
|
+
const { minSize, maxSize, automaticNameDelimiter } =
|
795
|
+
maxSizeQueueMap.get(chunk) || this.options.fallbackCacheGroup;
|
796
|
+
if (!maxSize) continue;
|
797
|
+
const results = deterministicGroupingForModules({
|
798
|
+
maxSize,
|
799
|
+
minSize,
|
800
|
+
items: chunk.modulesIterable,
|
801
|
+
getKey(module) {
|
802
|
+
const ident = contextify(
|
803
|
+
compilation.options.context,
|
804
|
+
module.identifier()
|
805
|
+
);
|
806
|
+
const name = module.nameForCondition
|
807
|
+
? contextify(
|
808
|
+
compilation.options.context,
|
809
|
+
module.nameForCondition()
|
810
|
+
)
|
811
|
+
: ident.replace(/^.*!|\?[^?!]*$/g, "");
|
812
|
+
const fullKey =
|
813
|
+
name + automaticNameDelimiter + hashFilename(ident);
|
814
|
+
return fullKey.replace(/[\\/?]/g, "_");
|
815
|
+
},
|
816
|
+
getSize(module) {
|
817
|
+
return module.size();
|
818
|
+
}
|
819
|
+
});
|
820
|
+
results.sort((a, b) => {
|
821
|
+
if (a.key < b.key) return -1;
|
822
|
+
if (a.key > b.key) return 1;
|
823
|
+
return 0;
|
824
|
+
});
|
825
|
+
for (let i = 0; i < results.length; i++) {
|
826
|
+
const group = results[i];
|
827
|
+
const key = this.options.hidePathInfo
|
828
|
+
? hashFilename(group.key)
|
829
|
+
: group.key;
|
830
|
+
let name = chunk.name
|
831
|
+
? chunk.name + automaticNameDelimiter + key
|
832
|
+
: null;
|
833
|
+
if (name && name.length > 100) {
|
834
|
+
name =
|
835
|
+
name.slice(0, 100) +
|
836
|
+
automaticNameDelimiter +
|
837
|
+
hashFilename(name);
|
838
|
+
}
|
839
|
+
let newPart;
|
840
|
+
if (i !== results.length - 1) {
|
841
|
+
newPart = compilation.addChunk(name);
|
842
|
+
chunk.split(newPart);
|
843
|
+
newPart.chunkReason = chunk.chunkReason;
|
844
|
+
// Add all modules to the new chunk
|
845
|
+
for (const module of group.items) {
|
846
|
+
if (typeof module.chunkCondition === "function") {
|
847
|
+
if (!module.chunkCondition(newPart)) continue;
|
848
|
+
}
|
849
|
+
// Add module to new chunk
|
850
|
+
GraphHelpers.connectChunkAndModule(newPart, module);
|
851
|
+
// Remove module from used chunks
|
852
|
+
chunk.removeModule(module);
|
853
|
+
module.rewriteChunkInReasons(chunk, [newPart]);
|
854
|
+
}
|
855
|
+
} else {
|
856
|
+
// change the chunk to be a part
|
857
|
+
newPart = chunk;
|
858
|
+
chunk.name = name;
|
859
|
+
}
|
860
|
+
}
|
861
|
+
}
|
862
|
+
}
|
863
|
+
);
|
864
|
+
});
|
865
|
+
}
|
866
|
+
};
|