source: frontend/node_modules/webpack/lib/Chunk.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

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