UNPKG

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