UNPKG

22.6 kBJavaScriptView Raw
1/*
2MIT License http://www.opensource.org/licenses/mit-license.php
3Author Tobias Koppers @sokra
4*/
5"use strict";
6
7const util = require("util");
8const SortableSet = require("./util/SortableSet");
9const intersect = require("./util/SetHelpers").intersect;
10const GraphHelpers = require("./GraphHelpers");
11const Entrypoint = require("./Entrypoint");
12let debugId = 1000;
13const ERR_CHUNK_ENTRY = "Chunk.entry was removed. Use hasRuntime()";
14const ERR_CHUNK_INITIAL =
15 "Chunk.initial was removed. Use canBeInitial/isOnlyInitial()";
16
17/** @typedef {import("./Module")} Module */
18/** @typedef {import("./ChunkGroup")} ChunkGroup */
19/** @typedef {import("./ModuleReason")} ModuleReason */
20/** @typedef {import("webpack-sources").Source} Source */
21/** @typedef {import("./util/createHash").Hash} Hash */
22
23/**
24 * @typedef {Object} WithId an object who has an id property *
25 * @property {string | number} id the id of the object
26 */
27
28/**
29 * Compare two Modules based on their ids for sorting
30 * @param {Module} a module
31 * @param {Module} b module
32 * @returns {-1|0|1} sort value
33 */
34
35// TODO use @callback
36/** @typedef {(a: Module, b: Module) => -1|0|1} ModuleSortPredicate */
37/** @typedef {(m: Module) => boolean} ModuleFilterPredicate */
38/** @typedef {(c: Chunk) => boolean} ChunkFilterPredicate */
39
40const sortModuleById = (a, b) => {
41 if (a.id < b.id) return -1;
42 if (b.id < a.id) return 1;
43 return 0;
44};
45
46/**
47 * Compare two ChunkGroups based on their ids for sorting
48 * @param {ChunkGroup} a chunk group
49 * @param {ChunkGroup} b chunk group
50 * @returns {-1|0|1} sort value
51 */
52const sortChunkGroupById = (a, b) => {
53 if (a.id < b.id) return -1;
54 if (b.id < a.id) return 1;
55 return 0;
56};
57
58/**
59 * Compare two Identifiables , based on their ids for sorting
60 * @param {Module} a first object with ident fn
61 * @param {Module} b second object with ident fn
62 * @returns {-1|0|1} The order number of the sort
63 */
64const sortByIdentifier = (a, b) => {
65 if (a.identifier() > b.identifier()) return 1;
66 if (a.identifier() < b.identifier()) return -1;
67 return 0;
68};
69
70/**
71 * @returns {string} a concatenation of module identifiers sorted
72 * @param {SortableSet} set to pull module identifiers from
73 */
74const getModulesIdent = set => {
75 set.sort();
76 let str = "";
77 for (const m of set) {
78 str += m.identifier() + "#";
79 }
80 return str;
81};
82
83/**
84 * @template T
85 * @param {SortableSet<T>} set the sortable set to convert to array
86 * @returns {Array<T>} the array returned from Array.from(set)
87 */
88const getArray = set => Array.from(set);
89
90/**
91 * @param {SortableSet<Module>} set the sortable Set to get the count/size of
92 * @returns {number} the size of the modules
93 */
94const getModulesSize = set => {
95 let size = 0;
96 for (const module of set) {
97 size += module.size();
98 }
99 return size;
100};
101
102/**
103 * A Chunk is a unit of encapsulation for Modules.
104 * Chunks are "rendered" into bundles that get emitted when the build completes.
105 */
106class Chunk {
107 /**
108 * @param {string=} name of chunk being created, is optional (for subclasses)
109 */
110 constructor(name) {
111 /** @type {number | null} */
112 this.id = null;
113 /** @type {number[] | null} */
114 this.ids = null;
115 /** @type {number} */
116 this.debugId = debugId++;
117 /** @type {string} */
118 this.name = name;
119 /** @type {boolean} */
120 this.preventIntegration = false;
121 /** @type {Module=} */
122 this.entryModule = undefined;
123 /** @private @type {SortableSet<Module>} */
124 this._modules = new SortableSet(undefined, sortByIdentifier);
125 /** @type {string?} */
126 this.filenameTemplate = undefined;
127 /** @private @type {SortableSet<ChunkGroup>} */
128 this._groups = new SortableSet(undefined, sortChunkGroupById);
129 /** @type {string[]} */
130 this.files = [];
131 /** @type {boolean} */
132 this.rendered = false;
133 /** @type {string=} */
134 this.hash = undefined;
135 /** @type {Object} */
136 this.contentHash = Object.create(null);
137 /** @type {string=} */
138 this.renderedHash = undefined;
139 /** @type {string=} */
140 this.chunkReason = undefined;
141 /** @type {boolean} */
142 this.extraAsync = false;
143 this.removedModules = undefined;
144 }
145
146 /**
147 * @deprecated Chunk.entry has been deprecated. Please use .hasRuntime() instead
148 * @returns {never} Throws an error trying to access this property
149 */
150 get entry() {
151 throw new Error(ERR_CHUNK_ENTRY);
152 }
153
154 /**
155 * @deprecated .entry has been deprecated. Please use .hasRuntime() instead
156 * @param {never} data The data that was attempting to be set
157 * @returns {never} Throws an error trying to access this property
158 */
159 set entry(data) {
160 throw new Error(ERR_CHUNK_ENTRY);
161 }
162
163 /**
164 * @deprecated Chunk.initial was removed. Use canBeInitial/isOnlyInitial()
165 * @returns {never} Throws an error trying to access this property
166 */
167 get initial() {
168 throw new Error(ERR_CHUNK_INITIAL);
169 }
170
171 /**
172 * @deprecated Chunk.initial was removed. Use canBeInitial/isOnlyInitial()
173 * @param {never} data The data attempting to be set
174 * @returns {never} Throws an error trying to access this property
175 */
176 set initial(data) {
177 throw new Error(ERR_CHUNK_INITIAL);
178 }
179
180 /**
181 * @returns {boolean} whether or not the Chunk will have a runtime
182 */
183 hasRuntime() {
184 for (const chunkGroup of this._groups) {
185 if (
186 chunkGroup.isInitial() &&
187 chunkGroup instanceof Entrypoint &&
188 chunkGroup.getRuntimeChunk() === this
189 ) {
190 return true;
191 }
192 }
193 return false;
194 }
195
196 /**
197 * @returns {boolean} whether or not this chunk can be an initial chunk
198 */
199 canBeInitial() {
200 for (const chunkGroup of this._groups) {
201 if (chunkGroup.isInitial()) return true;
202 }
203 return false;
204 }
205
206 /**
207 * @returns {boolean} whether this chunk can only be an initial chunk
208 */
209 isOnlyInitial() {
210 if (this._groups.size <= 0) return false;
211 for (const chunkGroup of this._groups) {
212 if (!chunkGroup.isInitial()) return false;
213 }
214 return true;
215 }
216
217 /**
218 * @returns {boolean} if this chunk contains the entry module
219 */
220 hasEntryModule() {
221 return !!this.entryModule;
222 }
223
224 /**
225 * @param {Module} module the module that will be added to this chunk.
226 * @returns {boolean} returns true if the chunk doesn't have the module and it was added
227 */
228 addModule(module) {
229 if (!this._modules.has(module)) {
230 this._modules.add(module);
231 return true;
232 }
233 return false;
234 }
235
236 /**
237 * @param {Module} module the module that will be removed from this chunk
238 * @returns {boolean} returns true if chunk exists and is successfully deleted
239 */
240 removeModule(module) {
241 if (this._modules.delete(module)) {
242 module.removeChunk(this);
243 return true;
244 }
245 return false;
246 }
247
248 /**
249 * @param {Module[]} modules the new modules to be set
250 * @returns {void} set new modules to this chunk and return nothing
251 */
252 setModules(modules) {
253 this._modules = new SortableSet(modules, sortByIdentifier);
254 }
255
256 /**
257 * @returns {number} the amount of modules in chunk
258 */
259 getNumberOfModules() {
260 return this._modules.size;
261 }
262
263 /**
264 * @returns {SortableSet} return the modules SortableSet for this chunk
265 */
266 get modulesIterable() {
267 return this._modules;
268 }
269
270 /**
271 * @param {ChunkGroup} chunkGroup the chunkGroup the chunk is being added
272 * @returns {boolean} returns true if chunk is not apart of chunkGroup and is added successfully
273 */
274 addGroup(chunkGroup) {
275 if (this._groups.has(chunkGroup)) return false;
276 this._groups.add(chunkGroup);
277 return true;
278 }
279
280 /**
281 * @param {ChunkGroup} chunkGroup the chunkGroup the chunk is being removed from
282 * @returns {boolean} returns true if chunk does exist in chunkGroup and is removed
283 */
284 removeGroup(chunkGroup) {
285 if (!this._groups.has(chunkGroup)) return false;
286 this._groups.delete(chunkGroup);
287 return true;
288 }
289
290 /**
291 * @param {ChunkGroup} chunkGroup the chunkGroup to check
292 * @returns {boolean} returns true if chunk has chunkGroup reference and exists in chunkGroup
293 */
294 isInGroup(chunkGroup) {
295 return this._groups.has(chunkGroup);
296 }
297
298 /**
299 * @returns {number} the amount of groups said chunk is in
300 */
301 getNumberOfGroups() {
302 return this._groups.size;
303 }
304
305 /**
306 * @returns {SortableSet<ChunkGroup>} the chunkGroups that said chunk is referenced in
307 */
308 get groupsIterable() {
309 return this._groups;
310 }
311
312 /**
313 * @param {Chunk} otherChunk the chunk to compare itself with
314 * @returns {-1|0|1} this is a comparitor function like sort and returns -1, 0, or 1 based on sort order
315 */
316 compareTo(otherChunk) {
317 if (this.name && !otherChunk.name) return -1;
318 if (!this.name && otherChunk.name) return 1;
319 if (this.name < otherChunk.name) return -1;
320 if (this.name > otherChunk.name) return 1;
321 if (this._modules.size > otherChunk._modules.size) return -1;
322 if (this._modules.size < otherChunk._modules.size) return 1;
323 this._modules.sort();
324 otherChunk._modules.sort();
325 const a = this._modules[Symbol.iterator]();
326 const b = otherChunk._modules[Symbol.iterator]();
327 // eslint-disable-next-line no-constant-condition
328 while (true) {
329 const aItem = a.next();
330 if (aItem.done) return 0;
331 const bItem = b.next();
332 const aModuleIdentifier = aItem.value.identifier();
333 const bModuleIdentifier = bItem.value.identifier();
334 if (aModuleIdentifier < bModuleIdentifier) return -1;
335 if (aModuleIdentifier > bModuleIdentifier) return 1;
336 }
337 }
338
339 /**
340 * @param {Module} module Module to check
341 * @returns {boolean} returns true if module does exist in this chunk
342 */
343 containsModule(module) {
344 return this._modules.has(module);
345 }
346
347 /**
348 * @returns {Module[]} an array of modules (do not modify)
349 */
350 getModules() {
351 return this._modules.getFromCache(getArray);
352 }
353
354 getModulesIdent() {
355 return this._modules.getFromUnorderedCache(getModulesIdent);
356 }
357
358 remove() {
359 // cleanup modules
360 // Array.from is used here to create a clone, because removeChunk modifies this._modules
361 for (const module of Array.from(this._modules)) {
362 module.removeChunk(this);
363 }
364 for (const chunkGroup of this._groups) {
365 chunkGroup.removeChunk(this);
366 }
367 }
368
369 /**
370 *
371 * @param {Module} module module to move
372 * @param {Chunk} otherChunk other chunk to move it to
373 * @returns {void}
374 */
375 moveModule(module, otherChunk) {
376 GraphHelpers.disconnectChunkAndModule(this, module);
377 GraphHelpers.connectChunkAndModule(otherChunk, module);
378 module.rewriteChunkInReasons(this, [otherChunk]);
379 }
380
381 /**
382 *
383 * @param {Chunk} otherChunk the chunk to integrate with
384 * @param {ModuleReason} reason reason why the module is being integrated
385 * @returns {boolean} returns true or false if integration succeeds or fails
386 */
387 integrate(otherChunk, reason) {
388 if (!this.canBeIntegrated(otherChunk)) {
389 return false;
390 }
391
392 // Pick a new name for the integrated chunk
393 if (this.name && otherChunk.name) {
394 if (this.hasEntryModule() === otherChunk.hasEntryModule()) {
395 // When both chunks have entry modules or none have one, use
396 // shortest name
397 if (this.name.length !== otherChunk.name.length) {
398 this.name =
399 this.name.length < otherChunk.name.length
400 ? this.name
401 : otherChunk.name;
402 } else {
403 this.name = this.name < otherChunk.name ? this.name : otherChunk.name;
404 }
405 } else if (otherChunk.hasEntryModule()) {
406 // Pick the name of the chunk with the entry module
407 this.name = otherChunk.name;
408 }
409 } else if (otherChunk.name) {
410 this.name = otherChunk.name;
411 }
412
413 // Array.from is used here to create a clone, because moveModule modifies otherChunk._modules
414 for (const module of Array.from(otherChunk._modules)) {
415 otherChunk.moveModule(module, this);
416 }
417 otherChunk._modules.clear();
418
419 if (otherChunk.entryModule) {
420 this.entryModule = otherChunk.entryModule;
421 }
422
423 for (const chunkGroup of otherChunk._groups) {
424 chunkGroup.replaceChunk(otherChunk, this);
425 this.addGroup(chunkGroup);
426 }
427 otherChunk._groups.clear();
428
429 return true;
430 }
431
432 /**
433 * @param {Chunk} newChunk the new chunk that will be split out of the current chunk
434 * @returns {void}
435 */
436 split(newChunk) {
437 for (const chunkGroup of this._groups) {
438 chunkGroup.insertChunk(newChunk, this);
439 newChunk.addGroup(chunkGroup);
440 }
441 }
442
443 isEmpty() {
444 return this._modules.size === 0;
445 }
446
447 updateHash(hash) {
448 hash.update(`${this.id} `);
449 hash.update(this.ids ? this.ids.join(",") : "");
450 hash.update(`${this.name || ""} `);
451 for (const m of this._modules) {
452 hash.update(m.hash);
453 }
454 }
455
456 canBeIntegrated(otherChunk) {
457 const isAvailable = (a, b) => {
458 const queue = new Set(b.groupsIterable);
459 for (const chunkGroup of queue) {
460 if (a.isInGroup(chunkGroup)) continue;
461 if (chunkGroup.isInitial()) return false;
462 for (const parent of chunkGroup.parentsIterable) {
463 queue.add(parent);
464 }
465 }
466 return true;
467 };
468
469 if (this.preventIntegration || otherChunk.preventIntegration) {
470 return false;
471 }
472
473 if (this.hasRuntime() !== otherChunk.hasRuntime()) {
474 if (this.hasRuntime()) {
475 return isAvailable(this, otherChunk);
476 } else if (otherChunk.hasRuntime()) {
477 return isAvailable(otherChunk, this);
478 } else {
479 return false;
480 }
481 }
482
483 if (this.hasEntryModule() || otherChunk.hasEntryModule()) {
484 return false;
485 }
486
487 return true;
488 }
489
490 /**
491 *
492 * @param {number} size the size
493 * @param {Object} options the options passed in
494 * @returns {number} the multiplier returned
495 */
496 addMultiplierAndOverhead(size, options) {
497 const overhead =
498 typeof options.chunkOverhead === "number" ? options.chunkOverhead : 10000;
499 const multiplicator = this.canBeInitial()
500 ? options.entryChunkMultiplicator || 10
501 : 1;
502
503 return size * multiplicator + overhead;
504 }
505
506 /**
507 * @returns {number} the size of all modules
508 */
509 modulesSize() {
510 return this._modules.getFromUnorderedCache(getModulesSize);
511 }
512
513 /**
514 * @param {Object} options the size display options
515 * @returns {number} the chunk size
516 */
517 size(options) {
518 return this.addMultiplierAndOverhead(this.modulesSize(), options);
519 }
520
521 /**
522 * @param {Chunk} otherChunk the other chunk
523 * @param {TODO} options the options for this function
524 * @returns {number | false} the size, or false if it can't be integrated
525 */
526 integratedSize(otherChunk, options) {
527 // Chunk if it's possible to integrate this chunk
528 if (!this.canBeIntegrated(otherChunk)) {
529 return false;
530 }
531
532 let integratedModulesSize = this.modulesSize();
533 // only count modules that do not exist in this chunk!
534 for (const otherModule of otherChunk._modules) {
535 if (!this._modules.has(otherModule)) {
536 integratedModulesSize += otherModule.size();
537 }
538 }
539
540 return this.addMultiplierAndOverhead(integratedModulesSize, options);
541 }
542
543 /**
544 * @param {function(Module, Module): -1|0|1=} sortByFn a predicate function used to sort modules
545 * @returns {void}
546 */
547 sortModules(sortByFn) {
548 this._modules.sortWith(sortByFn || sortModuleById);
549 }
550
551 sortItems() {
552 this.sortModules();
553 }
554
555 /**
556 * @returns {Set<Chunk>} a set of all the async chunks
557 */
558 getAllAsyncChunks() {
559 const queue = new Set();
560 const chunks = new Set();
561
562 const initialChunks = intersect(
563 Array.from(this.groupsIterable, g => new Set(g.chunks))
564 );
565
566 for (const chunkGroup of this.groupsIterable) {
567 for (const child of chunkGroup.childrenIterable) {
568 queue.add(child);
569 }
570 }
571
572 for (const chunkGroup of queue) {
573 for (const chunk of chunkGroup.chunks) {
574 if (!initialChunks.has(chunk)) {
575 chunks.add(chunk);
576 }
577 }
578 for (const child of chunkGroup.childrenIterable) {
579 queue.add(child);
580 }
581 }
582
583 return chunks;
584 }
585
586 /**
587 * @typedef {Object} ChunkMaps
588 * @property {Record<string|number, string>} hash
589 * @property {Record<string|number, Record<string, string>>} contentHash
590 * @property {Record<string|number, string>} name
591 */
592
593 /**
594 * @param {boolean} realHash should the full hash or the rendered hash be used
595 * @returns {ChunkMaps} the chunk map information
596 */
597 getChunkMaps(realHash) {
598 /** @type {Record<string|number, string>} */
599 const chunkHashMap = Object.create(null);
600 /** @type {Record<string|number, Record<string, string>>} */
601 const chunkContentHashMap = Object.create(null);
602 /** @type {Record<string|number, string>} */
603 const chunkNameMap = Object.create(null);
604
605 for (const chunk of this.getAllAsyncChunks()) {
606 chunkHashMap[chunk.id] = realHash ? chunk.hash : chunk.renderedHash;
607 for (const key of Object.keys(chunk.contentHash)) {
608 if (!chunkContentHashMap[key]) {
609 chunkContentHashMap[key] = Object.create(null);
610 }
611 chunkContentHashMap[key][chunk.id] = chunk.contentHash[key];
612 }
613 if (chunk.name) {
614 chunkNameMap[chunk.id] = chunk.name;
615 }
616 }
617
618 return {
619 hash: chunkHashMap,
620 contentHash: chunkContentHashMap,
621 name: chunkNameMap
622 };
623 }
624
625 /**
626 * @returns {Record<string, Set<TODO>[]>} a record object of names to lists of child ids(?)
627 */
628 getChildIdsByOrders() {
629 const lists = new Map();
630 for (const group of this.groupsIterable) {
631 if (group.chunks[group.chunks.length - 1] === this) {
632 for (const childGroup of group.childrenIterable) {
633 // TODO webpack 5 remove this check for options
634 if (typeof childGroup.options === "object") {
635 for (const key of Object.keys(childGroup.options)) {
636 if (key.endsWith("Order")) {
637 const name = key.substr(0, key.length - "Order".length);
638 let list = lists.get(name);
639 if (list === undefined) lists.set(name, (list = []));
640 list.push({
641 order: childGroup.options[key],
642 group: childGroup
643 });
644 }
645 }
646 }
647 }
648 }
649 }
650 const result = Object.create(null);
651 for (const [name, list] of lists) {
652 list.sort((a, b) => {
653 const cmp = b.order - a.order;
654 if (cmp !== 0) return cmp;
655 // TODO webpack 5 remove this check of compareTo
656 if (a.group.compareTo) {
657 return a.group.compareTo(b.group);
658 }
659 return 0;
660 });
661 result[name] = Array.from(
662 list.reduce((set, item) => {
663 for (const chunk of item.group.chunks) {
664 set.add(chunk.id);
665 }
666 return set;
667 }, new Set())
668 );
669 }
670 return result;
671 }
672
673 getChildIdsByOrdersMap(includeDirectChildren) {
674 const chunkMaps = Object.create(null);
675
676 const addChildIdsByOrdersToMap = chunk => {
677 const data = chunk.getChildIdsByOrders();
678 for (const key of Object.keys(data)) {
679 let chunkMap = chunkMaps[key];
680 if (chunkMap === undefined) {
681 chunkMaps[key] = chunkMap = Object.create(null);
682 }
683 chunkMap[chunk.id] = data[key];
684 }
685 };
686
687 if (includeDirectChildren) {
688 addChildIdsByOrdersToMap(this);
689 }
690
691 for (const chunk of this.getAllAsyncChunks()) {
692 addChildIdsByOrdersToMap(chunk);
693 }
694
695 return chunkMaps;
696 }
697
698 /**
699 * @typedef {Object} ChunkModuleMaps
700 * @property {Record<string|number, (string|number)[]>} id
701 * @property {Record<string|number, string>} hash
702 */
703
704 /**
705 * @param {ModuleFilterPredicate} filterFn function used to filter modules
706 * @returns {ChunkModuleMaps} module map information
707 */
708 getChunkModuleMaps(filterFn) {
709 /** @type {Record<string|number, (string|number)[]>} */
710 const chunkModuleIdMap = Object.create(null);
711 /** @type {Record<string|number, string>} */
712 const chunkModuleHashMap = Object.create(null);
713
714 for (const chunk of this.getAllAsyncChunks()) {
715 /** @type {(string|number)[]} */
716 let array;
717 for (const module of chunk.modulesIterable) {
718 if (filterFn(module)) {
719 if (array === undefined) {
720 array = [];
721 chunkModuleIdMap[chunk.id] = array;
722 }
723 array.push(module.id);
724 chunkModuleHashMap[module.id] = module.renderedHash;
725 }
726 }
727 if (array !== undefined) {
728 array.sort();
729 }
730 }
731
732 return {
733 id: chunkModuleIdMap,
734 hash: chunkModuleHashMap
735 };
736 }
737
738 /**
739 *
740 * @param {function(Module): boolean} filterFn predicate function used to filter modules
741 * @param {function(Chunk): boolean} filterChunkFn predicate function used to filter chunks
742 * @returns {boolean} return true if module exists in graph
743 */
744 hasModuleInGraph(filterFn, filterChunkFn) {
745 const queue = new Set(this.groupsIterable);
746 const chunksProcessed = new Set();
747
748 for (const chunkGroup of queue) {
749 for (const chunk of chunkGroup.chunks) {
750 if (!chunksProcessed.has(chunk)) {
751 chunksProcessed.add(chunk);
752 if (!filterChunkFn || filterChunkFn(chunk)) {
753 for (const module of chunk.modulesIterable) {
754 if (filterFn(module)) {
755 return true;
756 }
757 }
758 }
759 }
760 }
761 for (const child of chunkGroup.childrenIterable) {
762 queue.add(child);
763 }
764 }
765 return false;
766 }
767
768 toString() {
769 return `Chunk[${Array.from(this._modules).join()}]`;
770 }
771}
772
773// TODO remove in webpack 5
774Object.defineProperty(Chunk.prototype, "forEachModule", {
775 configurable: false,
776 value: util.deprecate(
777 /**
778 * @deprecated
779 * @this {Chunk}
780 * @typedef {function(any, any, Set<any>): void} ForEachModuleCallback
781 * @param {ForEachModuleCallback} fn Callback function
782 * @returns {void}
783 */
784 function(fn) {
785 this._modules.forEach(fn);
786 },
787 "Chunk.forEachModule: Use for(const module of chunk.modulesIterable) instead"
788 )
789});
790
791// TODO remove in webpack 5
792Object.defineProperty(Chunk.prototype, "mapModules", {
793 configurable: false,
794 value: util.deprecate(
795 /**
796 * @deprecated
797 * @this {Chunk}
798 * @typedef {function(any, number): any} MapModulesCallback
799 * @param {MapModulesCallback} fn Callback function
800 * @returns {TODO[]} result of mapped modules
801 */
802 function(fn) {
803 return Array.from(this._modules, fn);
804 },
805 "Chunk.mapModules: Use Array.from(chunk.modulesIterable, fn) instead"
806 )
807});
808
809// TODO remove in webpack 5
810Object.defineProperty(Chunk.prototype, "chunks", {
811 configurable: false,
812 get() {
813 throw new Error("Chunk.chunks: Use ChunkGroup.getChildren() instead");
814 },
815 set() {
816 throw new Error("Chunk.chunks: Use ChunkGroup.add/removeChild() instead");
817 }
818});
819
820// TODO remove in webpack 5
821Object.defineProperty(Chunk.prototype, "parents", {
822 configurable: false,
823 get() {
824 throw new Error("Chunk.parents: Use ChunkGroup.getParents() instead");
825 },
826 set() {
827 throw new Error("Chunk.parents: Use ChunkGroup.add/removeParent() instead");
828 }
829});
830
831// TODO remove in webpack 5
832Object.defineProperty(Chunk.prototype, "blocks", {
833 configurable: false,
834 get() {
835 throw new Error("Chunk.blocks: Use ChunkGroup.getBlocks() instead");
836 },
837 set() {
838 throw new Error("Chunk.blocks: Use ChunkGroup.add/removeBlock() instead");
839 }
840});
841
842// TODO remove in webpack 5
843Object.defineProperty(Chunk.prototype, "entrypoints", {
844 configurable: false,
845 get() {
846 throw new Error(
847 "Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead"
848 );
849 },
850 set() {
851 throw new Error("Chunk.entrypoints: Use Chunks.addGroup instead");
852 }
853});
854
855module.exports = Chunk;