UNPKG

41.1 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const util = require("util");
9const SortableSet = require("./util/SortableSet");
10const {
11 compareModulesById,
12 compareIterables,
13 compareModulesByIdentifier,
14 concatComparators,
15 compareSelect,
16 compareIds
17} = require("./util/comparators");
18const findGraphRoots = require("./util/findGraphRoots");
19const {
20 RuntimeSpecMap,
21 RuntimeSpecSet,
22 runtimeToString,
23 mergeRuntime
24} = require("./util/runtime");
25
26/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
27/** @typedef {import("./Chunk")} Chunk */
28/** @typedef {import("./ChunkGroup")} ChunkGroup */
29/** @typedef {import("./Entrypoint")} Entrypoint */
30/** @typedef {import("./Module")} Module */
31/** @typedef {import("./ModuleGraph")} ModuleGraph */
32/** @typedef {import("./RuntimeModule")} RuntimeModule */
33/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
34
35/** @type {ReadonlySet<string>} */
36const EMPTY_SET = new Set();
37
38const compareModuleIterables = compareIterables(compareModulesByIdentifier);
39
40/** @typedef {(c: Chunk, chunkGraph: ChunkGraph) => boolean} ChunkFilterPredicate */
41/** @typedef {(m: Module) => boolean} ModuleFilterPredicate */
42
43/**
44 * @typedef {Object} ChunkSizeOptions
45 * @property {number=} chunkOverhead constant overhead for a chunk
46 * @property {number=} entryChunkMultiplicator multiplicator for initial chunks
47 */
48
49/**
50 * @typedef {Object} ModuleHashInfo
51 * @property {string} hash
52 * @property {string} renderedHash
53 */
54
55/** @template T @typedef {(set: SortableSet<T>) => T[]} SetToArrayFunction<T> */
56
57/**
58 * @template T
59 * @param {SortableSet<T>} set the set
60 * @returns {T[]} set as array
61 */
62const getArray = set => {
63 return Array.from(set);
64};
65
66/**
67 * @param {SortableSet<Module>} set the set
68 * @returns {Map<string, SortableSet<Module>>} modules by source type
69 */
70const modulesBySourceType = set => {
71 /** @type {Map<string, SortableSet<Module>>} */
72 const map = new Map();
73 for (const module of set) {
74 for (const sourceType of module.getSourceTypes()) {
75 let innerSet = map.get(sourceType);
76 if (innerSet === undefined) {
77 innerSet = new SortableSet();
78 map.set(sourceType, innerSet);
79 }
80 innerSet.add(module);
81 }
82 }
83 for (const [key, innerSet] of map) {
84 // When all modules have the source type, we reuse the original SortableSet
85 // to benefit from the shared cache (especially for sorting)
86 if (innerSet.size === set.size) {
87 map.set(key, set);
88 }
89 }
90 return map;
91};
92
93/** @type {WeakMap<Function, any>} */
94const createOrderedArrayFunctionMap = new WeakMap();
95
96/**
97 * @template T
98 * @param {function(T, T): -1|0|1} comparator comparator function
99 * @returns {SetToArrayFunction<T>} set as ordered array
100 */
101const createOrderedArrayFunction = comparator => {
102 /** @type {SetToArrayFunction<T>} */
103 let fn = createOrderedArrayFunctionMap.get(comparator);
104 if (fn !== undefined) return fn;
105 fn = set => {
106 set.sortWith(comparator);
107 return Array.from(set);
108 };
109 createOrderedArrayFunctionMap.set(comparator, fn);
110 return fn;
111};
112
113/**
114 * @param {Iterable<Module>} modules the modules to get the count/size of
115 * @returns {number} the size of the modules
116 */
117const getModulesSize = modules => {
118 let size = 0;
119 for (const module of modules) {
120 for (const type of module.getSourceTypes()) {
121 size += module.size(type);
122 }
123 }
124 return size;
125};
126
127/**
128 * @param {Iterable<Module>} modules the sortable Set to get the size of
129 * @returns {Record<string, number>} the sizes of the modules
130 */
131const getModulesSizes = modules => {
132 let sizes = Object.create(null);
133 for (const module of modules) {
134 for (const type of module.getSourceTypes()) {
135 sizes[type] = (sizes[type] || 0) + module.size(type);
136 }
137 }
138 return sizes;
139};
140
141/**
142 * @param {Chunk} a chunk
143 * @param {Chunk} b chunk
144 * @returns {boolean} true, if a is always a parent of b
145 */
146const isAvailableChunk = (a, b) => {
147 const queue = new Set(b.groupsIterable);
148 for (const chunkGroup of queue) {
149 if (a.isInGroup(chunkGroup)) continue;
150 if (chunkGroup.isInitial()) return false;
151 for (const parent of chunkGroup.parentsIterable) {
152 queue.add(parent);
153 }
154 }
155 return true;
156};
157
158class ChunkGraphModule {
159 constructor() {
160 /** @type {SortableSet<Chunk>} */
161 this.chunks = new SortableSet();
162 /** @type {Set<Chunk> | undefined} */
163 this.entryInChunks = undefined;
164 /** @type {Set<Chunk> | undefined} */
165 this.runtimeInChunks = undefined;
166 /** @type {RuntimeSpecMap<ModuleHashInfo>} */
167 this.hashes = undefined;
168 /** @type {string | number} */
169 this.id = null;
170 /** @type {RuntimeSpecMap<Set<string>> | undefined} */
171 this.runtimeRequirements = undefined;
172 }
173}
174
175class ChunkGraphChunk {
176 constructor() {
177 /** @type {SortableSet<Module>} */
178 this.modules = new SortableSet();
179 /** @type {Map<Module, Entrypoint>} */
180 this.entryModules = new Map();
181 /** @type {SortableSet<RuntimeModule>} */
182 this.runtimeModules = new SortableSet();
183 /** @type {Set<RuntimeModule> | undefined} */
184 this.fullHashModules = undefined;
185 /** @type {Set<string> | undefined} */
186 this.runtimeRequirements = undefined;
187 /** @type {Set<string>} */
188 this.runtimeRequirementsInTree = new Set();
189 }
190}
191
192class ChunkGraph {
193 /**
194 * @param {ModuleGraph} moduleGraph the module graph
195 */
196 constructor(moduleGraph) {
197 /** @private @type {WeakMap<Module, ChunkGraphModule>} */
198 this._modules = new WeakMap();
199 /** @private @type {WeakMap<Chunk, ChunkGraphChunk>} */
200 this._chunks = new WeakMap();
201 /** @private @type {WeakMap<AsyncDependenciesBlock, ChunkGroup>} */
202 this._blockChunkGroups = new WeakMap();
203 /** @type {ModuleGraph} */
204 this.moduleGraph = moduleGraph;
205
206 this._getGraphRoots = this._getGraphRoots.bind(this);
207
208 // Caching
209 this._cacheChunkGraphModuleKey1 = undefined;
210 this._cacheChunkGraphModuleValue1 = undefined;
211 this._cacheChunkGraphModuleKey2 = undefined;
212 this._cacheChunkGraphModuleValue2 = undefined;
213 this._cacheChunkGraphChunkKey1 = undefined;
214 this._cacheChunkGraphChunkValue1 = undefined;
215 this._cacheChunkGraphChunkKey2 = undefined;
216 this._cacheChunkGraphChunkValue2 = undefined;
217 }
218
219 /**
220 * @private
221 * @param {Module} module the module
222 * @returns {ChunkGraphModule} internal module
223 */
224 _getChunkGraphModule(module) {
225 if (this._cacheChunkGraphModuleKey1 === module)
226 return this._cacheChunkGraphModuleValue1;
227 if (this._cacheChunkGraphModuleKey2 === module)
228 return this._cacheChunkGraphModuleValue2;
229 let cgm = this._modules.get(module);
230 if (cgm === undefined) {
231 cgm = new ChunkGraphModule();
232 this._modules.set(module, cgm);
233 }
234 this._cacheChunkGraphModuleKey2 = this._cacheChunkGraphModuleKey1;
235 this._cacheChunkGraphModuleValue2 = this._cacheChunkGraphModuleValue1;
236 this._cacheChunkGraphModuleKey1 = module;
237 this._cacheChunkGraphModuleValue1 = cgm;
238 return cgm;
239 }
240
241 /**
242 * @private
243 * @param {Chunk} chunk the chunk
244 * @returns {ChunkGraphChunk} internal chunk
245 */
246 _getChunkGraphChunk(chunk) {
247 if (this._cacheChunkGraphChunkKey1 === chunk)
248 return this._cacheChunkGraphChunkValue1;
249 if (this._cacheChunkGraphChunkKey2 === chunk)
250 return this._cacheChunkGraphChunkValue2;
251 let cgc = this._chunks.get(chunk);
252 if (cgc === undefined) {
253 cgc = new ChunkGraphChunk();
254 this._chunks.set(chunk, cgc);
255 }
256 this._cacheChunkGraphChunkKey2 = this._cacheChunkGraphChunkKey1;
257 this._cacheChunkGraphChunkValue2 = this._cacheChunkGraphChunkValue1;
258 this._cacheChunkGraphChunkKey1 = chunk;
259 this._cacheChunkGraphChunkValue1 = cgc;
260 return cgc;
261 }
262
263 /**
264 * @param {SortableSet<Module>} set the sortable Set to get the roots of
265 * @returns {Module[]} the graph roots
266 */
267 _getGraphRoots(set) {
268 const { moduleGraph } = this;
269 return Array.from(
270 findGraphRoots(set, module => {
271 /** @type {Set<Module>} */
272 const set = new Set();
273 for (const connection of moduleGraph.getOutgoingConnections(module)) {
274 if (!connection.module) continue;
275 set.add(connection.module);
276 }
277 return set;
278 })
279 ).sort(compareModulesByIdentifier);
280 }
281
282 /**
283 * @param {Chunk} chunk the new chunk
284 * @param {Module} module the module
285 * @returns {void}
286 */
287 connectChunkAndModule(chunk, module) {
288 const cgm = this._getChunkGraphModule(module);
289 const cgc = this._getChunkGraphChunk(chunk);
290 cgm.chunks.add(chunk);
291 cgc.modules.add(module);
292 }
293
294 /**
295 * @param {Chunk} chunk the chunk
296 * @param {Module} module the module
297 * @returns {void}
298 */
299 disconnectChunkAndModule(chunk, module) {
300 const cgm = this._getChunkGraphModule(module);
301 const cgc = this._getChunkGraphChunk(chunk);
302 cgc.modules.delete(module);
303 cgm.chunks.delete(chunk);
304 }
305
306 /**
307 * @param {Chunk} chunk the chunk which will be disconnected
308 * @returns {void}
309 */
310 disconnectChunk(chunk) {
311 const cgc = this._getChunkGraphChunk(chunk);
312 for (const module of cgc.modules) {
313 const cgm = this._getChunkGraphModule(module);
314 cgm.chunks.delete(chunk);
315 }
316 cgc.modules.clear();
317 chunk.disconnectFromGroups();
318 }
319
320 /**
321 * @param {Chunk} chunk the chunk
322 * @param {Iterable<Module>} modules the modules
323 * @returns {void}
324 */
325 attachModules(chunk, modules) {
326 const cgc = this._getChunkGraphChunk(chunk);
327 for (const module of modules) {
328 cgc.modules.add(module);
329 }
330 }
331
332 /**
333 * @param {Chunk} chunk the chunk
334 * @param {Iterable<RuntimeModule>} modules the runtime modules
335 * @returns {void}
336 */
337 attachRuntimeModules(chunk, modules) {
338 const cgc = this._getChunkGraphChunk(chunk);
339 for (const module of modules) {
340 cgc.runtimeModules.add(module);
341 }
342 }
343
344 /**
345 * @param {Chunk} chunk the chunk
346 * @param {Iterable<RuntimeModule>} modules the modules that require a full hash
347 * @returns {void}
348 */
349 attachFullHashModules(chunk, modules) {
350 const cgc = this._getChunkGraphChunk(chunk);
351 if (cgc.fullHashModules === undefined) cgc.fullHashModules = new Set();
352 for (const module of modules) {
353 cgc.fullHashModules.add(module);
354 }
355 }
356
357 /**
358 * @param {Module} oldModule the replaced module
359 * @param {Module} newModule the replacing module
360 * @returns {void}
361 */
362 replaceModule(oldModule, newModule) {
363 const oldCgm = this._getChunkGraphModule(oldModule);
364 const newCgm = this._getChunkGraphModule(newModule);
365
366 for (const chunk of oldCgm.chunks) {
367 const cgc = this._getChunkGraphChunk(chunk);
368 cgc.modules.delete(oldModule);
369 cgc.modules.add(newModule);
370 newCgm.chunks.add(chunk);
371 }
372 oldCgm.chunks.clear();
373
374 if (oldCgm.entryInChunks !== undefined) {
375 if (newCgm.entryInChunks === undefined) {
376 newCgm.entryInChunks = new Set();
377 }
378 for (const chunk of oldCgm.entryInChunks) {
379 const cgc = this._getChunkGraphChunk(chunk);
380 const old = cgc.entryModules.get(oldModule);
381 /** @type {Map<Module, Entrypoint>} */
382 const newEntryModules = new Map();
383 for (const [m, cg] of cgc.entryModules) {
384 if (m === oldModule) {
385 newEntryModules.set(newModule, old);
386 } else {
387 newEntryModules.set(m, cg);
388 }
389 }
390 cgc.entryModules = newEntryModules;
391 newCgm.entryInChunks.add(chunk);
392 }
393 oldCgm.entryInChunks = undefined;
394 }
395
396 if (oldCgm.runtimeInChunks !== undefined) {
397 if (newCgm.runtimeInChunks === undefined) {
398 newCgm.runtimeInChunks = new Set();
399 }
400 for (const chunk of oldCgm.runtimeInChunks) {
401 const cgc = this._getChunkGraphChunk(chunk);
402 cgc.runtimeModules.delete(/** @type {RuntimeModule} */ (oldModule));
403 cgc.runtimeModules.add(/** @type {RuntimeModule} */ (newModule));
404 newCgm.runtimeInChunks.add(chunk);
405 if (
406 cgc.fullHashModules !== undefined &&
407 cgc.fullHashModules.has(/** @type {RuntimeModule} */ (oldModule))
408 ) {
409 cgc.fullHashModules.delete(/** @type {RuntimeModule} */ (oldModule));
410 cgc.fullHashModules.add(/** @type {RuntimeModule} */ (newModule));
411 }
412 }
413 oldCgm.runtimeInChunks = undefined;
414 }
415 }
416
417 /**
418 * @param {Module} module the checked module
419 * @param {Chunk} chunk the checked chunk
420 * @returns {boolean} true, if the chunk contains the module
421 */
422 isModuleInChunk(module, chunk) {
423 const cgc = this._getChunkGraphChunk(chunk);
424 return cgc.modules.has(module);
425 }
426
427 /**
428 * @param {Module} module the checked module
429 * @param {ChunkGroup} chunkGroup the checked chunk group
430 * @returns {boolean} true, if the chunk contains the module
431 */
432 isModuleInChunkGroup(module, chunkGroup) {
433 for (const chunk of chunkGroup.chunks) {
434 if (this.isModuleInChunk(module, chunk)) return true;
435 }
436 return false;
437 }
438
439 /**
440 * @param {Module} module the checked module
441 * @returns {boolean} true, if the module is entry of any chunk
442 */
443 isEntryModule(module) {
444 const cgm = this._getChunkGraphModule(module);
445 return cgm.entryInChunks !== undefined;
446 }
447
448 /**
449 * @param {Module} module the module
450 * @returns {Iterable<Chunk>} iterable of chunks (do not modify)
451 */
452 getModuleChunksIterable(module) {
453 const cgm = this._getChunkGraphModule(module);
454 return cgm.chunks;
455 }
456
457 /**
458 * @param {Module} module the module
459 * @param {function(Chunk, Chunk): -1|0|1} sortFn sort function
460 * @returns {Iterable<Chunk>} iterable of chunks (do not modify)
461 */
462 getOrderedModuleChunksIterable(module, sortFn) {
463 const cgm = this._getChunkGraphModule(module);
464 cgm.chunks.sortWith(sortFn);
465 return cgm.chunks;
466 }
467
468 /**
469 * @param {Module} module the module
470 * @returns {Chunk[]} array of chunks (cached, do not modify)
471 */
472 getModuleChunks(module) {
473 const cgm = this._getChunkGraphModule(module);
474 return cgm.chunks.getFromCache(getArray);
475 }
476
477 /**
478 * @param {Module} module the module
479 * @returns {number} the number of chunk which contain the module
480 */
481 getNumberOfModuleChunks(module) {
482 const cgm = this._getChunkGraphModule(module);
483 return cgm.chunks.size;
484 }
485
486 /**
487 * @param {Module} module the module
488 * @returns {RuntimeSpecSet} runtimes
489 */
490 getModuleRuntimes(module) {
491 const cgm = this._getChunkGraphModule(module);
492 const runtimes = new RuntimeSpecSet();
493 for (const chunk of cgm.chunks) {
494 runtimes.add(chunk.runtime);
495 }
496 return runtimes;
497 }
498
499 /**
500 * @param {Chunk} chunk the chunk
501 * @returns {number} the number of module which are contained in this chunk
502 */
503 getNumberOfChunkModules(chunk) {
504 const cgc = this._getChunkGraphChunk(chunk);
505 return cgc.modules.size;
506 }
507
508 /**
509 * @param {Chunk} chunk the chunk
510 * @returns {Iterable<Module>} return the modules for this chunk
511 */
512 getChunkModulesIterable(chunk) {
513 const cgc = this._getChunkGraphChunk(chunk);
514 return cgc.modules;
515 }
516
517 /**
518 * @param {Chunk} chunk the chunk
519 * @param {string} sourceType source type
520 * @returns {Iterable<Module> | undefined} return the modules for this chunk
521 */
522 getChunkModulesIterableBySourceType(chunk, sourceType) {
523 const cgc = this._getChunkGraphChunk(chunk);
524 const modulesWithSourceType = cgc.modules
525 .getFromUnorderedCache(modulesBySourceType)
526 .get(sourceType);
527 return modulesWithSourceType;
528 }
529
530 /**
531 * @param {Chunk} chunk the chunk
532 * @param {function(Module, Module): -1|0|1} comparator comparator function
533 * @returns {Iterable<Module>} return the modules for this chunk
534 */
535 getOrderedChunkModulesIterable(chunk, comparator) {
536 const cgc = this._getChunkGraphChunk(chunk);
537 cgc.modules.sortWith(comparator);
538 return cgc.modules;
539 }
540
541 /**
542 * @param {Chunk} chunk the chunk
543 * @param {string} sourceType source type
544 * @param {function(Module, Module): -1|0|1} comparator comparator function
545 * @returns {Iterable<Module> | undefined} return the modules for this chunk
546 */
547 getOrderedChunkModulesIterableBySourceType(chunk, sourceType, comparator) {
548 const cgc = this._getChunkGraphChunk(chunk);
549 const modulesWithSourceType = cgc.modules
550 .getFromUnorderedCache(modulesBySourceType)
551 .get(sourceType);
552 if (modulesWithSourceType === undefined) return undefined;
553 modulesWithSourceType.sortWith(comparator);
554 return modulesWithSourceType;
555 }
556
557 /**
558 * @param {Chunk} chunk the chunk
559 * @returns {Module[]} return the modules for this chunk (cached, do not modify)
560 */
561 getChunkModules(chunk) {
562 const cgc = this._getChunkGraphChunk(chunk);
563 return cgc.modules.getFromUnorderedCache(getArray);
564 }
565
566 /**
567 * @param {Chunk} chunk the chunk
568 * @param {function(Module, Module): -1|0|1} comparator comparator function
569 * @returns {Module[]} return the modules for this chunk (cached, do not modify)
570 */
571 getOrderedChunkModules(chunk, comparator) {
572 const cgc = this._getChunkGraphChunk(chunk);
573 const arrayFunction = createOrderedArrayFunction(comparator);
574 return cgc.modules.getFromUnorderedCache(arrayFunction);
575 }
576
577 /**
578 * @param {Chunk} chunk the chunk
579 * @param {ModuleFilterPredicate} filterFn function used to filter modules
580 * @param {boolean} includeAllChunks all chunks or only async chunks
581 * @returns {Record<string|number, (string|number)[]>} chunk to module ids object
582 */
583 getChunkModuleIdMap(chunk, filterFn, includeAllChunks = false) {
584 /** @type {Record<string|number, (string|number)[]>} */
585 const chunkModuleIdMap = Object.create(null);
586
587 for (const asyncChunk of includeAllChunks
588 ? chunk.getAllReferencedChunks()
589 : chunk.getAllAsyncChunks()) {
590 /** @type {(string|number)[]} */
591 let array;
592 for (const module of this.getOrderedChunkModulesIterable(
593 asyncChunk,
594 compareModulesById(this)
595 )) {
596 if (filterFn(module)) {
597 if (array === undefined) {
598 array = [];
599 chunkModuleIdMap[asyncChunk.id] = array;
600 }
601 const moduleId = this.getModuleId(module);
602 array.push(moduleId);
603 }
604 }
605 }
606
607 return chunkModuleIdMap;
608 }
609
610 /**
611 * @param {Chunk} chunk the chunk
612 * @param {ModuleFilterPredicate} filterFn function used to filter modules
613 * @param {number} hashLength length of the hash
614 * @param {boolean} includeAllChunks all chunks or only async chunks
615 * @returns {Record<string|number, Record<string|number, string>>} chunk to module id to module hash object
616 */
617 getChunkModuleRenderedHashMap(
618 chunk,
619 filterFn,
620 hashLength = 0,
621 includeAllChunks = false
622 ) {
623 /** @type {Record<string|number, Record<string|number, string>>} */
624 const chunkModuleHashMap = Object.create(null);
625
626 for (const asyncChunk of includeAllChunks
627 ? chunk.getAllReferencedChunks()
628 : chunk.getAllAsyncChunks()) {
629 /** @type {Record<string|number, string>} */
630 let idToHashMap;
631 for (const module of this.getOrderedChunkModulesIterable(
632 asyncChunk,
633 compareModulesById(this)
634 )) {
635 if (filterFn(module)) {
636 if (idToHashMap === undefined) {
637 idToHashMap = Object.create(null);
638 chunkModuleHashMap[asyncChunk.id] = idToHashMap;
639 }
640 const moduleId = this.getModuleId(module);
641 const hash = this.getRenderedModuleHash(module, asyncChunk.runtime);
642 idToHashMap[moduleId] = hashLength ? hash.slice(0, hashLength) : hash;
643 }
644 }
645 }
646
647 return chunkModuleHashMap;
648 }
649
650 /**
651 * @param {Chunk} chunk the chunk
652 * @param {ChunkFilterPredicate} filterFn function used to filter chunks
653 * @returns {Record<string|number, boolean>} chunk map
654 */
655 getChunkConditionMap(chunk, filterFn) {
656 const map = Object.create(null);
657 for (const asyncChunk of chunk.getAllAsyncChunks()) {
658 map[asyncChunk.id] = filterFn(asyncChunk, this);
659 }
660 for (const depChunk of this.getChunkEntryDependentChunksIterable(chunk)) {
661 map[depChunk.id] = filterFn(depChunk, this);
662 }
663 return map;
664 }
665
666 /**
667 * @param {Chunk} chunk the chunk
668 * @param {ModuleFilterPredicate} filterFn predicate function used to filter modules
669 * @param {ChunkFilterPredicate=} filterChunkFn predicate function used to filter chunks
670 * @returns {boolean} return true if module exists in graph
671 */
672 hasModuleInGraph(chunk, filterFn, filterChunkFn) {
673 const queue = new Set(chunk.groupsIterable);
674 const chunksProcessed = new Set();
675
676 for (const chunkGroup of queue) {
677 for (const innerChunk of chunkGroup.chunks) {
678 if (!chunksProcessed.has(innerChunk)) {
679 chunksProcessed.add(innerChunk);
680 if (!filterChunkFn || filterChunkFn(innerChunk, this)) {
681 for (const module of this.getChunkModulesIterable(innerChunk)) {
682 if (filterFn(module)) {
683 return true;
684 }
685 }
686 }
687 }
688 }
689 for (const child of chunkGroup.childrenIterable) {
690 queue.add(child);
691 }
692 }
693 return false;
694 }
695
696 /**
697 * @param {Chunk} chunkA first chunk
698 * @param {Chunk} chunkB second chunk
699 * @returns {-1|0|1} this is a comparator function like sort and returns -1, 0, or 1 based on sort order
700 */
701 compareChunks(chunkA, chunkB) {
702 const cgcA = this._getChunkGraphChunk(chunkA);
703 const cgcB = this._getChunkGraphChunk(chunkB);
704 if (cgcA.modules.size > cgcB.modules.size) return -1;
705 if (cgcA.modules.size < cgcB.modules.size) return 1;
706 cgcA.modules.sortWith(compareModulesByIdentifier);
707 cgcB.modules.sortWith(compareModulesByIdentifier);
708 return compareModuleIterables(cgcA.modules, cgcB.modules);
709 }
710
711 /**
712 * @param {Chunk} chunk the chunk
713 * @returns {number} total size of all modules in the chunk
714 */
715 getChunkModulesSize(chunk) {
716 const cgc = this._getChunkGraphChunk(chunk);
717 return cgc.modules.getFromUnorderedCache(getModulesSize);
718 }
719
720 /**
721 * @param {Chunk} chunk the chunk
722 * @returns {Record<string, number>} total sizes of all modules in the chunk by source type
723 */
724 getChunkModulesSizes(chunk) {
725 const cgc = this._getChunkGraphChunk(chunk);
726 return cgc.modules.getFromUnorderedCache(getModulesSizes);
727 }
728
729 /**
730 * @param {Chunk} chunk the chunk
731 * @returns {Module[]} root modules of the chunks (ordered by identifier)
732 */
733 getChunkRootModules(chunk) {
734 const cgc = this._getChunkGraphChunk(chunk);
735 return cgc.modules.getFromUnorderedCache(this._getGraphRoots);
736 }
737
738 /**
739 * @param {Chunk} chunk the chunk
740 * @param {ChunkSizeOptions} options options object
741 * @returns {number} total size of the chunk
742 */
743 getChunkSize(chunk, options = {}) {
744 const cgc = this._getChunkGraphChunk(chunk);
745 const modulesSize = cgc.modules.getFromUnorderedCache(getModulesSize);
746 const chunkOverhead =
747 typeof options.chunkOverhead === "number" ? options.chunkOverhead : 10000;
748 const entryChunkMultiplicator =
749 typeof options.entryChunkMultiplicator === "number"
750 ? options.entryChunkMultiplicator
751 : 10;
752 return (
753 chunkOverhead +
754 modulesSize * (chunk.canBeInitial() ? entryChunkMultiplicator : 1)
755 );
756 }
757
758 /**
759 * @param {Chunk} chunkA chunk
760 * @param {Chunk} chunkB chunk
761 * @param {ChunkSizeOptions} options options object
762 * @returns {number} total size of the chunk or false if chunks can't be integrated
763 */
764 getIntegratedChunksSize(chunkA, chunkB, options = {}) {
765 const cgcA = this._getChunkGraphChunk(chunkA);
766 const cgcB = this._getChunkGraphChunk(chunkB);
767 const allModules = new Set(cgcA.modules);
768 for (const m of cgcB.modules) allModules.add(m);
769 let modulesSize = getModulesSize(allModules);
770 const chunkOverhead =
771 typeof options.chunkOverhead === "number" ? options.chunkOverhead : 10000;
772 const entryChunkMultiplicator =
773 typeof options.entryChunkMultiplicator === "number"
774 ? options.entryChunkMultiplicator
775 : 10;
776 return (
777 chunkOverhead +
778 modulesSize *
779 (chunkA.canBeInitial() || chunkB.canBeInitial()
780 ? entryChunkMultiplicator
781 : 1)
782 );
783 }
784
785 /**
786 * @param {Chunk} chunkA chunk
787 * @param {Chunk} chunkB chunk
788 * @returns {boolean} true, if chunks could be integrated
789 */
790 canChunksBeIntegrated(chunkA, chunkB) {
791 if (chunkA.preventIntegration || chunkB.preventIntegration) {
792 return false;
793 }
794
795 const hasRuntimeA = chunkA.hasRuntime();
796 const hasRuntimeB = chunkB.hasRuntime();
797
798 if (hasRuntimeA !== hasRuntimeB) {
799 if (hasRuntimeA) {
800 return isAvailableChunk(chunkA, chunkB);
801 } else if (hasRuntimeB) {
802 return isAvailableChunk(chunkB, chunkA);
803 } else {
804 return false;
805 }
806 }
807
808 if (
809 this.getNumberOfEntryModules(chunkA) > 0 ||
810 this.getNumberOfEntryModules(chunkB) > 0
811 ) {
812 return false;
813 }
814
815 return true;
816 }
817
818 /**
819 * @param {Chunk} chunkA the target chunk
820 * @param {Chunk} chunkB the chunk to integrate
821 * @returns {void}
822 */
823 integrateChunks(chunkA, chunkB) {
824 // Decide for one name (deterministic)
825 if (chunkA.name && chunkB.name) {
826 if (
827 this.getNumberOfEntryModules(chunkA) > 0 ===
828 this.getNumberOfEntryModules(chunkB) > 0
829 ) {
830 // When both chunks have entry modules or none have one, use
831 // shortest name
832 if (chunkA.name.length !== chunkB.name.length) {
833 chunkA.name =
834 chunkA.name.length < chunkB.name.length ? chunkA.name : chunkB.name;
835 } else {
836 chunkA.name = chunkA.name < chunkB.name ? chunkA.name : chunkB.name;
837 }
838 } else if (this.getNumberOfEntryModules(chunkB) > 0) {
839 // Pick the name of the chunk with the entry module
840 chunkA.name = chunkB.name;
841 }
842 } else if (chunkB.name) {
843 chunkA.name = chunkB.name;
844 }
845
846 // Merge id name hints
847 for (const hint of chunkB.idNameHints) {
848 chunkA.idNameHints.add(hint);
849 }
850
851 // Merge runtime
852 chunkA.runtime = mergeRuntime(chunkA.runtime, chunkB.runtime);
853
854 // getChunkModules is used here to create a clone, because disconnectChunkAndModule modifies
855 for (const module of this.getChunkModules(chunkB)) {
856 this.disconnectChunkAndModule(chunkB, module);
857 this.connectChunkAndModule(chunkA, module);
858 }
859
860 for (const [module, chunkGroup] of Array.from(
861 this.getChunkEntryModulesWithChunkGroupIterable(chunkB)
862 )) {
863 this.disconnectChunkAndEntryModule(chunkB, module);
864 this.connectChunkAndEntryModule(chunkA, module, chunkGroup);
865 }
866
867 for (const chunkGroup of chunkB.groupsIterable) {
868 chunkGroup.replaceChunk(chunkB, chunkA);
869 chunkA.addGroup(chunkGroup);
870 chunkB.removeGroup(chunkGroup);
871 }
872 }
873
874 /**
875 * @param {Module} module the checked module
876 * @param {Chunk} chunk the checked chunk
877 * @returns {boolean} true, if the chunk contains the module as entry
878 */
879 isEntryModuleInChunk(module, chunk) {
880 const cgc = this._getChunkGraphChunk(chunk);
881 return cgc.entryModules.has(module);
882 }
883
884 /**
885 * @param {Chunk} chunk the new chunk
886 * @param {Module} module the entry module
887 * @param {Entrypoint=} entrypoint the chunk group which must be loaded before the module is executed
888 * @returns {void}
889 */
890 connectChunkAndEntryModule(chunk, module, entrypoint) {
891 const cgm = this._getChunkGraphModule(module);
892 const cgc = this._getChunkGraphChunk(chunk);
893 if (cgm.entryInChunks === undefined) {
894 cgm.entryInChunks = new Set();
895 }
896 cgm.entryInChunks.add(chunk);
897 cgc.entryModules.set(module, entrypoint);
898 }
899
900 /**
901 * @param {Chunk} chunk the new chunk
902 * @param {RuntimeModule} module the runtime module
903 * @returns {void}
904 */
905 connectChunkAndRuntimeModule(chunk, module) {
906 const cgm = this._getChunkGraphModule(module);
907 const cgc = this._getChunkGraphChunk(chunk);
908 if (cgm.runtimeInChunks === undefined) {
909 cgm.runtimeInChunks = new Set();
910 }
911 cgm.runtimeInChunks.add(chunk);
912 cgc.runtimeModules.add(module);
913 }
914
915 /**
916 * @param {Chunk} chunk the new chunk
917 * @param {RuntimeModule} module the module that require a full hash
918 * @returns {void}
919 */
920 addFullHashModuleToChunk(chunk, module) {
921 const cgc = this._getChunkGraphChunk(chunk);
922 if (cgc.fullHashModules === undefined) cgc.fullHashModules = new Set();
923 cgc.fullHashModules.add(module);
924 }
925
926 /**
927 * @param {Chunk} chunk the new chunk
928 * @param {Module} module the entry module
929 * @returns {void}
930 */
931 disconnectChunkAndEntryModule(chunk, module) {
932 const cgm = this._getChunkGraphModule(module);
933 const cgc = this._getChunkGraphChunk(chunk);
934 cgm.entryInChunks.delete(chunk);
935 if (cgm.entryInChunks.size === 0) {
936 cgm.entryInChunks = undefined;
937 }
938 cgc.entryModules.delete(module);
939 }
940
941 /**
942 * @param {Chunk} chunk the new chunk
943 * @param {RuntimeModule} module the runtime module
944 * @returns {void}
945 */
946 disconnectChunkAndRuntimeModule(chunk, module) {
947 const cgm = this._getChunkGraphModule(module);
948 const cgc = this._getChunkGraphChunk(chunk);
949 cgm.runtimeInChunks.delete(chunk);
950 if (cgm.runtimeInChunks.size === 0) {
951 cgm.runtimeInChunks = undefined;
952 }
953 cgc.runtimeModules.delete(module);
954 }
955
956 /**
957 * @param {Module} module the entry module, it will no longer be entry
958 * @returns {void}
959 */
960 disconnectEntryModule(module) {
961 const cgm = this._getChunkGraphModule(module);
962 for (const chunk of cgm.entryInChunks) {
963 const cgc = this._getChunkGraphChunk(chunk);
964 cgc.entryModules.delete(module);
965 }
966 cgm.entryInChunks = undefined;
967 }
968
969 /**
970 * @param {Chunk} chunk the chunk, for which all entries will be removed
971 * @returns {void}
972 */
973 disconnectEntries(chunk) {
974 const cgc = this._getChunkGraphChunk(chunk);
975 for (const module of cgc.entryModules.keys()) {
976 const cgm = this._getChunkGraphModule(module);
977 cgm.entryInChunks.delete(chunk);
978 if (cgm.entryInChunks.size === 0) {
979 cgm.entryInChunks = undefined;
980 }
981 }
982 cgc.entryModules.clear();
983 }
984
985 /**
986 * @param {Chunk} chunk the chunk
987 * @returns {number} the amount of entry modules in chunk
988 */
989 getNumberOfEntryModules(chunk) {
990 const cgc = this._getChunkGraphChunk(chunk);
991 return cgc.entryModules.size;
992 }
993
994 /**
995 * @param {Chunk} chunk the chunk
996 * @returns {number} the amount of entry modules in chunk
997 */
998 getNumberOfRuntimeModules(chunk) {
999 const cgc = this._getChunkGraphChunk(chunk);
1000 return cgc.runtimeModules.size;
1001 }
1002
1003 /**
1004 * @param {Chunk} chunk the chunk
1005 * @returns {Iterable<Module>} iterable of modules (do not modify)
1006 */
1007 getChunkEntryModulesIterable(chunk) {
1008 const cgc = this._getChunkGraphChunk(chunk);
1009 return cgc.entryModules.keys();
1010 }
1011
1012 /**
1013 * @param {Chunk} chunk the chunk
1014 * @returns {Iterable<Chunk>} iterable of chunks
1015 */
1016 getChunkEntryDependentChunksIterable(chunk) {
1017 const cgc = this._getChunkGraphChunk(chunk);
1018 /** @type {Set<Chunk>} */
1019 const set = new Set();
1020 for (const chunkGroup of cgc.entryModules.values()) {
1021 for (const c of chunkGroup.chunks) {
1022 if (c !== chunk) {
1023 set.add(c);
1024 }
1025 }
1026 }
1027 return set;
1028 }
1029
1030 /**
1031 * @param {Chunk} chunk the chunk
1032 * @returns {boolean} true, when it has dependent chunks
1033 */
1034 hasChunkEntryDependentChunks(chunk) {
1035 const cgc = this._getChunkGraphChunk(chunk);
1036 for (const chunkGroup of cgc.entryModules.values()) {
1037 for (const c of chunkGroup.chunks) {
1038 if (c !== chunk) {
1039 return true;
1040 }
1041 }
1042 }
1043 return false;
1044 }
1045
1046 /**
1047 * @param {Chunk} chunk the chunk
1048 * @returns {Iterable<RuntimeModule>} iterable of modules (do not modify)
1049 */
1050 getChunkRuntimeModulesIterable(chunk) {
1051 const cgc = this._getChunkGraphChunk(chunk);
1052 return cgc.runtimeModules;
1053 }
1054
1055 /**
1056 * @param {Chunk} chunk the chunk
1057 * @returns {RuntimeModule[]} array of modules in order of execution
1058 */
1059 getChunkRuntimeModulesInOrder(chunk) {
1060 const cgc = this._getChunkGraphChunk(chunk);
1061 const array = Array.from(cgc.runtimeModules);
1062 array.sort(
1063 concatComparators(
1064 compareSelect(
1065 /**
1066 * @param {RuntimeModule} r runtime module
1067 * @returns {number=} stage
1068 */
1069 r => r.stage,
1070 compareIds
1071 ),
1072 compareModulesByIdentifier
1073 )
1074 );
1075 return array;
1076 }
1077
1078 /**
1079 * @param {Chunk} chunk the chunk
1080 * @returns {Iterable<RuntimeModule> | undefined} iterable of modules (do not modify)
1081 */
1082 getChunkFullHashModulesIterable(chunk) {
1083 const cgc = this._getChunkGraphChunk(chunk);
1084 return cgc.fullHashModules;
1085 }
1086
1087 /** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */
1088
1089 /**
1090 * @param {Chunk} chunk the chunk
1091 * @returns {Iterable<EntryModuleWithChunkGroup>} iterable of modules (do not modify)
1092 */
1093 getChunkEntryModulesWithChunkGroupIterable(chunk) {
1094 const cgc = this._getChunkGraphChunk(chunk);
1095 return cgc.entryModules;
1096 }
1097
1098 /**
1099 * @param {AsyncDependenciesBlock} depBlock the async block
1100 * @returns {ChunkGroup} the chunk group
1101 */
1102 getBlockChunkGroup(depBlock) {
1103 return this._blockChunkGroups.get(depBlock);
1104 }
1105
1106 /**
1107 * @param {AsyncDependenciesBlock} depBlock the async block
1108 * @param {ChunkGroup} chunkGroup the chunk group
1109 * @returns {void}
1110 */
1111 connectBlockAndChunkGroup(depBlock, chunkGroup) {
1112 this._blockChunkGroups.set(depBlock, chunkGroup);
1113 chunkGroup.addBlock(depBlock);
1114 }
1115
1116 /**
1117 * @param {ChunkGroup} chunkGroup the chunk group
1118 * @returns {void}
1119 */
1120 disconnectChunkGroup(chunkGroup) {
1121 for (const block of chunkGroup.blocksIterable) {
1122 this._blockChunkGroups.delete(block);
1123 }
1124 // TODO refactor by moving blocks list into ChunkGraph
1125 chunkGroup._blocks.clear();
1126 }
1127
1128 /**
1129 * @param {Module} module the module
1130 * @returns {string | number} the id of the module
1131 */
1132 getModuleId(module) {
1133 const cgm = this._getChunkGraphModule(module);
1134 return cgm.id;
1135 }
1136
1137 /**
1138 * @param {Module} module the module
1139 * @param {string | number} id the id of the module
1140 * @returns {void}
1141 */
1142 setModuleId(module, id) {
1143 const cgm = this._getChunkGraphModule(module);
1144 cgm.id = id;
1145 }
1146
1147 /**
1148 * @param {Module} module the module
1149 * @param {RuntimeSpec} runtime the runtime
1150 * @returns {ModuleHashInfo} hash
1151 */
1152 _getModuleHashInfo(module, runtime) {
1153 const cgm = this._getChunkGraphModule(module);
1154 const hashes = cgm.hashes;
1155 if (hashes && runtime === undefined) {
1156 const hashInfoItems = new Set(hashes.values());
1157 if (hashInfoItems.size !== 1) {
1158 throw new Error(
1159 `No unique hash info entry for unspecified runtime for ${module.identifier()} (existing runtimes: ${Array.from(
1160 hashes.keys(),
1161 r => runtimeToString(r)
1162 ).join(", ")}).
1163Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").`
1164 );
1165 }
1166 return hashInfoItems.values().next().value;
1167 } else {
1168 const hashInfo = hashes && hashes.get(runtime);
1169 if (!hashInfo) {
1170 throw new Error(
1171 `Module ${module.identifier()} has no hash info for runtime ${runtimeToString(
1172 runtime
1173 )} (available runtimes ${
1174 hashes && Array.from(hashes.keys(), runtimeToString).join(", ")
1175 })`
1176 );
1177 }
1178 return hashInfo;
1179 }
1180 }
1181
1182 /**
1183 * @param {Module} module the module
1184 * @param {RuntimeSpec} runtime the runtime
1185 * @returns {boolean} true, if the module has hashes for this runtime
1186 */
1187 hasModuleHashes(module, runtime) {
1188 const cgm = this._getChunkGraphModule(module);
1189 const hashes = cgm.hashes;
1190 return hashes && hashes.has(runtime);
1191 }
1192
1193 /**
1194 * @param {Module} module the module
1195 * @param {RuntimeSpec} runtime the runtime
1196 * @returns {string} hash
1197 */
1198 getModuleHash(module, runtime) {
1199 return this._getModuleHashInfo(module, runtime).hash;
1200 }
1201
1202 /**
1203 * @param {Module} module the module
1204 * @param {RuntimeSpec} runtime the runtime
1205 * @returns {string} hash
1206 */
1207 getRenderedModuleHash(module, runtime) {
1208 return this._getModuleHashInfo(module, runtime).renderedHash;
1209 }
1210
1211 /**
1212 * @param {Module} module the module
1213 * @param {RuntimeSpec} runtime the runtime
1214 * @param {string} hash the full hash
1215 * @param {string} renderedHash the shortened hash for rendering
1216 * @returns {void}
1217 */
1218 setModuleHashes(module, runtime, hash, renderedHash) {
1219 const cgm = this._getChunkGraphModule(module);
1220 if (cgm.hashes === undefined) {
1221 cgm.hashes = new RuntimeSpecMap();
1222 }
1223 cgm.hashes.set(runtime, { hash, renderedHash });
1224 }
1225
1226 /**
1227 * @param {Module} module the module
1228 * @param {RuntimeSpec} runtime the runtime
1229 * @param {Set<string>} items runtime requirements to be added (ownership of this Set is given to ChunkGraph)
1230 * @returns {void}
1231 */
1232 addModuleRuntimeRequirements(module, runtime, items) {
1233 const cgm = this._getChunkGraphModule(module);
1234 const runtimeRequirementsMap = cgm.runtimeRequirements;
1235 if (runtimeRequirementsMap === undefined) {
1236 const map = new RuntimeSpecMap();
1237 map.set(runtime, items);
1238 cgm.runtimeRequirements = map;
1239 return;
1240 }
1241 runtimeRequirementsMap.update(runtime, runtimeRequirements => {
1242 if (runtimeRequirements === undefined) {
1243 return items;
1244 } else if (runtimeRequirements.size >= items.size) {
1245 for (const item of items) runtimeRequirements.add(item);
1246 return runtimeRequirements;
1247 } else {
1248 for (const item of runtimeRequirements) items.add(item);
1249 return items;
1250 }
1251 });
1252 }
1253
1254 /**
1255 * @param {Chunk} chunk the chunk
1256 * @param {Set<string>} items runtime requirements to be added (ownership of this Set is given to ChunkGraph)
1257 * @returns {void}
1258 */
1259 addChunkRuntimeRequirements(chunk, items) {
1260 const cgc = this._getChunkGraphChunk(chunk);
1261 const runtimeRequirements = cgc.runtimeRequirements;
1262 if (runtimeRequirements === undefined) {
1263 cgc.runtimeRequirements = items;
1264 } else if (runtimeRequirements.size >= items.size) {
1265 for (const item of items) runtimeRequirements.add(item);
1266 } else {
1267 for (const item of runtimeRequirements) items.add(item);
1268 cgc.runtimeRequirements = items;
1269 }
1270 }
1271
1272 /**
1273 * @param {Chunk} chunk the chunk
1274 * @param {Iterable<string>} items runtime requirements to be added
1275 * @returns {void}
1276 */
1277 addTreeRuntimeRequirements(chunk, items) {
1278 const cgc = this._getChunkGraphChunk(chunk);
1279 const runtimeRequirements = cgc.runtimeRequirementsInTree;
1280 for (const item of items) runtimeRequirements.add(item);
1281 }
1282
1283 /**
1284 * @param {Module} module the module
1285 * @param {RuntimeSpec} runtime the runtime
1286 * @returns {ReadonlySet<string>} runtime requirements
1287 */
1288 getModuleRuntimeRequirements(module, runtime) {
1289 const cgm = this._getChunkGraphModule(module);
1290 const runtimeRequirements =
1291 cgm.runtimeRequirements && cgm.runtimeRequirements.get(runtime);
1292 return runtimeRequirements === undefined ? EMPTY_SET : runtimeRequirements;
1293 }
1294
1295 /**
1296 * @param {Chunk} chunk the chunk
1297 * @returns {ReadonlySet<string>} runtime requirements
1298 */
1299 getChunkRuntimeRequirements(chunk) {
1300 const cgc = this._getChunkGraphChunk(chunk);
1301 const runtimeRequirements = cgc.runtimeRequirements;
1302 return runtimeRequirements === undefined ? EMPTY_SET : runtimeRequirements;
1303 }
1304
1305 /**
1306 * @param {Chunk} chunk the chunk
1307 * @returns {ReadonlySet<string>} runtime requirements
1308 */
1309 getTreeRuntimeRequirements(chunk) {
1310 const cgc = this._getChunkGraphChunk(chunk);
1311 return cgc.runtimeRequirementsInTree;
1312 }
1313
1314 // TODO remove in webpack 6
1315 /**
1316 * @param {Module} module the module
1317 * @param {string} deprecateMessage message for the deprecation message
1318 * @param {string} deprecationCode code for the deprecation
1319 * @returns {ChunkGraph} the chunk graph
1320 */
1321 static getChunkGraphForModule(module, deprecateMessage, deprecationCode) {
1322 const fn = deprecateGetChunkGraphForModuleMap.get(deprecateMessage);
1323 if (fn) return fn(module);
1324 const newFn = util.deprecate(
1325 /**
1326 * @param {Module} module the module
1327 * @returns {ChunkGraph} the chunk graph
1328 */
1329 module => {
1330 const chunkGraph = chunkGraphForModuleMap.get(module);
1331 if (!chunkGraph)
1332 throw new Error(
1333 deprecateMessage +
1334 ": There was no ChunkGraph assigned to the Module for backward-compat (Use the new API)"
1335 );
1336 return chunkGraph;
1337 },
1338 deprecateMessage + ": Use new ChunkGraph API",
1339 deprecationCode
1340 );
1341 deprecateGetChunkGraphForModuleMap.set(deprecateMessage, newFn);
1342 return newFn(module);
1343 }
1344
1345 // TODO remove in webpack 6
1346 /**
1347 * @param {Module} module the module
1348 * @param {ChunkGraph} chunkGraph the chunk graph
1349 * @returns {void}
1350 */
1351 static setChunkGraphForModule(module, chunkGraph) {
1352 chunkGraphForModuleMap.set(module, chunkGraph);
1353 }
1354
1355 // TODO remove in webpack 6
1356 /**
1357 * @param {Chunk} chunk the chunk
1358 * @param {string} deprecateMessage message for the deprecation message
1359 * @param {string} deprecationCode code for the deprecation
1360 * @returns {ChunkGraph} the chunk graph
1361 */
1362 static getChunkGraphForChunk(chunk, deprecateMessage, deprecationCode) {
1363 const fn = deprecateGetChunkGraphForChunkMap.get(deprecateMessage);
1364 if (fn) return fn(chunk);
1365 const newFn = util.deprecate(
1366 /**
1367 * @param {Chunk} chunk the chunk
1368 * @returns {ChunkGraph} the chunk graph
1369 */
1370 chunk => {
1371 const chunkGraph = chunkGraphForChunkMap.get(chunk);
1372 if (!chunkGraph)
1373 throw new Error(
1374 deprecateMessage +
1375 "There was no ChunkGraph assigned to the Chunk for backward-compat (Use the new API)"
1376 );
1377 return chunkGraph;
1378 },
1379 deprecateMessage + ": Use new ChunkGraph API",
1380 deprecationCode
1381 );
1382 deprecateGetChunkGraphForChunkMap.set(deprecateMessage, newFn);
1383 return newFn(chunk);
1384 }
1385
1386 // TODO remove in webpack 6
1387 /**
1388 * @param {Chunk} chunk the chunk
1389 * @param {ChunkGraph} chunkGraph the chunk graph
1390 * @returns {void}
1391 */
1392 static setChunkGraphForChunk(chunk, chunkGraph) {
1393 chunkGraphForChunkMap.set(chunk, chunkGraph);
1394 }
1395}
1396
1397// TODO remove in webpack 6
1398/** @type {WeakMap<Module, ChunkGraph>} */
1399const chunkGraphForModuleMap = new WeakMap();
1400
1401// TODO remove in webpack 6
1402/** @type {WeakMap<Chunk, ChunkGraph>} */
1403const chunkGraphForChunkMap = new WeakMap();
1404
1405// TODO remove in webpack 6
1406/** @type {Map<string, (module: Module) => ChunkGraph>} */
1407const deprecateGetChunkGraphForModuleMap = new Map();
1408
1409// TODO remove in webpack 6
1410/** @type {Map<string, (chunk: Chunk) => ChunkGraph>} */
1411const deprecateGetChunkGraphForChunkMap = new Map();
1412
1413module.exports = ChunkGraph;