UNPKG

21.3 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 ChunkGraph = require("./ChunkGraph");
9const Entrypoint = require("./Entrypoint");
10const { intersect } = require("./util/SetHelpers");
11const SortableSet = require("./util/SortableSet");
12const StringXor = require("./util/StringXor");
13const {
14 compareModulesByIdentifier,
15 compareChunkGroupsByIndex,
16 compareModulesById
17} = require("./util/comparators");
18const { createArrayToSetDeprecationSet } = require("./util/deprecation");
19const { mergeRuntime } = require("./util/runtime");
20
21/** @typedef {import("webpack-sources").Source} Source */
22/** @typedef {import("./ChunkGraph").ChunkFilterPredicate} ChunkFilterPredicate */
23/** @typedef {import("./ChunkGraph").ChunkSizeOptions} ChunkSizeOptions */
24/** @typedef {import("./ChunkGraph").ModuleFilterPredicate} ModuleFilterPredicate */
25/** @typedef {import("./ChunkGroup")} ChunkGroup */
26/** @typedef {import("./Compilation")} Compilation */
27/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
28/** @typedef {import("./Compilation").PathData} PathData */
29/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */
30/** @typedef {import("./Module")} Module */
31/** @typedef {import("./ModuleGraph")} ModuleGraph */
32/** @typedef {import("./util/Hash")} Hash */
33/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
34
35const ChunkFilesSet = createArrayToSetDeprecationSet("chunk.files");
36
37/**
38 * @typedef {Object} WithId an object who has an id property *
39 * @property {string | number} id the id of the object
40 */
41
42/**
43 * @deprecated
44 * @typedef {Object} ChunkMaps
45 * @property {Record<string|number, string>} hash
46 * @property {Record<string|number, Record<string, string>>} contentHash
47 * @property {Record<string|number, string>} name
48 */
49
50/**
51 * @deprecated
52 * @typedef {Object} ChunkModuleMaps
53 * @property {Record<string|number, (string|number)[]>} id
54 * @property {Record<string|number, string>} hash
55 */
56
57let debugId = 1000;
58
59/**
60 * A Chunk is a unit of encapsulation for Modules.
61 * Chunks are "rendered" into bundles that get emitted when the build completes.
62 */
63class Chunk {
64 /**
65 * @param {string=} name of chunk being created, is optional (for subclasses)
66 */
67 constructor(name) {
68 /** @type {number | string | null} */
69 this.id = null;
70 /** @type {(number|string)[] | null} */
71 this.ids = null;
72 /** @type {number} */
73 this.debugId = debugId++;
74 /** @type {string} */
75 this.name = name;
76 /** @type {SortableSet<string>} */
77 this.idNameHints = new SortableSet();
78 /** @type {boolean} */
79 this.preventIntegration = false;
80 /** @type {(string | function(PathData, AssetInfo=): string)?} */
81 this.filenameTemplate = undefined;
82 /** @private @type {SortableSet<ChunkGroup>} */
83 this._groups = new SortableSet(undefined, compareChunkGroupsByIndex);
84 /** @type {RuntimeSpec} */
85 this.runtime = undefined;
86 /** @type {Set<string>} */
87 this.files = new ChunkFilesSet();
88 /** @type {Set<string>} */
89 this.auxiliaryFiles = new Set();
90 /** @type {boolean} */
91 this.rendered = false;
92 /** @type {string=} */
93 this.hash = undefined;
94 /** @type {Record<string, string>} */
95 this.contentHash = Object.create(null);
96 /** @type {string=} */
97 this.renderedHash = undefined;
98 /** @type {string=} */
99 this.chunkReason = undefined;
100 /** @type {boolean} */
101 this.extraAsync = false;
102 }
103
104 // TODO remove in webpack 6
105 // BACKWARD-COMPAT START
106 get entryModule() {
107 const entryModules = Array.from(
108 ChunkGraph.getChunkGraphForChunk(
109 this,
110 "Chunk.entryModule",
111 "DEP_WEBPACK_CHUNK_ENTRY_MODULE"
112 ).getChunkEntryModulesIterable(this)
113 );
114 if (entryModules.length === 0) {
115 return undefined;
116 } else if (entryModules.length === 1) {
117 return entryModules[0];
118 } else {
119 throw new Error(
120 "Module.entryModule: Multiple entry modules are not supported by the deprecated API (Use the new ChunkGroup API)"
121 );
122 }
123 }
124
125 /**
126 * @returns {boolean} true, if the chunk contains an entry module
127 */
128 hasEntryModule() {
129 return (
130 ChunkGraph.getChunkGraphForChunk(
131 this,
132 "Chunk.hasEntryModule",
133 "DEP_WEBPACK_CHUNK_HAS_ENTRY_MODULE"
134 ).getNumberOfEntryModules(this) > 0
135 );
136 }
137
138 /**
139 * @param {Module} module the module
140 * @returns {boolean} true, if the chunk could be added
141 */
142 addModule(module) {
143 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
144 this,
145 "Chunk.addModule",
146 "DEP_WEBPACK_CHUNK_ADD_MODULE"
147 );
148 if (chunkGraph.isModuleInChunk(module, this)) return false;
149 chunkGraph.connectChunkAndModule(this, module);
150 return true;
151 }
152
153 /**
154 * @param {Module} module the module
155 * @returns {void}
156 */
157 removeModule(module) {
158 ChunkGraph.getChunkGraphForChunk(
159 this,
160 "Chunk.removeModule",
161 "DEP_WEBPACK_CHUNK_REMOVE_MODULE"
162 ).disconnectChunkAndModule(this, module);
163 }
164
165 /**
166 * @returns {number} the number of module which are contained in this chunk
167 */
168 getNumberOfModules() {
169 return ChunkGraph.getChunkGraphForChunk(
170 this,
171 "Chunk.getNumberOfModules",
172 "DEP_WEBPACK_CHUNK_GET_NUMBER_OF_MODULES"
173 ).getNumberOfChunkModules(this);
174 }
175
176 get modulesIterable() {
177 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
178 this,
179 "Chunk.modulesIterable",
180 "DEP_WEBPACK_CHUNK_MODULES_ITERABLE"
181 );
182 return chunkGraph.getOrderedChunkModulesIterable(
183 this,
184 compareModulesByIdentifier
185 );
186 }
187
188 /**
189 * @param {Chunk} otherChunk the chunk to compare with
190 * @returns {-1|0|1} the comparison result
191 */
192 compareTo(otherChunk) {
193 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
194 this,
195 "Chunk.compareTo",
196 "DEP_WEBPACK_CHUNK_COMPARE_TO"
197 );
198 return chunkGraph.compareChunks(this, otherChunk);
199 }
200
201 /**
202 * @param {Module} module the module
203 * @returns {boolean} true, if the chunk contains the module
204 */
205 containsModule(module) {
206 return ChunkGraph.getChunkGraphForChunk(
207 this,
208 "Chunk.containsModule",
209 "DEP_WEBPACK_CHUNK_CONTAINS_MODULE"
210 ).isModuleInChunk(module, this);
211 }
212
213 /**
214 * @returns {Module[]} the modules for this chunk
215 */
216 getModules() {
217 return ChunkGraph.getChunkGraphForChunk(
218 this,
219 "Chunk.getModules",
220 "DEP_WEBPACK_CHUNK_GET_MODULES"
221 ).getChunkModules(this);
222 }
223
224 /**
225 * @returns {void}
226 */
227 remove() {
228 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
229 this,
230 "Chunk.remove",
231 "DEP_WEBPACK_CHUNK_REMOVE"
232 );
233 chunkGraph.disconnectChunk(this);
234 this.disconnectFromGroups();
235 }
236
237 /**
238 * @param {Module} module the module
239 * @param {Chunk} otherChunk the target chunk
240 * @returns {void}
241 */
242 moveModule(module, otherChunk) {
243 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
244 this,
245 "Chunk.moveModule",
246 "DEP_WEBPACK_CHUNK_MOVE_MODULE"
247 );
248 chunkGraph.disconnectChunkAndModule(this, module);
249 chunkGraph.connectChunkAndModule(otherChunk, module);
250 }
251
252 /**
253 * @param {Chunk} otherChunk the other chunk
254 * @returns {boolean} true, if the specified chunk has been integrated
255 */
256 integrate(otherChunk) {
257 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
258 this,
259 "Chunk.integrate",
260 "DEP_WEBPACK_CHUNK_INTEGRATE"
261 );
262 if (chunkGraph.canChunksBeIntegrated(this, otherChunk)) {
263 chunkGraph.integrateChunks(this, otherChunk);
264 return true;
265 } else {
266 return false;
267 }
268 }
269
270 /**
271 * @param {Chunk} otherChunk the other chunk
272 * @returns {boolean} true, if chunks could be integrated
273 */
274 canBeIntegrated(otherChunk) {
275 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
276 this,
277 "Chunk.canBeIntegrated",
278 "DEP_WEBPACK_CHUNK_CAN_BE_INTEGRATED"
279 );
280 return chunkGraph.canChunksBeIntegrated(this, otherChunk);
281 }
282
283 /**
284 * @returns {boolean} true, if this chunk contains no module
285 */
286 isEmpty() {
287 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
288 this,
289 "Chunk.isEmpty",
290 "DEP_WEBPACK_CHUNK_IS_EMPTY"
291 );
292 return chunkGraph.getNumberOfChunkModules(this) === 0;
293 }
294
295 /**
296 * @returns {number} total size of all modules in this chunk
297 */
298 modulesSize() {
299 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
300 this,
301 "Chunk.modulesSize",
302 "DEP_WEBPACK_CHUNK_MODULES_SIZE"
303 );
304 return chunkGraph.getChunkModulesSize(this);
305 }
306
307 /**
308 * @param {ChunkSizeOptions} options options object
309 * @returns {number} total size of this chunk
310 */
311 size(options = {}) {
312 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
313 this,
314 "Chunk.size",
315 "DEP_WEBPACK_CHUNK_SIZE"
316 );
317 return chunkGraph.getChunkSize(this, options);
318 }
319
320 /**
321 * @param {Chunk} otherChunk the other chunk
322 * @param {ChunkSizeOptions} options options object
323 * @returns {number} total size of the chunk or false if the chunk can't be integrated
324 */
325 integratedSize(otherChunk, options) {
326 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
327 this,
328 "Chunk.integratedSize",
329 "DEP_WEBPACK_CHUNK_INTEGRATED_SIZE"
330 );
331 return chunkGraph.getIntegratedChunksSize(this, otherChunk, options);
332 }
333
334 /**
335 * @param {ModuleFilterPredicate} filterFn function used to filter modules
336 * @returns {ChunkModuleMaps} module map information
337 */
338 getChunkModuleMaps(filterFn) {
339 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
340 this,
341 "Chunk.getChunkModuleMaps",
342 "DEP_WEBPACK_CHUNK_GET_CHUNK_MODULE_MAPS"
343 );
344 /** @type {Record<string|number, (string|number)[]>} */
345 const chunkModuleIdMap = Object.create(null);
346 /** @type {Record<string|number, string>} */
347 const chunkModuleHashMap = Object.create(null);
348
349 for (const asyncChunk of this.getAllAsyncChunks()) {
350 /** @type {(string|number)[]} */
351 let array;
352 for (const module of chunkGraph.getOrderedChunkModulesIterable(
353 asyncChunk,
354 compareModulesById(chunkGraph)
355 )) {
356 if (filterFn(module)) {
357 if (array === undefined) {
358 array = [];
359 chunkModuleIdMap[asyncChunk.id] = array;
360 }
361 const moduleId = chunkGraph.getModuleId(module);
362 array.push(moduleId);
363 chunkModuleHashMap[moduleId] = chunkGraph.getRenderedModuleHash(
364 module,
365 undefined
366 );
367 }
368 }
369 }
370
371 return {
372 id: chunkModuleIdMap,
373 hash: chunkModuleHashMap
374 };
375 }
376
377 /**
378 * @param {ModuleFilterPredicate} filterFn predicate function used to filter modules
379 * @param {ChunkFilterPredicate=} filterChunkFn predicate function used to filter chunks
380 * @returns {boolean} return true if module exists in graph
381 */
382 hasModuleInGraph(filterFn, filterChunkFn) {
383 const chunkGraph = ChunkGraph.getChunkGraphForChunk(
384 this,
385 "Chunk.hasModuleInGraph",
386 "DEP_WEBPACK_CHUNK_HAS_MODULE_IN_GRAPH"
387 );
388 return chunkGraph.hasModuleInGraph(this, filterFn, filterChunkFn);
389 }
390
391 /**
392 * @deprecated
393 * @param {boolean} realHash whether the full hash or the rendered hash is to be used
394 * @returns {ChunkMaps} the chunk map information
395 */
396 getChunkMaps(realHash) {
397 /** @type {Record<string|number, string>} */
398 const chunkHashMap = Object.create(null);
399 /** @type {Record<string|number, Record<string, string>>} */
400 const chunkContentHashMap = Object.create(null);
401 /** @type {Record<string|number, string>} */
402 const chunkNameMap = Object.create(null);
403
404 for (const chunk of this.getAllAsyncChunks()) {
405 chunkHashMap[chunk.id] = realHash ? chunk.hash : chunk.renderedHash;
406 for (const key of Object.keys(chunk.contentHash)) {
407 if (!chunkContentHashMap[key]) {
408 chunkContentHashMap[key] = Object.create(null);
409 }
410 chunkContentHashMap[key][chunk.id] = chunk.contentHash[key];
411 }
412 if (chunk.name) {
413 chunkNameMap[chunk.id] = chunk.name;
414 }
415 }
416
417 return {
418 hash: chunkHashMap,
419 contentHash: chunkContentHashMap,
420 name: chunkNameMap
421 };
422 }
423 // BACKWARD-COMPAT END
424
425 /**
426 * @returns {boolean} whether or not the Chunk will have a runtime
427 */
428 hasRuntime() {
429 for (const chunkGroup of this._groups) {
430 if (
431 chunkGroup instanceof Entrypoint &&
432 chunkGroup.getRuntimeChunk() === this
433 ) {
434 return true;
435 }
436 }
437 return false;
438 }
439
440 /**
441 * @returns {boolean} whether or not this chunk can be an initial chunk
442 */
443 canBeInitial() {
444 for (const chunkGroup of this._groups) {
445 if (chunkGroup.isInitial()) return true;
446 }
447 return false;
448 }
449
450 /**
451 * @returns {boolean} whether this chunk can only be an initial chunk
452 */
453 isOnlyInitial() {
454 if (this._groups.size <= 0) return false;
455 for (const chunkGroup of this._groups) {
456 if (!chunkGroup.isInitial()) return false;
457 }
458 return true;
459 }
460
461 /**
462 * @returns {EntryOptions | undefined} the entry options for this chunk
463 */
464 getEntryOptions() {
465 for (const chunkGroup of this._groups) {
466 if (chunkGroup instanceof Entrypoint) {
467 return chunkGroup.options;
468 }
469 }
470 return undefined;
471 }
472
473 /**
474 * @param {ChunkGroup} chunkGroup the chunkGroup the chunk is being added
475 * @returns {void}
476 */
477 addGroup(chunkGroup) {
478 this._groups.add(chunkGroup);
479 }
480
481 /**
482 * @param {ChunkGroup} chunkGroup the chunkGroup the chunk is being removed from
483 * @returns {void}
484 */
485 removeGroup(chunkGroup) {
486 this._groups.delete(chunkGroup);
487 }
488
489 /**
490 * @param {ChunkGroup} chunkGroup the chunkGroup to check
491 * @returns {boolean} returns true if chunk has chunkGroup reference and exists in chunkGroup
492 */
493 isInGroup(chunkGroup) {
494 return this._groups.has(chunkGroup);
495 }
496
497 /**
498 * @returns {number} the amount of groups that the said chunk is in
499 */
500 getNumberOfGroups() {
501 return this._groups.size;
502 }
503
504 /**
505 * @returns {Iterable<ChunkGroup>} the chunkGroups that the said chunk is referenced in
506 */
507 get groupsIterable() {
508 this._groups.sort();
509 return this._groups;
510 }
511
512 /**
513 * @returns {void}
514 */
515 disconnectFromGroups() {
516 for (const chunkGroup of this._groups) {
517 chunkGroup.removeChunk(this);
518 }
519 }
520
521 /**
522 * @param {Chunk} newChunk the new chunk that will be split out of
523 * @returns {void}
524 */
525 split(newChunk) {
526 for (const chunkGroup of this._groups) {
527 chunkGroup.insertChunk(newChunk, this);
528 newChunk.addGroup(chunkGroup);
529 }
530 for (const idHint of this.idNameHints) {
531 newChunk.idNameHints.add(idHint);
532 }
533 newChunk.runtime = mergeRuntime(newChunk.runtime, this.runtime);
534 }
535
536 /**
537 * @param {Hash} hash hash (will be modified)
538 * @param {ChunkGraph} chunkGraph the chunk graph
539 * @returns {void}
540 */
541 updateHash(hash, chunkGraph) {
542 hash.update(`${this.id} `);
543 hash.update(this.ids ? this.ids.join(",") : "");
544 hash.update(`${this.name || ""} `);
545 const xor = new StringXor();
546 for (const m of chunkGraph.getChunkModulesIterable(this)) {
547 xor.add(chunkGraph.getModuleHash(m, this.runtime));
548 }
549 xor.updateHash(hash);
550 const entryModules = chunkGraph.getChunkEntryModulesWithChunkGroupIterable(
551 this
552 );
553 for (const [m, chunkGroup] of entryModules) {
554 hash.update("entry");
555 hash.update(`${chunkGraph.getModuleId(m)}`);
556 hash.update(chunkGroup.id);
557 }
558 }
559
560 /**
561 * @returns {Set<Chunk>} a set of all the async chunks
562 */
563 getAllAsyncChunks() {
564 const queue = new Set();
565 const chunks = new Set();
566
567 const initialChunks = intersect(
568 Array.from(this.groupsIterable, g => new Set(g.chunks))
569 );
570
571 const initialQueue = new Set(this.groupsIterable);
572
573 for (const chunkGroup of initialQueue) {
574 for (const child of chunkGroup.childrenIterable) {
575 if (child instanceof Entrypoint) {
576 initialQueue.add(child);
577 } else {
578 queue.add(child);
579 }
580 }
581 }
582
583 for (const chunkGroup of queue) {
584 for (const chunk of chunkGroup.chunks) {
585 if (!initialChunks.has(chunk)) {
586 chunks.add(chunk);
587 }
588 }
589 for (const child of chunkGroup.childrenIterable) {
590 queue.add(child);
591 }
592 }
593
594 return chunks;
595 }
596
597 /**
598 * @returns {Set<Chunk>} a set of all the initial chunks (including itself)
599 */
600 getAllInitialChunks() {
601 const chunks = new Set();
602 for (const group of this.groupsIterable) {
603 for (const c of group.chunks) chunks.add(c);
604 }
605 return chunks;
606 }
607
608 /**
609 * @returns {Set<Chunk>} a set of all the referenced chunks (including itself)
610 */
611 getAllReferencedChunks() {
612 const queue = new Set(this.groupsIterable);
613 const chunks = new Set();
614
615 for (const chunkGroup of queue) {
616 for (const chunk of chunkGroup.chunks) {
617 chunks.add(chunk);
618 }
619 for (const child of chunkGroup.childrenIterable) {
620 queue.add(child);
621 }
622 }
623
624 return chunks;
625 }
626
627 /**
628 * @returns {Set<Entrypoint>} a set of all the referenced entrypoints
629 */
630 getAllReferencedAsyncEntrypoints() {
631 const queue = new Set(this.groupsIterable);
632 const entrypoints = new Set();
633
634 for (const chunkGroup of queue) {
635 for (const entrypoint of chunkGroup.asyncEntrypointsIterable) {
636 entrypoints.add(entrypoint);
637 }
638 for (const child of chunkGroup.childrenIterable) {
639 queue.add(child);
640 }
641 }
642
643 return entrypoints;
644 }
645
646 /**
647 * @returns {boolean} true, if the chunk references async chunks
648 */
649 hasAsyncChunks() {
650 const queue = new Set();
651
652 const initialChunks = intersect(
653 Array.from(this.groupsIterable, g => new Set(g.chunks))
654 );
655
656 for (const chunkGroup of this.groupsIterable) {
657 for (const child of chunkGroup.childrenIterable) {
658 queue.add(child);
659 }
660 }
661
662 for (const chunkGroup of queue) {
663 for (const chunk of chunkGroup.chunks) {
664 if (!initialChunks.has(chunk)) {
665 return true;
666 }
667 }
668 for (const child of chunkGroup.childrenIterable) {
669 queue.add(child);
670 }
671 }
672
673 return false;
674 }
675
676 /**
677 * @param {ChunkGraph} chunkGraph the chunk graph
678 * @param {ChunkFilterPredicate=} filterFn function used to filter chunks
679 * @returns {Record<string, (string | number)[]>} a record object of names to lists of child ids(?)
680 */
681 getChildIdsByOrders(chunkGraph, filterFn) {
682 /** @type {Map<string, {order: number, group: ChunkGroup}[]>} */
683 const lists = new Map();
684 for (const group of this.groupsIterable) {
685 if (group.chunks[group.chunks.length - 1] === this) {
686 for (const childGroup of group.childrenIterable) {
687 for (const key of Object.keys(childGroup.options)) {
688 if (key.endsWith("Order")) {
689 const name = key.substr(0, key.length - "Order".length);
690 let list = lists.get(name);
691 if (list === undefined) {
692 list = [];
693 lists.set(name, list);
694 }
695 list.push({
696 order: childGroup.options[key],
697 group: childGroup
698 });
699 }
700 }
701 }
702 }
703 }
704 /** @type {Record<string, (string | number)[]>} */
705 const result = Object.create(null);
706 for (const [name, list] of lists) {
707 list.sort((a, b) => {
708 const cmp = b.order - a.order;
709 if (cmp !== 0) return cmp;
710 return a.group.compareTo(chunkGraph, b.group);
711 });
712 /** @type {Set<string | number>} */
713 const chunkIdSet = new Set();
714 for (const item of list) {
715 for (const chunk of item.group.chunks) {
716 if (filterFn && !filterFn(chunk, chunkGraph)) continue;
717 chunkIdSet.add(chunk.id);
718 }
719 }
720 if (chunkIdSet.size > 0) {
721 result[name] = Array.from(chunkIdSet);
722 }
723 }
724 return result;
725 }
726
727 /**
728 * @param {ChunkGraph} chunkGraph the chunk graph
729 * @param {string} type option name
730 * @returns {{ onChunks: Chunk[], chunks: Set<Chunk> }[]} referenced chunks for a specific type
731 */
732 getChildrenOfTypeInOrder(chunkGraph, type) {
733 const list = [];
734 for (const group of this.groupsIterable) {
735 for (const childGroup of group.childrenIterable) {
736 const order = childGroup.options[type];
737 if (order === undefined) continue;
738 list.push({
739 order,
740 group,
741 childGroup
742 });
743 }
744 }
745 if (list.length === 0) return undefined;
746 list.sort((a, b) => {
747 const cmp = b.order - a.order;
748 if (cmp !== 0) return cmp;
749 return a.group.compareTo(chunkGraph, b.group);
750 });
751 const result = [];
752 let lastEntry;
753 for (const { group, childGroup } of list) {
754 if (lastEntry && lastEntry.onChunks === group.chunks) {
755 for (const chunk of childGroup.chunks) {
756 lastEntry.chunks.add(chunk);
757 }
758 } else {
759 result.push(
760 (lastEntry = {
761 onChunks: group.chunks,
762 chunks: new Set(childGroup.chunks)
763 })
764 );
765 }
766 }
767 return result;
768 }
769
770 /**
771 * @param {ChunkGraph} chunkGraph the chunk graph
772 * @param {boolean=} includeDirectChildren include direct children (by default only children of async children are included)
773 * @param {ChunkFilterPredicate=} filterFn function used to filter chunks
774 * @returns {Record<string|number, Record<string, (string | number)[]>>} a record object of names to lists of child ids(?) by chunk id
775 */
776 getChildIdsByOrdersMap(chunkGraph, includeDirectChildren, filterFn) {
777 /** @type {Record<string|number, Record<string, (string | number)[]>>} */
778 const chunkMaps = Object.create(null);
779
780 /**
781 * @param {Chunk} chunk a chunk
782 * @returns {void}
783 */
784 const addChildIdsByOrdersToMap = chunk => {
785 const data = chunk.getChildIdsByOrders(chunkGraph, filterFn);
786 for (const key of Object.keys(data)) {
787 let chunkMap = chunkMaps[key];
788 if (chunkMap === undefined) {
789 chunkMaps[key] = chunkMap = Object.create(null);
790 }
791 chunkMap[chunk.id] = data[key];
792 }
793 };
794
795 if (includeDirectChildren) {
796 /** @type {Set<Chunk>} */
797 const chunks = new Set();
798 for (const chunkGroup of this.groupsIterable) {
799 for (const chunk of chunkGroup.chunks) {
800 chunks.add(chunk);
801 }
802 }
803 for (const chunk of chunks) {
804 addChildIdsByOrdersToMap(chunk);
805 }
806 }
807
808 for (const chunk of this.getAllAsyncChunks()) {
809 addChildIdsByOrdersToMap(chunk);
810 }
811
812 return chunkMaps;
813 }
814}
815
816module.exports = Chunk;