| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 | 
							- /*
 
- 	MIT License http://www.opensource.org/licenses/mit-license.php
 
- 	Author Tobias Koppers @sokra
 
- */
 
- "use strict";
 
- const util = require("util");
 
- const compareLocations = require("./compareLocations");
 
- const SortableSet = require("./util/SortableSet");
 
- let debugId = 1000;
 
- const sortById = (a, b) => {
 
- 	if(a.id < b.id) return -1;
 
- 	if(b.id < a.id) return 1;
 
- 	return 0;
 
- };
 
- const sortByIdentifier = (a, b) => {
 
- 	if(a.identifier() > b.identifier()) return 1;
 
- 	if(a.identifier() < b.identifier()) return -1;
 
- 	return 0;
 
- };
 
- class Chunk {
 
- 	constructor(name, module, loc) {
 
- 		this.id = null;
 
- 		this.ids = null;
 
- 		this.debugId = debugId++;
 
- 		this.name = name;
 
- 		this._modules = new SortableSet(undefined, sortByIdentifier);
 
- 		this.entrypoints = [];
 
- 		this.chunks = [];
 
- 		this.parents = [];
 
- 		this.blocks = [];
 
- 		this.origins = [];
 
- 		this.files = [];
 
- 		this.rendered = false;
 
- 		if(module) {
 
- 			this.origins.push({
 
- 				module,
 
- 				loc,
 
- 				name
 
- 			});
 
- 		}
 
- 	}
 
- 	get entry() {
 
- 		throw new Error("Chunk.entry was removed. Use hasRuntime()");
 
- 	}
 
- 	set entry(data) {
 
- 		throw new Error("Chunk.entry was removed. Use hasRuntime()");
 
- 	}
 
- 	get initial() {
 
- 		throw new Error("Chunk.initial was removed. Use isInitial()");
 
- 	}
 
- 	set initial(data) {
 
- 		throw new Error("Chunk.initial was removed. Use isInitial()");
 
- 	}
 
- 	hasRuntime() {
 
- 		if(this.entrypoints.length === 0) return false;
 
- 		return this.entrypoints[0].chunks[0] === this;
 
- 	}
 
- 	isInitial() {
 
- 		return this.entrypoints.length > 0;
 
- 	}
 
- 	hasEntryModule() {
 
- 		return !!this.entryModule;
 
- 	}
 
- 	addToCollection(collection, item) {
 
- 		if(item === this) {
 
- 			return false;
 
- 		}
 
- 		if(collection.indexOf(item) > -1) {
 
- 			return false;
 
- 		}
 
- 		collection.push(item);
 
- 		return true;
 
- 	}
 
- 	addChunk(chunk) {
 
- 		return this.addToCollection(this.chunks, chunk);
 
- 	}
 
- 	addParent(parentChunk) {
 
- 		return this.addToCollection(this.parents, parentChunk);
 
- 	}
 
- 	addModule(module) {
 
- 		if(!this._modules.has(module)) {
 
- 			this._modules.add(module);
 
- 			return true;
 
- 		}
 
- 		return false;
 
- 	}
 
- 	addBlock(block) {
 
- 		return this.addToCollection(this.blocks, block);
 
- 	}
 
- 	removeModule(module) {
 
- 		if(this._modules.delete(module)) {
 
- 			module.removeChunk(this);
 
- 			return true;
 
- 		}
 
- 		return false;
 
- 	}
 
- 	removeChunk(chunk) {
 
- 		const idx = this.chunks.indexOf(chunk);
 
- 		if(idx >= 0) {
 
- 			this.chunks.splice(idx, 1);
 
- 			chunk.removeParent(this);
 
- 			return true;
 
- 		}
 
- 		return false;
 
- 	}
 
- 	removeParent(chunk) {
 
- 		const idx = this.parents.indexOf(chunk);
 
- 		if(idx >= 0) {
 
- 			this.parents.splice(idx, 1);
 
- 			chunk.removeChunk(this);
 
- 			return true;
 
- 		}
 
- 		return false;
 
- 	}
 
- 	addOrigin(module, loc) {
 
- 		this.origins.push({
 
- 			module,
 
- 			loc,
 
- 			name: this.name
 
- 		});
 
- 	}
 
- 	setModules(modules) {
 
- 		this._modules = new SortableSet(modules, sortByIdentifier);
 
- 	}
 
- 	getNumberOfModules() {
 
- 		return this._modules.size;
 
- 	}
 
- 	get modulesIterable() {
 
- 		return this._modules;
 
- 	}
 
- 	forEachModule(fn) {
 
- 		this._modules.forEach(fn);
 
- 	}
 
- 	mapModules(fn) {
 
- 		return Array.from(this._modules, fn);
 
- 	}
 
- 	compareTo(otherChunk) {
 
- 		this._modules.sort();
 
- 		otherChunk._modules.sort();
 
- 		if(this._modules.size > otherChunk._modules.size) return -1;
 
- 		if(this._modules.size < otherChunk._modules.size) return 1;
 
- 		const a = this._modules[Symbol.iterator]();
 
- 		const b = otherChunk._modules[Symbol.iterator]();
 
- 		while(true) { // eslint-disable-line
 
- 			const aItem = a.next();
 
- 			const bItem = b.next();
 
- 			if(aItem.done) return 0;
 
- 			const aModuleIdentifier = aItem.value.identifier();
 
- 			const bModuleIdentifier = bItem.value.identifier();
 
- 			if(aModuleIdentifier > bModuleIdentifier) return -1;
 
- 			if(aModuleIdentifier < bModuleIdentifier) return 1;
 
- 		}
 
- 	}
 
- 	containsModule(module) {
 
- 		return this._modules.has(module);
 
- 	}
 
- 	getModules() {
 
- 		return Array.from(this._modules);
 
- 	}
 
- 	getModulesIdent() {
 
- 		this._modules.sort();
 
- 		let str = "";
 
- 		this._modules.forEach(m => {
 
- 			str += m.identifier() + "#";
 
- 		});
 
- 		return str;
 
- 	}
 
- 	remove(reason) {
 
- 		// cleanup modules
 
- 		// Array.from is used here to create a clone, because removeChunk modifies this._modules
 
- 		Array.from(this._modules).forEach(module => {
 
- 			module.removeChunk(this);
 
- 		});
 
- 		// cleanup parents
 
- 		this.parents.forEach(parentChunk => {
 
- 			// remove this chunk from its parents
 
- 			const idx = parentChunk.chunks.indexOf(this);
 
- 			if(idx >= 0) {
 
- 				parentChunk.chunks.splice(idx, 1);
 
- 			}
 
- 			// cleanup "sub chunks"
 
- 			this.chunks.forEach(chunk => {
 
- 				/**
 
- 				 * remove this chunk as "intermediary" and connect
 
- 				 * it "sub chunks" and parents directly
 
- 				 */
 
- 				// add parent to each "sub chunk"
 
- 				chunk.addParent(parentChunk);
 
- 				// add "sub chunk" to parent
 
- 				parentChunk.addChunk(chunk);
 
- 			});
 
- 		});
 
- 		/**
 
- 		 * we need to iterate again over the chunks
 
- 		 * to remove this from the chunks parents.
 
- 		 * This can not be done in the above loop
 
- 		 * as it is not garuanteed that `this.parents` contains anything.
 
- 		 */
 
- 		this.chunks.forEach(chunk => {
 
- 			// remove this as parent of every "sub chunk"
 
- 			const idx = chunk.parents.indexOf(this);
 
- 			if(idx >= 0) {
 
- 				chunk.parents.splice(idx, 1);
 
- 			}
 
- 		});
 
- 		// cleanup blocks
 
- 		this.blocks.forEach(block => {
 
- 			const idx = block.chunks.indexOf(this);
 
- 			if(idx >= 0) {
 
- 				block.chunks.splice(idx, 1);
 
- 				if(block.chunks.length === 0) {
 
- 					block.chunks = null;
 
- 					block.chunkReason = reason;
 
- 				}
 
- 			}
 
- 		});
 
- 	}
 
- 	moveModule(module, otherChunk) {
 
- 		module.removeChunk(this);
 
- 		module.addChunk(otherChunk);
 
- 		otherChunk.addModule(module);
 
- 		module.rewriteChunkInReasons(this, [otherChunk]);
 
- 	}
 
- 	replaceChunk(oldChunk, newChunk) {
 
- 		const idx = this.chunks.indexOf(oldChunk);
 
- 		if(idx >= 0) {
 
- 			this.chunks.splice(idx, 1);
 
- 		}
 
- 		if(this !== newChunk && newChunk.addParent(this)) {
 
- 			this.addChunk(newChunk);
 
- 		}
 
- 	}
 
- 	replaceParentChunk(oldParentChunk, newParentChunk) {
 
- 		const idx = this.parents.indexOf(oldParentChunk);
 
- 		if(idx >= 0) {
 
- 			this.parents.splice(idx, 1);
 
- 		}
 
- 		if(this !== newParentChunk && newParentChunk.addChunk(this)) {
 
- 			this.addParent(newParentChunk);
 
- 		}
 
- 	}
 
- 	integrate(otherChunk, reason) {
 
- 		if(!this.canBeIntegrated(otherChunk)) {
 
- 			return false;
 
- 		}
 
- 		// Array.from is used here to create a clone, because moveModule modifies otherChunk._modules
 
- 		const otherChunkModules = Array.from(otherChunk._modules);
 
- 		otherChunkModules.forEach(module => otherChunk.moveModule(module, this));
 
- 		otherChunk._modules.clear();
 
- 		otherChunk.parents.forEach(parentChunk => parentChunk.replaceChunk(otherChunk, this));
 
- 		otherChunk.parents.length = 0;
 
- 		otherChunk.chunks.forEach(chunk => chunk.replaceParentChunk(otherChunk, this));
 
- 		otherChunk.chunks.length = 0;
 
- 		otherChunk.blocks.forEach(b => {
 
- 			b.chunks = b.chunks ? b.chunks.map(c => {
 
- 				return c === otherChunk ? this : c;
 
- 			}) : [this];
 
- 			b.chunkReason = reason;
 
- 			this.addBlock(b);
 
- 		});
 
- 		otherChunk.blocks.length = 0;
 
- 		otherChunk.origins.forEach(origin => {
 
- 			this.origins.push(origin);
 
- 		});
 
- 		this.origins.forEach(origin => {
 
- 			if(!origin.reasons) {
 
- 				origin.reasons = [reason];
 
- 			} else if(origin.reasons[0] !== reason) {
 
- 				origin.reasons.unshift(reason);
 
- 			}
 
- 		});
 
- 		this.chunks = this.chunks.filter(chunk => {
 
- 			return chunk !== otherChunk && chunk !== this;
 
- 		});
 
- 		this.parents = this.parents.filter(parentChunk => {
 
- 			return parentChunk !== otherChunk && parentChunk !== this;
 
- 		});
 
- 		return true;
 
- 	}
 
- 	split(newChunk) {
 
- 		this.blocks.forEach(block => {
 
- 			newChunk.blocks.push(block);
 
- 			block.chunks.push(newChunk);
 
- 		});
 
- 		this.chunks.forEach(chunk => {
 
- 			newChunk.chunks.push(chunk);
 
- 			chunk.parents.push(newChunk);
 
- 		});
 
- 		this.parents.forEach(parentChunk => {
 
- 			parentChunk.chunks.push(newChunk);
 
- 			newChunk.parents.push(parentChunk);
 
- 		});
 
- 		this.entrypoints.forEach(entrypoint => {
 
- 			entrypoint.insertChunk(newChunk, this);
 
- 		});
 
- 	}
 
- 	isEmpty() {
 
- 		return this._modules.size === 0;
 
- 	}
 
- 	updateHash(hash) {
 
- 		hash.update(`${this.id} `);
 
- 		hash.update(this.ids ? this.ids.join(",") : "");
 
- 		hash.update(`${this.name || ""} `);
 
- 		this._modules.forEach(m => m.updateHash(hash));
 
- 	}
 
- 	canBeIntegrated(otherChunk) {
 
- 		if(otherChunk.isInitial()) {
 
- 			return false;
 
- 		}
 
- 		if(this.isInitial()) {
 
- 			if(otherChunk.parents.length !== 1 || otherChunk.parents[0] !== this) {
 
- 				return false;
 
- 			}
 
- 		}
 
- 		return true;
 
- 	}
 
- 	addMultiplierAndOverhead(size, options) {
 
- 		const overhead = typeof options.chunkOverhead === "number" ? options.chunkOverhead : 10000;
 
- 		const multiplicator = this.isInitial() ? (options.entryChunkMultiplicator || 10) : 1;
 
- 		return size * multiplicator + overhead;
 
- 	}
 
- 	modulesSize() {
 
- 		let count = 0;
 
- 		for(const module of this._modules) {
 
- 			count += module.size();
 
- 		}
 
- 		return count;
 
- 	}
 
- 	size(options) {
 
- 		return this.addMultiplierAndOverhead(this.modulesSize(), options);
 
- 	}
 
- 	integratedSize(otherChunk, options) {
 
- 		// Chunk if it's possible to integrate this chunk
 
- 		if(!this.canBeIntegrated(otherChunk)) {
 
- 			return false;
 
- 		}
 
- 		let integratedModulesSize = this.modulesSize();
 
- 		// only count modules that do not exist in this chunk!
 
- 		for(const otherModule of otherChunk._modules) {
 
- 			if(!this._modules.has(otherModule)) {
 
- 				integratedModulesSize += otherModule.size();
 
- 			}
 
- 		}
 
- 		return this.addMultiplierAndOverhead(integratedModulesSize, options);
 
- 	}
 
- 	getChunkMaps(includeEntries, realHash) {
 
- 		const chunksProcessed = [];
 
- 		const chunkHashMap = {};
 
- 		const chunkNameMap = {};
 
- 		(function addChunk(chunk) {
 
- 			if(chunksProcessed.indexOf(chunk) >= 0) return;
 
- 			chunksProcessed.push(chunk);
 
- 			if(!chunk.hasRuntime() || includeEntries) {
 
- 				chunkHashMap[chunk.id] = realHash ? chunk.hash : chunk.renderedHash;
 
- 				if(chunk.name)
 
- 					chunkNameMap[chunk.id] = chunk.name;
 
- 			}
 
- 			chunk.chunks.forEach(addChunk);
 
- 		}(this));
 
- 		return {
 
- 			hash: chunkHashMap,
 
- 			name: chunkNameMap
 
- 		};
 
- 	}
 
- 	sortModules(sortByFn) {
 
- 		this._modules.sortWith(sortByFn || sortById);
 
- 	}
 
- 	sortItems() {
 
- 		this.sortModules();
 
- 		this.origins.sort((a, b) => {
 
- 			const aIdent = a.module.identifier();
 
- 			const bIdent = b.module.identifier();
 
- 			if(aIdent < bIdent) return -1;
 
- 			if(aIdent > bIdent) return 1;
 
- 			return compareLocations(a.loc, b.loc);
 
- 		});
 
- 		this.origins.forEach(origin => {
 
- 			if(origin.reasons)
 
- 				origin.reasons.sort();
 
- 		});
 
- 		this.parents.sort(sortById);
 
- 		this.chunks.sort(sortById);
 
- 	}
 
- 	toString() {
 
- 		return `Chunk[${Array.from(this._modules).join()}]`;
 
- 	}
 
- 	checkConstraints() {
 
- 		const chunk = this;
 
- 		chunk.chunks.forEach((child, idx) => {
 
- 			if(chunk.chunks.indexOf(child) !== idx)
 
- 				throw new Error(`checkConstraints: duplicate child in chunk ${chunk.debugId} ${child.debugId}`);
 
- 			if(child.parents.indexOf(chunk) < 0)
 
- 				throw new Error(`checkConstraints: child missing parent ${chunk.debugId} -> ${child.debugId}`);
 
- 		});
 
- 		chunk.parents.forEach((parentChunk, idx) => {
 
- 			if(chunk.parents.indexOf(parentChunk) !== idx)
 
- 				throw new Error(`checkConstraints: duplicate parent in chunk ${chunk.debugId} ${parentChunk.debugId}`);
 
- 			if(parentChunk.chunks.indexOf(chunk) < 0)
 
- 				throw new Error(`checkConstraints: parent missing child ${parentChunk.debugId} <- ${chunk.debugId}`);
 
- 		});
 
- 	}
 
- }
 
- Object.defineProperty(Chunk.prototype, "modules", {
 
- 	configurable: false,
 
- 	get: util.deprecate(function() {
 
- 		return Array.from(this._modules);
 
- 	}, "Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead."),
 
- 	set: util.deprecate(function(value) {
 
- 		this.setModules(value);
 
- 	}, "Chunk.modules is deprecated. Use Chunk.addModule/removeModule instead.")
 
- });
 
- module.exports = Chunk;
 
 
  |