webpack 5.90.2 → 5.91.0
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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/README.md +5 -5
- package/bin/webpack.js +5 -1
- package/lib/APIPlugin.js +8 -4
- package/lib/AutomaticPrefetchPlugin.js +1 -1
- package/lib/BannerPlugin.js +3 -1
- package/lib/Cache.js +7 -1
- package/lib/CacheFacade.js +3 -3
- package/lib/ChunkGraph.js +32 -18
- package/lib/ChunkGroup.js +14 -14
- package/lib/CleanPlugin.js +7 -5
- package/lib/Compilation.js +263 -94
- package/lib/Compiler.js +199 -83
- package/lib/ConditionalInitFragment.js +4 -5
- package/lib/ContextModule.js +4 -1
- package/lib/ContextModuleFactory.js +4 -2
- package/lib/ContextReplacementPlugin.js +3 -2
- package/lib/CssModule.js +0 -3
- package/lib/DefinePlugin.js +4 -2
- package/lib/DelegatedModule.js +2 -1
- package/lib/Dependency.js +4 -2
- package/lib/DependencyTemplate.js +7 -2
- package/lib/DllModule.js +3 -1
- package/lib/DllReferencePlugin.js +6 -2
- package/lib/EntryOptionPlugin.js +4 -1
- package/lib/EntryPlugin.js +6 -1
- package/lib/Entrypoint.js +1 -1
- package/lib/ExportsInfo.js +1 -4
- package/lib/ExternalModule.js +120 -25
- package/lib/ExternalModuleFactoryPlugin.js +37 -2
- package/lib/FileSystemInfo.js +1 -1
- package/lib/Generator.js +2 -1
- package/lib/HookWebpackError.js +2 -2
- package/lib/InitFragment.js +5 -3
- package/lib/LibManifestPlugin.js +15 -7
- package/lib/Module.js +54 -5
- package/lib/ModuleFilenameHelpers.js +1 -1
- package/lib/ModuleGraph.js +56 -27
- package/lib/ModuleGraphConnection.js +2 -1
- package/lib/MultiCompiler.js +61 -17
- package/lib/NodeStuffPlugin.js +14 -3
- package/lib/NormalModule.js +239 -86
- package/lib/NormalModuleFactory.js +163 -32
- package/lib/NormalModuleReplacementPlugin.js +5 -1
- package/lib/ProvidePlugin.js +3 -1
- package/lib/RawModule.js +4 -2
- package/lib/ResolverFactory.js +5 -1
- package/lib/RuntimeModule.js +6 -5
- package/lib/RuntimePlugin.js +1 -0
- package/lib/RuntimeTemplate.js +102 -34
- package/lib/SourceMapDevToolPlugin.js +4 -1
- package/lib/Stats.js +12 -5
- package/lib/TemplatedPathPlugin.js +32 -6
- package/lib/Watching.js +67 -60
- package/lib/WebpackError.js +6 -6
- package/lib/WebpackOptionsApply.js +18 -5
- package/lib/asset/RawDataUrlModule.js +5 -2
- package/lib/async-modules/AwaitDependenciesInitFragment.js +2 -2
- package/lib/buildChunkGraph.js +220 -392
- package/lib/cache/IdleFileCachePlugin.js +8 -3
- package/lib/cache/MemoryCachePlugin.js +1 -1
- package/lib/cache/MemoryWithGcCachePlugin.js +6 -2
- package/lib/cache/PackFileCacheStrategy.js +49 -16
- package/lib/cache/ResolverCachePlugin.js +14 -6
- package/lib/cache/getLazyHashedEtag.js +1 -1
- package/lib/config/defaults.js +24 -1
- package/lib/config/normalization.js +3 -1
- package/lib/container/ContainerEntryDependency.js +2 -1
- package/lib/container/ContainerEntryModule.js +5 -2
- package/lib/container/ContainerPlugin.js +14 -10
- package/lib/container/FallbackModule.js +3 -2
- package/lib/container/RemoteModule.js +2 -1
- package/lib/container/RemoteRuntimeModule.js +12 -3
- package/lib/css/CssExportsGenerator.js +34 -17
- package/lib/css/CssGenerator.js +20 -2
- package/lib/css/CssLoadingRuntimeModule.js +212 -96
- package/lib/css/CssModulesPlugin.js +47 -13
- package/lib/debug/ProfilingPlugin.js +27 -2
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +9 -5
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +4 -1
- package/lib/dependencies/CommonJsDependencyHelpers.js +2 -1
- package/lib/dependencies/CommonJsExportRequireDependency.js +33 -18
- package/lib/dependencies/CommonJsExportsDependency.js +13 -5
- package/lib/dependencies/CommonJsExportsParserPlugin.js +20 -15
- package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -2
- package/lib/dependencies/ContextDependencyHelpers.js +49 -29
- package/lib/dependencies/ContextElementDependency.js +8 -1
- package/lib/dependencies/CssLocalIdentifierDependency.js +63 -8
- package/lib/dependencies/CssUrlDependency.js +5 -3
- package/lib/dependencies/ExportsInfoDependency.js +4 -3
- package/lib/dependencies/ExternalModuleInitFragment.js +5 -3
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +4 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +43 -23
- package/lib/dependencies/HarmonyExportHeaderDependency.js +1 -1
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +73 -32
- package/lib/dependencies/HarmonyExportInitFragment.js +10 -2
- package/lib/dependencies/HarmonyImportDependency.js +28 -12
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +44 -16
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +7 -6
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +21 -10
- package/lib/dependencies/ImportDependency.js +9 -2
- package/lib/dependencies/ImportEagerDependency.js +4 -2
- package/lib/dependencies/ImportMetaContextDependency.js +7 -0
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +25 -14
- package/lib/dependencies/ImportParserPlugin.js +12 -4
- package/lib/dependencies/ImportWeakDependency.js +4 -2
- package/lib/dependencies/LoaderDependency.js +2 -1
- package/lib/dependencies/LoaderImportDependency.js +2 -1
- package/lib/dependencies/ModuleDependency.js +4 -5
- package/lib/dependencies/PureExpressionDependency.js +4 -1
- package/lib/dependencies/RequireContextPlugin.js +1 -1
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +26 -14
- package/lib/dependencies/RequireEnsureDependency.js +1 -1
- package/lib/dependencies/URLDependency.js +7 -4
- package/lib/dependencies/WorkerDependency.js +1 -1
- package/lib/dependencies/WorkerPlugin.js +6 -5
- package/lib/dependencies/getFunctionExpression.js +3 -1
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +2 -1
- package/lib/hmr/LazyCompilationPlugin.js +2 -1
- package/lib/javascript/BasicEvaluatedExpression.js +2 -2
- package/lib/javascript/ChunkHelpers.js +2 -2
- package/lib/javascript/JavascriptParser.js +169 -57
- package/lib/javascript/JavascriptParserHelpers.js +1 -1
- package/lib/javascript/StartupHelpers.js +22 -5
- package/lib/logging/Logger.js +27 -2
- package/lib/logging/createConsoleLogger.js +11 -7
- package/lib/node/NodeEnvironmentPlugin.js +13 -7
- package/lib/node/NodeWatchFileSystem.js +37 -26
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +2 -1
- package/lib/node/RequireChunkLoadingRuntimeModule.js +2 -1
- package/lib/node/nodeConsole.js +24 -1
- package/lib/optimize/AggressiveSplittingPlugin.js +1 -0
- package/lib/optimize/ConcatenatedModule.js +140 -55
- package/lib/optimize/EnsureChunkConditionsPlugin.js +1 -1
- package/lib/optimize/InnerGraph.js +7 -2
- package/lib/optimize/InnerGraphPlugin.js +36 -13
- package/lib/optimize/ModuleConcatenationPlugin.js +12 -2
- package/lib/optimize/RemoveParentModulesPlugin.js +1 -0
- package/lib/optimize/RuntimeChunkPlugin.js +6 -1
- package/lib/optimize/SideEffectsFlagPlugin.js +46 -15
- package/lib/optimize/SplitChunksPlugin.js +2 -2
- package/lib/performance/SizeLimitsPlugin.js +11 -0
- package/lib/rules/ObjectMatcherRulePlugin.js +4 -0
- package/lib/runtime/EnsureChunkRuntimeModule.js +2 -1
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +2 -1
- package/lib/serialization/FileMiddleware.js +1 -0
- package/lib/serialization/ObjectMiddleware.js +2 -0
- package/lib/serialization/Serializer.js +19 -0
- package/lib/sharing/ConsumeSharedModule.js +3 -2
- package/lib/sharing/ConsumeSharedPlugin.js +17 -3
- package/lib/sharing/ConsumeSharedRuntimeModule.js +9 -2
- package/lib/sharing/ProvideSharedModule.js +2 -1
- package/lib/sharing/ProvideSharedPlugin.js +12 -5
- package/lib/sharing/resolveMatchedConfigs.js +2 -2
- package/lib/sharing/utils.js +13 -6
- package/lib/util/StackedCacheMap.js +26 -0
- package/lib/util/WeakTupleMap.js +57 -13
- package/lib/util/cleverMerge.js +24 -11
- package/lib/util/comparators.js +34 -14
- package/lib/util/conventions.js +129 -0
- package/lib/util/fs.js +379 -65
- package/lib/util/hash/BatchedHash.js +3 -0
- package/lib/util/hash/xxhash64.js +2 -2
- package/lib/util/memoize.js +2 -0
- package/lib/util/runtime.js +1 -1
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +4 -2
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +15 -6
- package/lib/wasm-sync/WebAssemblyGenerator.js +27 -6
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +2 -1
- package/lib/wasm-sync/WebAssemblyParser.js +7 -4
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -1
- package/lib/webpack.js +11 -5
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +2 -1
- package/package.json +25 -26
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +69 -8
- package/schemas/plugins/BannerPlugin.check.js +1 -1
- package/schemas/plugins/BannerPlugin.json +5 -1
- package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +1 -1
- package/schemas/plugins/css/CssGeneratorOptions.check.js +1 -1
- package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +1 -1
- package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
- package/types.d.ts +1772 -673
package/lib/buildChunkGraph.js
CHANGED
@@ -34,18 +34,15 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
|
|
34
34
|
* @property {ChunkGroupInfo} chunkGroupInfo
|
35
35
|
*/
|
36
36
|
|
37
|
-
/** @typedef {Set<Module> & { plus: Set<Module> }} ModuleSetPlus */
|
38
|
-
|
39
37
|
/**
|
40
38
|
* @typedef {Object} ChunkGroupInfo
|
41
39
|
* @property {ChunkGroup} chunkGroup the chunk group
|
42
40
|
* @property {RuntimeSpec} runtime the runtimes
|
43
|
-
* @property {
|
44
|
-
* @property {
|
45
|
-
* @property {ModuleSetPlus[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules
|
41
|
+
* @property {bigint | undefined} minAvailableModules current minimal set of modules available at this point
|
42
|
+
* @property {bigint[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules
|
46
43
|
* @property {Set<Module>=} skippedItems modules that were skipped because module is already available in parent chunks (need to reconsider when minAvailableModules is shrinking)
|
47
44
|
* @property {Set<[Module, ModuleGraphConnection[]]>=} skippedModuleConnections referenced modules that where skipped because they were not active in this runtime
|
48
|
-
* @property {
|
45
|
+
* @property {bigint | undefined} resultingAvailableModules set of modules available including modules from this chunk group
|
49
46
|
* @property {Set<ChunkGroupInfo> | undefined} children set of children chunk groups, that will be revisited when availableModules shrink
|
50
47
|
* @property {Set<ChunkGroupInfo> | undefined} availableSources set of chunk groups that are the source for minAvailableModules
|
51
48
|
* @property {Set<ChunkGroupInfo> | undefined} availableChildren set of chunk groups which depend on the this chunk group as availableSource
|
@@ -61,17 +58,26 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
|
|
61
58
|
* @property {ChunkGroup} chunkGroup referenced chunk group
|
62
59
|
*/
|
63
60
|
|
64
|
-
|
65
|
-
|
61
|
+
/** @typedef {(Module | ConnectionState | ModuleGraphConnection)[]} BlockModulesInTuples */
|
62
|
+
/** @typedef {(Module | ConnectionState | ModuleGraphConnection[])[]} BlockModulesInFlattenTuples */
|
63
|
+
/** @typedef {Map<DependenciesBlock, BlockModulesInFlattenTuples>} BlockModulesMap */
|
64
|
+
/** @typedef {Map<Chunk, bigint>} MaskByChunk */
|
65
|
+
/** @typedef {Set<DependenciesBlock>} BlocksWithNestedBlocks */
|
66
|
+
/** @typedef {Map<AsyncDependenciesBlock, BlockChunkGroupConnection[]>} BlockConnections */
|
67
|
+
/** @typedef {Map<ChunkGroup, ChunkGroupInfo>} ChunkGroupInfoMap */
|
68
|
+
/** @typedef {Set<ChunkGroup>} AllCreatedChunkGroups */
|
69
|
+
/** @typedef {Map<Entrypoint, Module[]>} InputEntrypointsAndModules */
|
70
|
+
|
71
|
+
const ZERO_BIGINT = BigInt(0);
|
72
|
+
const ONE_BIGINT = BigInt(1);
|
66
73
|
|
67
74
|
/**
|
68
|
-
* @param {
|
69
|
-
* @param {
|
70
|
-
* @returns {
|
75
|
+
* @param {bigint} mask The mask to test
|
76
|
+
* @param {number} ordinal The ordinal of the bit to test
|
77
|
+
* @returns {boolean} If the ordinal-th bit is set in the mask
|
71
78
|
*/
|
72
|
-
const
|
73
|
-
|
74
|
-
};
|
79
|
+
const isOrdinalSetInMask = (mask, ordinal) =>
|
80
|
+
BigInt.asUintN(1, mask >> BigInt(ordinal)) !== ZERO_BIGINT;
|
75
81
|
|
76
82
|
/**
|
77
83
|
* @param {ModuleGraphConnection[]} connections list of connections
|
@@ -92,15 +98,26 @@ const getActiveStateOfConnections = (connections, runtime) => {
|
|
92
98
|
return merged;
|
93
99
|
};
|
94
100
|
|
101
|
+
/**
|
102
|
+
* @param {Module} module module
|
103
|
+
* @param {ModuleGraph} moduleGraph module graph
|
104
|
+
* @param {RuntimeSpec} runtime runtime
|
105
|
+
* @param {BlockModulesMap} blockModulesMap block modules map
|
106
|
+
*/
|
95
107
|
const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
108
|
+
/** @type {DependenciesBlock | undefined} */
|
96
109
|
let blockCache;
|
110
|
+
/** @type {BlockModulesInTuples | undefined} */
|
97
111
|
let modules;
|
98
112
|
|
113
|
+
/** @type {BlockModulesInTuples[]} */
|
99
114
|
const arrays = [];
|
100
115
|
|
116
|
+
/** @type {DependenciesBlock[]} */
|
101
117
|
const queue = [module];
|
102
118
|
while (queue.length > 0) {
|
103
|
-
const block = queue.pop();
|
119
|
+
const block = /** @type {DependenciesBlock} */ (queue.pop());
|
120
|
+
/** @type {Module[]} */
|
104
121
|
const arr = [];
|
105
122
|
arrays.push(arr);
|
106
123
|
blockModulesMap.set(block, arr);
|
@@ -124,17 +141,26 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
|
124
141
|
|
125
142
|
// deprecated fallback
|
126
143
|
if (index < 0) {
|
127
|
-
index = block.dependencies.indexOf(d);
|
144
|
+
index = /** @type {DependenciesBlock} */ (block).dependencies.indexOf(d);
|
128
145
|
}
|
129
146
|
|
130
147
|
if (blockCache !== block) {
|
131
|
-
modules =
|
148
|
+
modules =
|
149
|
+
/** @type {BlockModulesInTuples} */
|
150
|
+
(
|
151
|
+
blockModulesMap.get(
|
152
|
+
(blockCache = /** @type {DependenciesBlock} */ (block))
|
153
|
+
)
|
154
|
+
);
|
132
155
|
}
|
133
156
|
|
134
157
|
const i = index * 3;
|
135
|
-
|
136
|
-
modules[i
|
137
|
-
|
158
|
+
/** @type {BlockModulesInTuples} */
|
159
|
+
(modules)[i] = m;
|
160
|
+
/** @type {BlockModulesInTuples} */
|
161
|
+
(modules)[i + 1] = connection.getActiveState(runtime);
|
162
|
+
/** @type {BlockModulesInTuples} */
|
163
|
+
(modules)[i + 2] = connection;
|
138
164
|
}
|
139
165
|
|
140
166
|
for (const modules of arrays) {
|
@@ -144,14 +170,15 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
|
144
170
|
outer: for (let j = 0; j < modules.length; j += 3) {
|
145
171
|
const m = modules[j];
|
146
172
|
if (m === undefined) continue;
|
147
|
-
const state = modules[j + 1];
|
148
|
-
const connection = modules[j + 2];
|
173
|
+
const state = /** @type {ConnectionState} */ (modules[j + 1]);
|
174
|
+
const connection = /** @type {ModuleGraphConnection} */ (modules[j + 2]);
|
149
175
|
if (indexMap === undefined) {
|
150
176
|
let i = 0;
|
151
177
|
for (; i < length; i += 3) {
|
152
178
|
if (modules[i] === m) {
|
153
|
-
const merged = modules[i + 1];
|
154
|
-
|
179
|
+
const merged = /** @type {ConnectionState} */ (modules[i + 1]);
|
180
|
+
/** @type {ModuleGraphConnection[]} */
|
181
|
+
(/** @type {unknown} */ (modules[i + 2])).push(connection);
|
155
182
|
if (merged === true) continue outer;
|
156
183
|
modules[i + 1] = ModuleGraphConnection.addConnectionStates(
|
157
184
|
merged,
|
@@ -164,7 +191,8 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
|
164
191
|
length++;
|
165
192
|
modules[length] = state;
|
166
193
|
length++;
|
167
|
-
|
194
|
+
/** @type {ModuleGraphConnection[]} */
|
195
|
+
(/** @type {unknown} */ (modules[length])) = [connection];
|
168
196
|
length++;
|
169
197
|
if (length > 30) {
|
170
198
|
// To avoid worse case performance, we will use an index map for
|
@@ -178,8 +206,9 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
|
178
206
|
} else {
|
179
207
|
const idx = indexMap.get(m);
|
180
208
|
if (idx !== undefined) {
|
181
|
-
const merged = modules[idx];
|
182
|
-
|
209
|
+
const merged = /** @type {ConnectionState} */ (modules[idx]);
|
210
|
+
/** @type {ModuleGraphConnection[]} */
|
211
|
+
(/** @type {unknown} */ (modules[idx + 1])).push(connection);
|
183
212
|
if (merged === true) continue outer;
|
184
213
|
modules[idx] = ModuleGraphConnection.addConnectionStates(
|
185
214
|
merged,
|
@@ -191,7 +220,11 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
|
191
220
|
modules[length] = state;
|
192
221
|
indexMap.set(m, length);
|
193
222
|
length++;
|
194
|
-
|
223
|
+
/** @type {ModuleGraphConnection[]} */
|
224
|
+
(
|
225
|
+
/** @type {unknown} */
|
226
|
+
(modules[length])
|
227
|
+
) = [connection];
|
195
228
|
length++;
|
196
229
|
}
|
197
230
|
}
|
@@ -204,11 +237,12 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
|
204
237
|
*
|
205
238
|
* @param {Logger} logger a logger
|
206
239
|
* @param {Compilation} compilation the compilation
|
207
|
-
* @param {
|
208
|
-
* @param {
|
209
|
-
* @param {
|
210
|
-
* @param {
|
211
|
-
* @param {
|
240
|
+
* @param {InputEntrypointsAndModules} inputEntrypointsAndModules chunk groups which are processed with the modules
|
241
|
+
* @param {ChunkGroupInfoMap} chunkGroupInfoMap mapping from chunk group to available modules
|
242
|
+
* @param {BlockConnections} blockConnections connection for blocks
|
243
|
+
* @param {BlocksWithNestedBlocks} blocksWithNestedBlocks flag for blocks that have nested blocks
|
244
|
+
* @param {AllCreatedChunkGroups} allCreatedChunkGroups filled with all chunk groups that are created here
|
245
|
+
* @param {MaskByChunk} maskByChunk module content mask by chunk
|
212
246
|
*/
|
213
247
|
const visitModules = (
|
214
248
|
logger,
|
@@ -217,30 +251,51 @@ const visitModules = (
|
|
217
251
|
chunkGroupInfoMap,
|
218
252
|
blockConnections,
|
219
253
|
blocksWithNestedBlocks,
|
220
|
-
allCreatedChunkGroups
|
254
|
+
allCreatedChunkGroups,
|
255
|
+
maskByChunk
|
221
256
|
) => {
|
222
257
|
const { moduleGraph, chunkGraph, moduleMemCaches } = compilation;
|
223
258
|
|
224
259
|
const blockModulesRuntimeMap = new Map();
|
225
260
|
|
226
|
-
/** @type {
|
227
|
-
let blockModulesMapRuntime = false;
|
228
|
-
/** @type {Map<DependenciesBlock, (Module | ConnectionState)[]>} */
|
261
|
+
/** @type {BlockModulesMap | undefined} */
|
229
262
|
let blockModulesMap;
|
230
263
|
|
264
|
+
/** @type {Map<Module, number>} */
|
265
|
+
const ordinalByModule = new Map();
|
266
|
+
|
267
|
+
/**
|
268
|
+
* @param {Module} module The module to look up
|
269
|
+
* @returns {number} The ordinal of the module in masks
|
270
|
+
*/
|
271
|
+
const getModuleOrdinal = module => {
|
272
|
+
let ordinal = ordinalByModule.get(module);
|
273
|
+
if (ordinal === undefined) {
|
274
|
+
ordinal = ordinalByModule.size;
|
275
|
+
ordinalByModule.set(module, ordinal);
|
276
|
+
}
|
277
|
+
return ordinal;
|
278
|
+
};
|
279
|
+
|
280
|
+
for (const chunk of compilation.chunks) {
|
281
|
+
let mask = ZERO_BIGINT;
|
282
|
+
for (const m of chunkGraph.getChunkModulesIterable(chunk)) {
|
283
|
+
mask |= ONE_BIGINT << BigInt(getModuleOrdinal(m));
|
284
|
+
}
|
285
|
+
maskByChunk.set(chunk, mask);
|
286
|
+
}
|
287
|
+
|
231
288
|
/**
|
232
289
|
*
|
233
290
|
* @param {DependenciesBlock} block block
|
234
291
|
* @param {RuntimeSpec} runtime runtime
|
235
|
-
* @returns {
|
292
|
+
* @returns {BlockModulesInFlattenTuples} block modules in flatten tuples
|
236
293
|
*/
|
237
294
|
const getBlockModules = (block, runtime) => {
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
blockModulesRuntimeMap.set(runtime, blockModulesMap);
|
243
|
-
}
|
295
|
+
blockModulesMap = blockModulesRuntimeMap.get(runtime);
|
296
|
+
if (blockModulesMap === undefined) {
|
297
|
+
blockModulesMap = new Map();
|
298
|
+
blockModulesRuntimeMap.set(runtime, blockModulesMap);
|
244
299
|
}
|
245
300
|
let blockModules = blockModulesMap.get(block);
|
246
301
|
if (blockModules !== undefined) return blockModules;
|
@@ -264,9 +319,11 @@ const visitModules = (
|
|
264
319
|
} else {
|
265
320
|
logger.time("visitModules: prepare");
|
266
321
|
extractBlockModules(module, moduleGraph, runtime, blockModulesMap);
|
267
|
-
blockModules =
|
322
|
+
blockModules =
|
323
|
+
/** @type {BlockModulesInFlattenTuples} */
|
324
|
+
(blockModulesMap.get(block));
|
268
325
|
logger.timeAggregate("visitModules: prepare");
|
269
|
-
return
|
326
|
+
return blockModules;
|
270
327
|
}
|
271
328
|
};
|
272
329
|
|
@@ -331,7 +388,6 @@ const visitModules = (
|
|
331
388
|
chunkGroup,
|
332
389
|
runtime,
|
333
390
|
minAvailableModules: undefined,
|
334
|
-
minAvailableModulesOwned: false,
|
335
391
|
availableModulesToBeMerged: [],
|
336
392
|
skippedItems: undefined,
|
337
393
|
resultingAvailableModules: undefined,
|
@@ -354,15 +410,12 @@ const visitModules = (
|
|
354
410
|
// minAvailableModules for child entrypoints are unknown yet, set to undefined.
|
355
411
|
// This means no module is added until other sets are merged into
|
356
412
|
// this minAvailableModules (by the parent entrypoints)
|
357
|
-
const skippedItems = new Set();
|
358
|
-
for (const module of modules) {
|
359
|
-
skippedItems.add(module);
|
360
|
-
}
|
413
|
+
const skippedItems = new Set(modules);
|
361
414
|
chunkGroupInfo.skippedItems = skippedItems;
|
362
415
|
chunkGroupsForCombining.add(chunkGroupInfo);
|
363
416
|
} else {
|
364
417
|
// The application may start here: We start with an empty list of available modules
|
365
|
-
chunkGroupInfo.minAvailableModules =
|
418
|
+
chunkGroupInfo.minAvailableModules = ZERO_BIGINT;
|
366
419
|
const chunk = chunkGroup.getEntrypointChunk();
|
367
420
|
for (const module of modules) {
|
368
421
|
queue.push({
|
@@ -433,6 +486,7 @@ const visitModules = (
|
|
433
486
|
const iteratorBlock = b => {
|
434
487
|
// 1. We create a chunk group with single chunk in it for this Block
|
435
488
|
// but only once (blockChunkGroups map)
|
489
|
+
/** @type {ChunkGroupInfo | undefined} */
|
436
490
|
let cgi = blockChunkGroups.get(b);
|
437
491
|
/** @type {ChunkGroup | undefined} */
|
438
492
|
let c;
|
@@ -447,15 +501,15 @@ const visitModules = (
|
|
447
501
|
entrypoint = compilation.addAsyncEntrypoint(
|
448
502
|
entryOptions,
|
449
503
|
module,
|
450
|
-
b.loc,
|
451
|
-
b.request
|
504
|
+
/** @type {DependencyLocation} */ (b.loc),
|
505
|
+
/** @type {string} */ (b.request)
|
452
506
|
);
|
507
|
+
maskByChunk.set(entrypoint.chunks[0], ZERO_BIGINT);
|
453
508
|
entrypoint.index = nextChunkGroupIndex++;
|
454
509
|
cgi = {
|
455
510
|
chunkGroup: entrypoint,
|
456
511
|
runtime: entrypoint.options.runtime || entrypoint.name,
|
457
|
-
minAvailableModules:
|
458
|
-
minAvailableModulesOwned: false,
|
512
|
+
minAvailableModules: ZERO_BIGINT,
|
459
513
|
availableModulesToBeMerged: [],
|
460
514
|
skippedItems: undefined,
|
461
515
|
resultingAvailableModules: undefined,
|
@@ -482,7 +536,11 @@ const visitModules = (
|
|
482
536
|
} else {
|
483
537
|
entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
|
484
538
|
// TODO merge entryOptions
|
485
|
-
entrypoint.addOrigin(
|
539
|
+
entrypoint.addOrigin(
|
540
|
+
module,
|
541
|
+
/** @type {DependencyLocation} */ (b.loc),
|
542
|
+
/** @type {string} */ (b.request)
|
543
|
+
);
|
486
544
|
chunkGraph.connectBlockAndChunkGroup(b, entrypoint);
|
487
545
|
}
|
488
546
|
|
@@ -490,7 +548,7 @@ const visitModules = (
|
|
490
548
|
queueDelayed.push({
|
491
549
|
action: PROCESS_ENTRY_BLOCK,
|
492
550
|
block: b,
|
493
|
-
module
|
551
|
+
module,
|
494
552
|
chunk: entrypoint.chunks[0],
|
495
553
|
chunkGroup: entrypoint,
|
496
554
|
chunkGroupInfo: cgi
|
@@ -500,26 +558,26 @@ const visitModules = (
|
|
500
558
|
queue.push({
|
501
559
|
action: PROCESS_BLOCK,
|
502
560
|
block: b,
|
503
|
-
module
|
561
|
+
module,
|
504
562
|
chunk,
|
505
563
|
chunkGroup,
|
506
564
|
chunkGroupInfo
|
507
565
|
});
|
508
566
|
} else {
|
509
|
-
cgi = chunkName
|
567
|
+
cgi = chunkName ? namedChunkGroups.get(chunkName) : undefined;
|
510
568
|
if (!cgi) {
|
511
569
|
c = compilation.addChunkInGroup(
|
512
570
|
b.groupOptions || b.chunkName,
|
513
571
|
module,
|
514
|
-
b.loc,
|
515
|
-
b.request
|
572
|
+
/** @type {DependencyLocation} */ (b.loc),
|
573
|
+
/** @type {string} */ (b.request)
|
516
574
|
);
|
575
|
+
maskByChunk.set(c.chunks[0], ZERO_BIGINT);
|
517
576
|
c.index = nextChunkGroupIndex++;
|
518
577
|
cgi = {
|
519
578
|
chunkGroup: c,
|
520
579
|
runtime: chunkGroupInfo.runtime,
|
521
580
|
minAvailableModules: undefined,
|
522
|
-
minAvailableModulesOwned: undefined,
|
523
581
|
availableModulesToBeMerged: [],
|
524
582
|
skippedItems: undefined,
|
525
583
|
resultingAvailableModules: undefined,
|
@@ -543,19 +601,23 @@ const visitModules = (
|
|
543
601
|
new AsyncDependencyToInitialChunkError(
|
544
602
|
/** @type {string} */ (chunkName),
|
545
603
|
module,
|
546
|
-
b.loc
|
604
|
+
/** @type {DependencyLocation} */ (b.loc)
|
547
605
|
)
|
548
606
|
);
|
549
607
|
c = chunkGroup;
|
550
608
|
} else {
|
551
609
|
c.addOptions(b.groupOptions);
|
552
610
|
}
|
553
|
-
c.addOrigin(
|
611
|
+
c.addOrigin(
|
612
|
+
module,
|
613
|
+
/** @type {DependencyLocation} */ (b.loc),
|
614
|
+
/** @type {string} */ (b.request)
|
615
|
+
);
|
554
616
|
}
|
555
617
|
blockConnections.set(b, []);
|
556
618
|
}
|
557
619
|
blockChunkGroups.set(b, /** @type {ChunkGroupInfo} */ (cgi));
|
558
|
-
blockByChunkGroups.set(cgi, b);
|
620
|
+
blockByChunkGroups.set(/** @type {ChunkGroupInfo} */ (cgi), b);
|
559
621
|
} else if (entryOptions) {
|
560
622
|
entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
|
561
623
|
} else {
|
@@ -565,7 +627,8 @@ const visitModules = (
|
|
565
627
|
if (c !== undefined) {
|
566
628
|
// 2. We store the connection for the block
|
567
629
|
// to connect it later if needed
|
568
|
-
|
630
|
+
/** @type {BlockChunkGroupConnection[]} */
|
631
|
+
(blockConnections.get(b)).push({
|
569
632
|
originChunkGroupInfo: chunkGroupInfo,
|
570
633
|
chunkGroup: c
|
571
634
|
});
|
@@ -584,7 +647,7 @@ const visitModules = (
|
|
584
647
|
queueDelayed.push({
|
585
648
|
action: PROCESS_BLOCK,
|
586
649
|
block: b,
|
587
|
-
module
|
650
|
+
module,
|
588
651
|
chunk: c.chunks[0],
|
589
652
|
chunkGroup: c,
|
590
653
|
chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
|
@@ -604,15 +667,22 @@ const visitModules = (
|
|
604
667
|
const blockModules = getBlockModules(block, chunkGroupInfo.runtime);
|
605
668
|
|
606
669
|
if (blockModules !== undefined) {
|
607
|
-
const
|
670
|
+
const minAvailableModules =
|
671
|
+
/** @type {bigint} */
|
672
|
+
(chunkGroupInfo.minAvailableModules);
|
608
673
|
// Buffer items because order need to be reversed to get indices correct
|
609
674
|
// Traverse all referenced modules
|
610
|
-
for (let i = 0
|
675
|
+
for (let i = 0, len = blockModules.length; i < len; i += 3) {
|
611
676
|
const refModule = /** @type {Module} */ (blockModules[i]);
|
612
|
-
|
677
|
+
// For single comparisons this might be cheaper
|
678
|
+
const isModuleInChunk = chunkGraph.isModuleInChunk(refModule, chunk);
|
679
|
+
|
680
|
+
if (isModuleInChunk) {
|
613
681
|
// skip early if already connected
|
614
682
|
continue;
|
615
683
|
}
|
684
|
+
|
685
|
+
const refOrdinal = /** @type {number} */ getModuleOrdinal(refModule);
|
616
686
|
const activeState = /** @type {ConnectionState} */ (
|
617
687
|
blockModules[i + 1]
|
618
688
|
);
|
@@ -623,12 +693,7 @@ const visitModules = (
|
|
623
693
|
skipConnectionBuffer.push([refModule, connections]);
|
624
694
|
// We skip inactive connections
|
625
695
|
if (activeState === false) continue;
|
626
|
-
}
|
627
|
-
if (
|
628
|
-
activeState === true &&
|
629
|
-
(minAvailableModules.has(refModule) ||
|
630
|
-
minAvailableModules.plus.has(refModule))
|
631
|
-
) {
|
696
|
+
} else if (isOrdinalSetInMask(minAvailableModules, refOrdinal)) {
|
632
697
|
// already in parent chunks, skip it for now
|
633
698
|
skipBuffer.push(refModule);
|
634
699
|
continue;
|
@@ -694,15 +759,15 @@ const visitModules = (
|
|
694
759
|
const blockModules = getBlockModules(block, chunkGroupInfo.runtime);
|
695
760
|
|
696
761
|
if (blockModules !== undefined) {
|
697
|
-
// Traverse all referenced modules
|
698
|
-
for (let i =
|
762
|
+
// Traverse all referenced modules in reverse order
|
763
|
+
for (let i = blockModules.length - 3; i >= 0; i -= 3) {
|
699
764
|
const refModule = /** @type {Module} */ (blockModules[i]);
|
700
765
|
const activeState = /** @type {ConnectionState} */ (
|
701
766
|
blockModules[i + 1]
|
702
767
|
);
|
703
768
|
// enqueue, then add and enter to be in the correct order
|
704
769
|
// this is relevant with circular dependencies
|
705
|
-
|
770
|
+
queue.push({
|
706
771
|
action:
|
707
772
|
activeState === true ? ADD_AND_ENTER_ENTRY_MODULE : PROCESS_BLOCK,
|
708
773
|
block: refModule,
|
@@ -712,13 +777,6 @@ const visitModules = (
|
|
712
777
|
chunkGroupInfo
|
713
778
|
});
|
714
779
|
}
|
715
|
-
// Add buffered items in reverse order
|
716
|
-
if (queueBuffer.length > 0) {
|
717
|
-
for (let i = queueBuffer.length - 1; i >= 0; i--) {
|
718
|
-
queue.push(queueBuffer[i]);
|
719
|
-
}
|
720
|
-
queueBuffer.length = 0;
|
721
|
-
}
|
722
780
|
}
|
723
781
|
|
724
782
|
// Traverse all Blocks
|
@@ -750,12 +808,18 @@ const visitModules = (
|
|
750
808
|
);
|
751
809
|
// fallthrough
|
752
810
|
case ADD_AND_ENTER_MODULE: {
|
753
|
-
|
811
|
+
const isModuleInChunk = chunkGraph.isModuleInChunk(module, chunk);
|
812
|
+
|
813
|
+
if (isModuleInChunk) {
|
754
814
|
// already connected, skip it
|
755
815
|
break;
|
756
816
|
}
|
757
817
|
// We connect Module and Chunk
|
758
818
|
chunkGraph.connectChunkAndModule(chunk, module);
|
819
|
+
const moduleOrdinal = getModuleOrdinal(module);
|
820
|
+
let chunkMask = /** @type {bigint} */ (maskByChunk.get(chunk));
|
821
|
+
chunkMask |= ONE_BIGINT << BigInt(moduleOrdinal);
|
822
|
+
maskByChunk.set(chunk, chunkMask);
|
759
823
|
}
|
760
824
|
// fallthrough
|
761
825
|
case ENTER_MODULE: {
|
@@ -812,44 +876,24 @@ const visitModules = (
|
|
812
876
|
}
|
813
877
|
};
|
814
878
|
|
879
|
+
/**
|
880
|
+
* @param {ChunkGroupInfo} chunkGroupInfo The info object for the chunk group
|
881
|
+
* @returns {bigint} The mask of available modules after the chunk group
|
882
|
+
*/
|
815
883
|
const calculateResultingAvailableModules = chunkGroupInfo => {
|
816
|
-
if (chunkGroupInfo.resultingAvailableModules)
|
884
|
+
if (chunkGroupInfo.resultingAvailableModules !== undefined)
|
817
885
|
return chunkGroupInfo.resultingAvailableModules;
|
818
886
|
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
// We want to be as lazy as possible. There are multiple ways doing this:
|
823
|
-
// Note that resultingAvailableModules is stored as "(a) + (b)" as it's a ModuleSetPlus
|
824
|
-
// - resultingAvailableModules = (modules of chunk) + (minAvailableModules + minAvailableModules.plus)
|
825
|
-
// - resultingAvailableModules = (minAvailableModules + modules of chunk) + (minAvailableModules.plus)
|
826
|
-
// We choose one depending on the size of minAvailableModules vs minAvailableModules.plus
|
827
|
-
|
828
|
-
let resultingAvailableModules;
|
829
|
-
if (minAvailableModules.size > minAvailableModules.plus.size) {
|
830
|
-
// resultingAvailableModules = (modules of chunk) + (minAvailableModules + minAvailableModules.plus)
|
831
|
-
resultingAvailableModules =
|
832
|
-
/** @type {Set<Module> & {plus: Set<Module>}} */ (new Set());
|
833
|
-
for (const module of minAvailableModules.plus)
|
834
|
-
minAvailableModules.add(module);
|
835
|
-
minAvailableModules.plus = EMPTY_SET;
|
836
|
-
resultingAvailableModules.plus = minAvailableModules;
|
837
|
-
chunkGroupInfo.minAvailableModulesOwned = false;
|
838
|
-
} else {
|
839
|
-
// resultingAvailableModules = (minAvailableModules + modules of chunk) + (minAvailableModules.plus)
|
840
|
-
resultingAvailableModules =
|
841
|
-
/** @type {Set<Module> & {plus: Set<Module>}} */ (
|
842
|
-
new Set(minAvailableModules)
|
843
|
-
);
|
844
|
-
resultingAvailableModules.plus = minAvailableModules.plus;
|
845
|
-
}
|
887
|
+
let resultingAvailableModules = /** @type {bigint} */ (
|
888
|
+
chunkGroupInfo.minAvailableModules
|
889
|
+
);
|
846
890
|
|
847
891
|
// add the modules from the chunk group to the set
|
848
892
|
for (const chunk of chunkGroupInfo.chunkGroup.chunks) {
|
849
|
-
|
850
|
-
|
851
|
-
}
|
893
|
+
const mask = /** @type {bigint} */ (maskByChunk.get(chunk));
|
894
|
+
resultingAvailableModules |= mask;
|
852
895
|
}
|
896
|
+
|
853
897
|
return (chunkGroupInfo.resultingAvailableModules =
|
854
898
|
resultingAvailableModules);
|
855
899
|
};
|
@@ -896,232 +940,24 @@ const visitModules = (
|
|
896
940
|
// Execute the merge
|
897
941
|
for (const info of chunkGroupsForMerging) {
|
898
942
|
const availableModulesToBeMerged = info.availableModulesToBeMerged;
|
899
|
-
|
943
|
+
const cachedMinAvailableModules = info.minAvailableModules;
|
944
|
+
let minAvailableModules = cachedMinAvailableModules;
|
900
945
|
|
901
946
|
statMergedAvailableModuleSets += availableModulesToBeMerged.length;
|
902
947
|
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
// the list didn't shrink.
|
907
|
-
if (availableModulesToBeMerged.length > 1) {
|
908
|
-
availableModulesToBeMerged.sort(bySetSize);
|
909
|
-
}
|
910
|
-
let changed = false;
|
911
|
-
merge: for (const availableModules of availableModulesToBeMerged) {
|
912
|
-
if (cachedMinAvailableModules === undefined) {
|
913
|
-
cachedMinAvailableModules = availableModules;
|
914
|
-
info.minAvailableModules = cachedMinAvailableModules;
|
915
|
-
info.minAvailableModulesOwned = false;
|
916
|
-
changed = true;
|
948
|
+
for (const availableModules of availableModulesToBeMerged) {
|
949
|
+
if (minAvailableModules === undefined) {
|
950
|
+
minAvailableModules = availableModules;
|
917
951
|
} else {
|
918
|
-
|
919
|
-
// We own it and can modify it
|
920
|
-
if (cachedMinAvailableModules.plus === availableModules.plus) {
|
921
|
-
for (const m of cachedMinAvailableModules) {
|
922
|
-
if (!availableModules.has(m)) {
|
923
|
-
cachedMinAvailableModules.delete(m);
|
924
|
-
changed = true;
|
925
|
-
}
|
926
|
-
}
|
927
|
-
} else {
|
928
|
-
for (const m of cachedMinAvailableModules) {
|
929
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
930
|
-
cachedMinAvailableModules.delete(m);
|
931
|
-
changed = true;
|
932
|
-
}
|
933
|
-
}
|
934
|
-
for (const m of cachedMinAvailableModules.plus) {
|
935
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
936
|
-
// We can't remove modules from the plus part
|
937
|
-
// so we need to merge plus into the normal part to allow modifying it
|
938
|
-
const iterator =
|
939
|
-
cachedMinAvailableModules.plus[Symbol.iterator]();
|
940
|
-
// fast forward add all modules until m
|
941
|
-
/** @type {IteratorResult<Module>} */
|
942
|
-
let it;
|
943
|
-
while (!(it = iterator.next()).done) {
|
944
|
-
const module = it.value;
|
945
|
-
if (module === m) break;
|
946
|
-
cachedMinAvailableModules.add(module);
|
947
|
-
}
|
948
|
-
// check the remaining modules before adding
|
949
|
-
while (!(it = iterator.next()).done) {
|
950
|
-
const module = it.value;
|
951
|
-
if (
|
952
|
-
availableModules.has(module) ||
|
953
|
-
availableModules.plus.has(module)
|
954
|
-
) {
|
955
|
-
cachedMinAvailableModules.add(module);
|
956
|
-
}
|
957
|
-
}
|
958
|
-
cachedMinAvailableModules.plus = EMPTY_SET;
|
959
|
-
changed = true;
|
960
|
-
continue merge;
|
961
|
-
}
|
962
|
-
}
|
963
|
-
}
|
964
|
-
} else if (cachedMinAvailableModules.plus === availableModules.plus) {
|
965
|
-
// Common and fast case when the plus part is shared
|
966
|
-
// We only need to care about the normal part
|
967
|
-
if (availableModules.size < cachedMinAvailableModules.size) {
|
968
|
-
// the new availableModules is smaller so it's faster to
|
969
|
-
// fork from the new availableModules
|
970
|
-
statForkedAvailableModules++;
|
971
|
-
statForkedAvailableModulesCount += availableModules.size;
|
972
|
-
statForkedMergedModulesCount += cachedMinAvailableModules.size;
|
973
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
974
|
-
const newSet = /** @type {ModuleSetPlus} */ (new Set());
|
975
|
-
newSet.plus = availableModules.plus;
|
976
|
-
for (const m of availableModules) {
|
977
|
-
if (cachedMinAvailableModules.has(m)) {
|
978
|
-
newSet.add(m);
|
979
|
-
}
|
980
|
-
}
|
981
|
-
statForkedResultModulesCount += newSet.size;
|
982
|
-
cachedMinAvailableModules = newSet;
|
983
|
-
info.minAvailableModulesOwned = true;
|
984
|
-
info.minAvailableModules = newSet;
|
985
|
-
changed = true;
|
986
|
-
continue merge;
|
987
|
-
}
|
988
|
-
for (const m of cachedMinAvailableModules) {
|
989
|
-
if (!availableModules.has(m)) {
|
990
|
-
// cachedMinAvailableModules need to be modified
|
991
|
-
// but we don't own it
|
992
|
-
statForkedAvailableModules++;
|
993
|
-
statForkedAvailableModulesCount +=
|
994
|
-
cachedMinAvailableModules.size;
|
995
|
-
statForkedMergedModulesCount += availableModules.size;
|
996
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
997
|
-
// as the plus part is equal we can just take over this one
|
998
|
-
const newSet = /** @type {ModuleSetPlus} */ (new Set());
|
999
|
-
newSet.plus = availableModules.plus;
|
1000
|
-
const iterator = cachedMinAvailableModules[Symbol.iterator]();
|
1001
|
-
// fast forward add all modules until m
|
1002
|
-
/** @type {IteratorResult<Module>} */
|
1003
|
-
let it;
|
1004
|
-
while (!(it = iterator.next()).done) {
|
1005
|
-
const module = it.value;
|
1006
|
-
if (module === m) break;
|
1007
|
-
newSet.add(module);
|
1008
|
-
}
|
1009
|
-
// check the remaining modules before adding
|
1010
|
-
while (!(it = iterator.next()).done) {
|
1011
|
-
const module = it.value;
|
1012
|
-
if (availableModules.has(module)) {
|
1013
|
-
newSet.add(module);
|
1014
|
-
}
|
1015
|
-
}
|
1016
|
-
statForkedResultModulesCount += newSet.size;
|
1017
|
-
cachedMinAvailableModules = newSet;
|
1018
|
-
info.minAvailableModulesOwned = true;
|
1019
|
-
info.minAvailableModules = newSet;
|
1020
|
-
changed = true;
|
1021
|
-
continue merge;
|
1022
|
-
}
|
1023
|
-
}
|
1024
|
-
} else {
|
1025
|
-
for (const m of cachedMinAvailableModules) {
|
1026
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
1027
|
-
// cachedMinAvailableModules need to be modified
|
1028
|
-
// but we don't own it
|
1029
|
-
statForkedAvailableModules++;
|
1030
|
-
statForkedAvailableModulesCount +=
|
1031
|
-
cachedMinAvailableModules.size;
|
1032
|
-
statForkedAvailableModulesCountPlus +=
|
1033
|
-
cachedMinAvailableModules.plus.size;
|
1034
|
-
statForkedMergedModulesCount += availableModules.size;
|
1035
|
-
statForkedMergedModulesCountPlus += availableModules.plus.size;
|
1036
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
1037
|
-
const newSet = /** @type {ModuleSetPlus} */ (new Set());
|
1038
|
-
newSet.plus = EMPTY_SET;
|
1039
|
-
const iterator = cachedMinAvailableModules[Symbol.iterator]();
|
1040
|
-
// fast forward add all modules until m
|
1041
|
-
/** @type {IteratorResult<Module>} */
|
1042
|
-
let it;
|
1043
|
-
while (!(it = iterator.next()).done) {
|
1044
|
-
const module = it.value;
|
1045
|
-
if (module === m) break;
|
1046
|
-
newSet.add(module);
|
1047
|
-
}
|
1048
|
-
// check the remaining modules before adding
|
1049
|
-
while (!(it = iterator.next()).done) {
|
1050
|
-
const module = it.value;
|
1051
|
-
if (
|
1052
|
-
availableModules.has(module) ||
|
1053
|
-
availableModules.plus.has(module)
|
1054
|
-
) {
|
1055
|
-
newSet.add(module);
|
1056
|
-
}
|
1057
|
-
}
|
1058
|
-
// also check all modules in cachedMinAvailableModules.plus
|
1059
|
-
for (const module of cachedMinAvailableModules.plus) {
|
1060
|
-
if (
|
1061
|
-
availableModules.has(module) ||
|
1062
|
-
availableModules.plus.has(module)
|
1063
|
-
) {
|
1064
|
-
newSet.add(module);
|
1065
|
-
}
|
1066
|
-
}
|
1067
|
-
statForkedResultModulesCount += newSet.size;
|
1068
|
-
cachedMinAvailableModules = newSet;
|
1069
|
-
info.minAvailableModulesOwned = true;
|
1070
|
-
info.minAvailableModules = newSet;
|
1071
|
-
changed = true;
|
1072
|
-
continue merge;
|
1073
|
-
}
|
1074
|
-
}
|
1075
|
-
for (const m of cachedMinAvailableModules.plus) {
|
1076
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
1077
|
-
// cachedMinAvailableModules need to be modified
|
1078
|
-
// but we don't own it
|
1079
|
-
statForkedAvailableModules++;
|
1080
|
-
statForkedAvailableModulesCount +=
|
1081
|
-
cachedMinAvailableModules.size;
|
1082
|
-
statForkedAvailableModulesCountPlus +=
|
1083
|
-
cachedMinAvailableModules.plus.size;
|
1084
|
-
statForkedMergedModulesCount += availableModules.size;
|
1085
|
-
statForkedMergedModulesCountPlus += availableModules.plus.size;
|
1086
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
1087
|
-
// we already know that all modules directly from cachedMinAvailableModules are in availableModules too
|
1088
|
-
const newSet = /** @type {ModuleSetPlus} */ (
|
1089
|
-
new Set(cachedMinAvailableModules)
|
1090
|
-
);
|
1091
|
-
newSet.plus = EMPTY_SET;
|
1092
|
-
const iterator =
|
1093
|
-
cachedMinAvailableModules.plus[Symbol.iterator]();
|
1094
|
-
// fast forward add all modules until m
|
1095
|
-
/** @type {IteratorResult<Module>} */
|
1096
|
-
let it;
|
1097
|
-
while (!(it = iterator.next()).done) {
|
1098
|
-
const module = it.value;
|
1099
|
-
if (module === m) break;
|
1100
|
-
newSet.add(module);
|
1101
|
-
}
|
1102
|
-
// check the remaining modules before adding
|
1103
|
-
while (!(it = iterator.next()).done) {
|
1104
|
-
const module = it.value;
|
1105
|
-
if (
|
1106
|
-
availableModules.has(module) ||
|
1107
|
-
availableModules.plus.has(module)
|
1108
|
-
) {
|
1109
|
-
newSet.add(module);
|
1110
|
-
}
|
1111
|
-
}
|
1112
|
-
statForkedResultModulesCount += newSet.size;
|
1113
|
-
cachedMinAvailableModules = newSet;
|
1114
|
-
info.minAvailableModulesOwned = true;
|
1115
|
-
info.minAvailableModules = newSet;
|
1116
|
-
changed = true;
|
1117
|
-
continue merge;
|
1118
|
-
}
|
1119
|
-
}
|
1120
|
-
}
|
952
|
+
minAvailableModules &= availableModules;
|
1121
953
|
}
|
1122
954
|
}
|
955
|
+
|
956
|
+
const changed = minAvailableModules !== cachedMinAvailableModules;
|
957
|
+
|
1123
958
|
availableModulesToBeMerged.length = 0;
|
1124
959
|
if (changed) {
|
960
|
+
info.minAvailableModules = minAvailableModules;
|
1125
961
|
info.resultingAvailableModules = undefined;
|
1126
962
|
outdatedChunkGroupInfo.add(info);
|
1127
963
|
}
|
@@ -1134,34 +970,24 @@ const visitModules = (
|
|
1134
970
|
for (const source of /** @type {Set<ChunkGroupInfo>} */ (
|
1135
971
|
info.availableSources
|
1136
972
|
)) {
|
1137
|
-
if (
|
973
|
+
if (source.minAvailableModules === undefined) {
|
1138
974
|
chunkGroupsForCombining.delete(info);
|
1139
975
|
break;
|
1140
976
|
}
|
1141
977
|
}
|
1142
978
|
}
|
979
|
+
|
1143
980
|
for (const info of chunkGroupsForCombining) {
|
1144
|
-
|
1145
|
-
availableModules.plus = EMPTY_SET;
|
1146
|
-
const mergeSet = set => {
|
1147
|
-
if (set.size > availableModules.plus.size) {
|
1148
|
-
for (const item of availableModules.plus) availableModules.add(item);
|
1149
|
-
availableModules.plus = set;
|
1150
|
-
} else {
|
1151
|
-
for (const item of set) availableModules.add(item);
|
1152
|
-
}
|
1153
|
-
};
|
981
|
+
let availableModules = ZERO_BIGINT;
|
1154
982
|
// combine minAvailableModules from all resultingAvailableModules
|
1155
983
|
for (const source of /** @type {Set<ChunkGroupInfo>} */ (
|
1156
984
|
info.availableSources
|
1157
985
|
)) {
|
1158
986
|
const resultingAvailableModules =
|
1159
987
|
calculateResultingAvailableModules(source);
|
1160
|
-
|
1161
|
-
mergeSet(resultingAvailableModules.plus);
|
988
|
+
availableModules |= resultingAvailableModules;
|
1162
989
|
}
|
1163
990
|
info.minAvailableModules = availableModules;
|
1164
|
-
info.minAvailableModulesOwned = false;
|
1165
991
|
info.resultingAvailableModules = undefined;
|
1166
992
|
outdatedChunkGroupInfo.add(info);
|
1167
993
|
}
|
@@ -1175,13 +1001,11 @@ const visitModules = (
|
|
1175
1001
|
// 1. Reconsider skipped items
|
1176
1002
|
if (info.skippedItems !== undefined) {
|
1177
1003
|
const minAvailableModules =
|
1178
|
-
/** @type {
|
1004
|
+
/** @type {bigint} */
|
1179
1005
|
(info.minAvailableModules);
|
1180
1006
|
for (const module of info.skippedItems) {
|
1181
|
-
|
1182
|
-
|
1183
|
-
!minAvailableModules.plus.has(module)
|
1184
|
-
) {
|
1007
|
+
const ordinal = getModuleOrdinal(module);
|
1008
|
+
if (!isOrdinalSetInMask(minAvailableModules, ordinal)) {
|
1185
1009
|
queue.push({
|
1186
1010
|
action: ADD_AND_ENTER_MODULE,
|
1187
1011
|
block: module,
|
@@ -1198,7 +1022,7 @@ const visitModules = (
|
|
1198
1022
|
// 2. Reconsider skipped connections
|
1199
1023
|
if (info.skippedModuleConnections !== undefined) {
|
1200
1024
|
const minAvailableModules =
|
1201
|
-
/** @type {
|
1025
|
+
/** @type {bigint} */
|
1202
1026
|
(info.minAvailableModules);
|
1203
1027
|
for (const entry of info.skippedModuleConnections) {
|
1204
1028
|
const [module, connections] = entry;
|
@@ -1208,15 +1032,13 @@ const visitModules = (
|
|
1208
1032
|
);
|
1209
1033
|
if (activeState === false) continue;
|
1210
1034
|
if (activeState === true) {
|
1035
|
+
const ordinal = getModuleOrdinal(module);
|
1211
1036
|
info.skippedModuleConnections.delete(entry);
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
) {
|
1218
|
-
info.skippedItems.add(module);
|
1219
|
-
continue;
|
1037
|
+
if (isOrdinalSetInMask(minAvailableModules, ordinal)) {
|
1038
|
+
/** @type {NonNullable<ChunkGroupInfo["skippedItems"]>} */
|
1039
|
+
(info.skippedItems).add(module);
|
1040
|
+
continue;
|
1041
|
+
}
|
1220
1042
|
}
|
1221
1043
|
queue.push({
|
1222
1044
|
action: activeState === true ? ADD_AND_ENTER_MODULE : PROCESS_BLOCK,
|
@@ -1307,26 +1129,29 @@ const visitModules = (
|
|
1307
1129
|
let preOrderIndex = 0;
|
1308
1130
|
let postOrderIndex = 0;
|
1309
1131
|
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
visited.add(current);
|
1316
|
-
|
1132
|
+
/**
|
1133
|
+
* @param {DependenciesBlock} current current
|
1134
|
+
* @param {BlocksWithNestedBlocks} visited visited dependencies blocks
|
1135
|
+
*/
|
1136
|
+
const process = (current, visited) => {
|
1317
1137
|
const blockModules = getBlockModules(current, runtime);
|
1318
1138
|
if (blockModules === undefined) {
|
1319
1139
|
return;
|
1320
1140
|
}
|
1321
1141
|
|
1322
|
-
for (let i = 0
|
1323
|
-
const refModule = /** @type {Module} */ (blockModules[i]);
|
1142
|
+
for (let i = 0, len = blockModules.length; i < len; i += 3) {
|
1324
1143
|
const activeState = /** @type {ConnectionState} */ (
|
1325
1144
|
blockModules[i + 1]
|
1326
1145
|
);
|
1327
1146
|
if (activeState === false) {
|
1328
1147
|
continue;
|
1329
1148
|
}
|
1149
|
+
const refModule = /** @type {Module} */ (blockModules[i]);
|
1150
|
+
if (visited.has(refModule)) {
|
1151
|
+
continue;
|
1152
|
+
}
|
1153
|
+
|
1154
|
+
visited.add(refModule);
|
1330
1155
|
|
1331
1156
|
if (refModule) {
|
1332
1157
|
chunkGroup.setModulePreOrderIndex(refModule, preOrderIndex++);
|
@@ -1336,9 +1161,10 @@ const visitModules = (
|
|
1336
1161
|
}
|
1337
1162
|
};
|
1338
1163
|
|
1339
|
-
process(block);
|
1164
|
+
process(block, new Set());
|
1340
1165
|
}
|
1341
1166
|
outdatedOrderIndexChunkGroups.clear();
|
1167
|
+
ordinalByModule.clear();
|
1342
1168
|
|
1343
1169
|
logger.log(
|
1344
1170
|
`${statProcessedQueueItems} queue items processed (${statProcessedBlocks} blocks)`
|
@@ -1355,15 +1181,15 @@ const visitModules = (
|
|
1355
1181
|
/**
|
1356
1182
|
*
|
1357
1183
|
* @param {Compilation} compilation the compilation
|
1358
|
-
* @param {
|
1359
|
-
* @param {
|
1360
|
-
* @param {
|
1184
|
+
* @param {BlocksWithNestedBlocks} blocksWithNestedBlocks flag for blocks that have nested blocks
|
1185
|
+
* @param {BlockConnections} blockConnections connection for blocks
|
1186
|
+
* @param {MaskByChunk} maskByChunk mapping from chunk to module mask
|
1361
1187
|
*/
|
1362
1188
|
const connectChunkGroups = (
|
1363
1189
|
compilation,
|
1364
1190
|
blocksWithNestedBlocks,
|
1365
1191
|
blockConnections,
|
1366
|
-
|
1192
|
+
maskByChunk
|
1367
1193
|
) => {
|
1368
1194
|
const { chunkGraph } = compilation;
|
1369
1195
|
|
@@ -1371,15 +1197,13 @@ const connectChunkGroups = (
|
|
1371
1197
|
* Helper function to check if all modules of a chunk are available
|
1372
1198
|
*
|
1373
1199
|
* @param {ChunkGroup} chunkGroup the chunkGroup to scan
|
1374
|
-
* @param {
|
1200
|
+
* @param {bigint} availableModules the comparator set
|
1375
1201
|
* @returns {boolean} return true if all modules of a chunk are available
|
1376
1202
|
*/
|
1377
1203
|
const areModulesAvailable = (chunkGroup, availableModules) => {
|
1378
1204
|
for (const chunk of chunkGroup.chunks) {
|
1379
|
-
|
1380
|
-
|
1381
|
-
return false;
|
1382
|
-
}
|
1205
|
+
const chunkMask = /** @type {bigint} */ (maskByChunk.get(chunk));
|
1206
|
+
if ((chunkMask & availableModules) !== chunkMask) return false;
|
1383
1207
|
}
|
1384
1208
|
return true;
|
1385
1209
|
};
|
@@ -1398,7 +1222,7 @@ const connectChunkGroups = (
|
|
1398
1222
|
connections.every(({ chunkGroup, originChunkGroupInfo }) =>
|
1399
1223
|
areModulesAvailable(
|
1400
1224
|
chunkGroup,
|
1401
|
-
originChunkGroupInfo.resultingAvailableModules
|
1225
|
+
/** @type {bigint} */ (originChunkGroupInfo.resultingAvailableModules)
|
1402
1226
|
)
|
1403
1227
|
)
|
1404
1228
|
) {
|
@@ -1444,7 +1268,7 @@ const cleanupUnconnectedGroups = (compilation, allCreatedChunkGroups) => {
|
|
1444
1268
|
/**
|
1445
1269
|
* This method creates the Chunk graph from the Module graph
|
1446
1270
|
* @param {Compilation} compilation the compilation
|
1447
|
-
* @param {
|
1271
|
+
* @param {InputEntrypointsAndModules} inputEntrypointsAndModules chunk groups which are processed with the modules
|
1448
1272
|
* @returns {void}
|
1449
1273
|
*/
|
1450
1274
|
const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
@@ -1452,18 +1276,21 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
|
1452
1276
|
|
1453
1277
|
// SHARED STATE
|
1454
1278
|
|
1455
|
-
/** @type {
|
1279
|
+
/** @type {BlockConnections} */
|
1456
1280
|
const blockConnections = new Map();
|
1457
1281
|
|
1458
|
-
/** @type {
|
1282
|
+
/** @type {AllCreatedChunkGroups} */
|
1459
1283
|
const allCreatedChunkGroups = new Set();
|
1460
1284
|
|
1461
|
-
/** @type {
|
1285
|
+
/** @type {ChunkGroupInfoMap} */
|
1462
1286
|
const chunkGroupInfoMap = new Map();
|
1463
1287
|
|
1464
|
-
/** @type {
|
1288
|
+
/** @type {BlocksWithNestedBlocks} */
|
1465
1289
|
const blocksWithNestedBlocks = new Set();
|
1466
1290
|
|
1291
|
+
/** @type {MaskByChunk} */
|
1292
|
+
const maskByChunk = new Map();
|
1293
|
+
|
1467
1294
|
// PART ONE
|
1468
1295
|
|
1469
1296
|
logger.time("visitModules");
|
@@ -1474,7 +1301,8 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
|
1474
1301
|
chunkGroupInfoMap,
|
1475
1302
|
blockConnections,
|
1476
1303
|
blocksWithNestedBlocks,
|
1477
|
-
allCreatedChunkGroups
|
1304
|
+
allCreatedChunkGroups,
|
1305
|
+
maskByChunk
|
1478
1306
|
);
|
1479
1307
|
logger.timeEnd("visitModules");
|
1480
1308
|
|
@@ -1485,7 +1313,7 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
|
1485
1313
|
compilation,
|
1486
1314
|
blocksWithNestedBlocks,
|
1487
1315
|
blockConnections,
|
1488
|
-
|
1316
|
+
maskByChunk
|
1489
1317
|
);
|
1490
1318
|
logger.timeEnd("connectChunkGroups");
|
1491
1319
|
|