2013-01-31 01:49:25 +08:00
|
|
|
/*
|
|
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
|
|
Author Tobias Koppers @sokra
|
|
|
|
*/
|
2017-01-05 00:17:49 +08:00
|
|
|
"use strict";
|
|
|
|
|
2017-04-21 16:05:56 +08:00
|
|
|
const util = require("util");
|
2017-01-05 00:17:49 +08:00
|
|
|
const compareLocations = require("./compareLocations");
|
2017-06-18 11:57:11 +08:00
|
|
|
const SortableSet = require("./util/SortableSet");
|
2017-01-05 00:17:49 +08:00
|
|
|
let debugId = 1000;
|
|
|
|
|
2017-06-19 20:13:44 +08:00
|
|
|
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;
|
|
|
|
};
|
2017-06-18 11:57:11 +08:00
|
|
|
|
2017-11-06 18:26:16 +08:00
|
|
|
const getFrozenArray = set => Object.freeze(Array.from(set));
|
2017-11-03 17:17:08 +08:00
|
|
|
|
|
|
|
const getModulesIdent = set => {
|
|
|
|
set.sort();
|
|
|
|
let str = "";
|
|
|
|
set.forEach(m => {
|
|
|
|
str += m.identifier() + "#";
|
|
|
|
});
|
|
|
|
return str;
|
|
|
|
};
|
|
|
|
|
|
|
|
const getArray = set => Array.from(set);
|
|
|
|
|
|
|
|
const getModulesSize = set => {
|
|
|
|
let count = 0;
|
|
|
|
for(const module of set) {
|
|
|
|
count += module.size();
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
};
|
|
|
|
|
2017-06-19 20:13:44 +08:00
|
|
|
class Chunk {
|
2017-06-18 11:57:11 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
constructor(name, module, loc) {
|
|
|
|
this.id = null;
|
|
|
|
this.ids = null;
|
|
|
|
this.debugId = debugId++;
|
|
|
|
this.name = name;
|
2017-11-06 20:02:35 +08:00
|
|
|
this.entryModule = undefined;
|
2017-06-19 20:13:44 +08:00
|
|
|
this._modules = new SortableSet(undefined, sortByIdentifier);
|
2017-11-06 23:41:26 +08:00
|
|
|
this._entrypoints = new SortableSet();
|
2017-06-24 09:40:24 +08:00
|
|
|
this._chunks = new SortableSet(undefined, sortById);
|
2017-09-22 22:38:47 +08:00
|
|
|
this._parents = new SortableSet(undefined, sortById);
|
|
|
|
this._blocks = new SortableSet();
|
2017-01-05 00:17:49 +08:00
|
|
|
this.origins = [];
|
|
|
|
this.files = [];
|
|
|
|
this.rendered = false;
|
2017-11-06 20:02:35 +08:00
|
|
|
this.hash = undefined;
|
|
|
|
this.renderedHash = undefined;
|
|
|
|
this.chunkReason = undefined;
|
|
|
|
this.extraAsync = false;
|
2017-01-05 00:17:49 +08:00
|
|
|
if(module) {
|
|
|
|
this.origins.push({
|
|
|
|
module,
|
|
|
|
loc,
|
|
|
|
name
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
get entry() {
|
2016-07-13 17:03:14 +08:00
|
|
|
throw new Error("Chunk.entry was removed. Use hasRuntime()");
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
set entry(data) {
|
2016-07-13 17:03:14 +08:00
|
|
|
throw new Error("Chunk.entry was removed. Use hasRuntime()");
|
|
|
|
}
|
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
get initial() {
|
2016-07-13 17:03:14 +08:00
|
|
|
throw new Error("Chunk.initial was removed. Use isInitial()");
|
|
|
|
}
|
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
set initial(data) {
|
|
|
|
throw new Error("Chunk.initial was removed. Use isInitial()");
|
|
|
|
}
|
2016-07-13 17:03:14 +08:00
|
|
|
|
2017-06-24 09:03:48 +08:00
|
|
|
/**
|
2017-09-22 20:07:28 +08:00
|
|
|
* @return {Array} - an array containing the chunks
|
2017-06-24 09:03:48 +08:00
|
|
|
*/
|
|
|
|
getChunks() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._chunks.getFromCache(getArray);
|
2017-09-22 20:07:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
getNumberOfChunks() {
|
|
|
|
return this._chunks.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
get chunksIterable() {
|
2017-06-24 09:03:48 +08:00
|
|
|
return this._chunks;
|
|
|
|
}
|
|
|
|
|
2017-09-22 22:38:47 +08:00
|
|
|
/**
|
|
|
|
* @return {Array} - an array containing the parents
|
|
|
|
*/
|
|
|
|
getParents() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._parents.getFromCache(getArray);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
setParents(newParents) {
|
|
|
|
this._parents.clear();
|
|
|
|
for(const p of newParents)
|
|
|
|
this._parents.add(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
mapParents(fn) {
|
|
|
|
return Array.from(this._parents, fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
getNumberOfParents() {
|
|
|
|
return this._parents.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
hasParent(parent) {
|
|
|
|
return this._parents.has(parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
get parentsIterable() {
|
|
|
|
return this._parents;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return {Array} - an array containing the blocks
|
|
|
|
*/
|
|
|
|
getBlocks() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._blocks.getFromCache(getArray);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
setBlocks(newBlocks) {
|
|
|
|
this._blocks.clear();
|
|
|
|
for(const p of newBlocks)
|
|
|
|
this._blocks.add(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
mapBlocks(fn) {
|
|
|
|
return Array.from(this._blocks, fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
getNumberOfBlocks() {
|
|
|
|
return this._blocks.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
hasBlock(block) {
|
|
|
|
return this._blocks.has(block);
|
|
|
|
}
|
|
|
|
|
|
|
|
get blocksIterable() {
|
|
|
|
return this._blocks;
|
|
|
|
}
|
|
|
|
|
2017-11-06 23:41:26 +08:00
|
|
|
/**
|
|
|
|
* @return {Array} - an array containing the entrypoints
|
|
|
|
*/
|
|
|
|
getEntrypoints() {
|
|
|
|
return this._entrypoints.getFromCache(getArray);
|
|
|
|
}
|
|
|
|
|
|
|
|
setEntrypoints(newEntrypoints) {
|
|
|
|
this._entrypoints.clear();
|
|
|
|
for(const p of newEntrypoints)
|
|
|
|
this._entrypoints.add(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
mapEntrypoints(fn) {
|
|
|
|
return Array.from(this._entrypoints, fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
getNumberOfEntrypoints() {
|
|
|
|
return this._entrypoints.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
hasEntrypoint(entrypoint) {
|
|
|
|
return this._entrypoints.has(entrypoint);
|
|
|
|
}
|
|
|
|
|
|
|
|
get entrypointsIterable() {
|
|
|
|
return this._entrypoints;
|
|
|
|
}
|
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
hasRuntime() {
|
2017-11-06 23:41:26 +08:00
|
|
|
for(const entrypoint of this._entrypoints) {
|
|
|
|
// We only need to check the first one
|
|
|
|
return entrypoint.getRuntimeChunk() === this;
|
|
|
|
}
|
|
|
|
return false;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2016-07-13 17:03:14 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
isInitial() {
|
2017-11-06 23:41:26 +08:00
|
|
|
return this._entrypoints.size > 0;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2016-07-13 17:03:14 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
hasEntryModule() {
|
|
|
|
return !!this.entryModule;
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
|
2017-01-26 13:55:20 +08:00
|
|
|
addToCollection(collection, item) {
|
|
|
|
if(item === this) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(collection.indexOf(item) > -1) {
|
2017-01-05 00:17:49 +08:00
|
|
|
return false;
|
|
|
|
}
|
2017-01-26 13:55:20 +08:00
|
|
|
|
|
|
|
collection.push(item);
|
2017-01-05 00:17:49 +08:00
|
|
|
return true;
|
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
|
2017-01-26 13:55:20 +08:00
|
|
|
addChunk(chunk) {
|
2017-06-21 20:56:58 +08:00
|
|
|
if(this._chunks.has(chunk)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this._chunks.add(chunk);
|
|
|
|
return true;
|
2017-01-26 13:55:20 +08:00
|
|
|
}
|
|
|
|
|
2017-01-26 15:46:49 +08:00
|
|
|
addParent(parentChunk) {
|
2017-09-22 22:38:47 +08:00
|
|
|
if(!this._parents.has(parentChunk)) {
|
|
|
|
this._parents.add(parentChunk);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2017-01-26 13:55:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
addModule(module) {
|
2017-04-21 16:05:56 +08:00
|
|
|
if(!this._modules.has(module)) {
|
|
|
|
this._modules.add(module);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2017-01-26 13:55:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
addBlock(block) {
|
2017-09-22 22:38:47 +08:00
|
|
|
if(!this._blocks.has(block)) {
|
|
|
|
this._blocks.add(block);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2017-01-26 13:55:20 +08:00
|
|
|
}
|
|
|
|
|
2017-11-06 23:41:26 +08:00
|
|
|
addEntrypoint(entrypoint) {
|
|
|
|
if(!this._entrypoints.has(entrypoint)) {
|
|
|
|
this._entrypoints.add(entrypoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
removeModule(module) {
|
2017-04-21 16:05:56 +08:00
|
|
|
if(this._modules.delete(module)) {
|
2017-02-13 18:26:25 +08:00
|
|
|
module.removeChunk(this);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
removeChunk(chunk) {
|
2017-06-21 20:56:58 +08:00
|
|
|
if(!this._chunks.has(chunk)) {
|
|
|
|
return false;
|
2017-02-13 18:26:25 +08:00
|
|
|
}
|
2017-06-21 20:56:58 +08:00
|
|
|
|
|
|
|
this._chunks.delete(chunk);
|
|
|
|
chunk.removeParent(this);
|
|
|
|
return true;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
removeParent(chunk) {
|
2017-09-22 22:38:47 +08:00
|
|
|
if(this._parents.delete(chunk)) {
|
2017-02-13 18:26:25 +08:00
|
|
|
chunk.removeChunk(this);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2013-01-31 01:49:25 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
addOrigin(module, loc) {
|
|
|
|
this.origins.push({
|
|
|
|
module,
|
|
|
|
loc,
|
|
|
|
name: this.name
|
|
|
|
});
|
|
|
|
}
|
2014-06-25 00:53:32 +08:00
|
|
|
|
2017-04-21 16:05:56 +08:00
|
|
|
setModules(modules) {
|
2017-06-19 20:13:44 +08:00
|
|
|
this._modules = new SortableSet(modules, sortByIdentifier);
|
2017-04-21 16:05:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
getNumberOfModules() {
|
|
|
|
return this._modules.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
get modulesIterable() {
|
|
|
|
return this._modules;
|
|
|
|
}
|
|
|
|
|
|
|
|
forEachModule(fn) {
|
|
|
|
this._modules.forEach(fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
mapModules(fn) {
|
2017-05-20 20:46:21 +08:00
|
|
|
return Array.from(this._modules, fn);
|
2017-04-21 16:05:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
compareTo(otherChunk) {
|
2017-06-18 11:57:11 +08:00
|
|
|
this._modules.sort();
|
|
|
|
otherChunk._modules.sort();
|
2017-04-21 16:05:56 +08:00
|
|
|
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() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._modules.getFromCache(getArray);
|
2017-04-21 16:05:56 +08:00
|
|
|
}
|
|
|
|
|
2017-06-01 22:10:27 +08:00
|
|
|
getModulesIdent() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._modules.getFromUnorderedCache(getModulesIdent);
|
2017-06-01 22:10:27 +08:00
|
|
|
}
|
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
remove(reason) {
|
2017-01-26 12:47:31 +08:00
|
|
|
// cleanup modules
|
2017-05-20 20:46:21 +08:00
|
|
|
// Array.from is used here to create a clone, because removeChunk modifies this._modules
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const module of Array.from(this._modules)) {
|
2017-01-26 12:42:23 +08:00
|
|
|
module.removeChunk(this);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
2017-01-26 12:47:31 +08:00
|
|
|
|
|
|
|
// cleanup parents
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const parentChunk of this._parents) {
|
2017-01-26 12:47:31 +08:00
|
|
|
// remove this chunk from its parents
|
2017-06-21 20:56:58 +08:00
|
|
|
parentChunk._chunks.delete(this);
|
2017-01-26 12:47:31 +08:00
|
|
|
|
|
|
|
// cleanup "sub chunks"
|
2017-06-21 20:56:58 +08:00
|
|
|
this._chunks.forEach(chunk => {
|
2017-01-26 12:47:31 +08:00
|
|
|
/**
|
|
|
|
* remove this chunk as "intermediary" and connect
|
|
|
|
* it "sub chunks" and parents directly
|
|
|
|
*/
|
|
|
|
// add parent to each "sub chunk"
|
2017-01-26 15:46:49 +08:00
|
|
|
chunk.addParent(parentChunk);
|
2017-01-26 12:47:31 +08:00
|
|
|
// add "sub chunk" to parent
|
2017-01-26 15:46:49 +08:00
|
|
|
parentChunk.addChunk(chunk);
|
2017-01-05 00:17:49 +08:00
|
|
|
});
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
2017-01-26 12:47:31 +08:00
|
|
|
|
2017-02-13 18:32:33 +08:00
|
|
|
/**
|
|
|
|
* we need to iterate again over the chunks
|
|
|
|
* to remove this from the chunks parents.
|
|
|
|
* This can not be done in the above loop
|
2017-09-22 22:38:47 +08:00
|
|
|
* as it is not garuanteed that `this._parents` contains anything.
|
2017-02-13 18:32:33 +08:00
|
|
|
*/
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const chunk of this._chunks) {
|
2017-02-13 18:32:33 +08:00
|
|
|
// remove this as parent of every "sub chunk"
|
2017-09-22 22:38:47 +08:00
|
|
|
chunk._parents.delete(this);
|
|
|
|
}
|
2017-02-13 18:32:33 +08:00
|
|
|
|
2017-01-26 12:47:31 +08:00
|
|
|
// cleanup blocks
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const block of this._blocks) {
|
2017-01-26 12:42:23 +08:00
|
|
|
const idx = block.chunks.indexOf(this);
|
2017-01-05 00:17:49 +08:00
|
|
|
if(idx >= 0) {
|
2017-01-26 12:42:23 +08:00
|
|
|
block.chunks.splice(idx, 1);
|
|
|
|
if(block.chunks.length === 0) {
|
|
|
|
block.chunks = null;
|
|
|
|
block.chunkReason = reason;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2014-06-25 00:53:32 +08:00
|
|
|
|
2017-01-26 14:08:35 +08:00
|
|
|
moveModule(module, otherChunk) {
|
2017-01-05 00:17:49 +08:00
|
|
|
module.removeChunk(this);
|
2017-01-26 14:08:35 +08:00
|
|
|
module.addChunk(otherChunk);
|
|
|
|
otherChunk.addModule(module);
|
|
|
|
module.rewriteChunkInReasons(this, [otherChunk]);
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
|
2017-01-26 14:53:23 +08:00
|
|
|
replaceChunk(oldChunk, newChunk) {
|
2017-06-21 20:56:58 +08:00
|
|
|
this._chunks.delete(oldChunk);
|
2017-01-26 14:53:23 +08:00
|
|
|
if(this !== newChunk && newChunk.addParent(this)) {
|
|
|
|
this.addChunk(newChunk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-26 15:46:49 +08:00
|
|
|
replaceParentChunk(oldParentChunk, newParentChunk) {
|
2017-09-22 22:38:47 +08:00
|
|
|
this._parents.delete(oldParentChunk);
|
2017-01-26 15:46:49 +08:00
|
|
|
if(this !== newParentChunk && newParentChunk.addChunk(this)) {
|
|
|
|
this.addParent(newParentChunk);
|
2017-01-26 14:53:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-26 15:43:39 +08:00
|
|
|
integrate(otherChunk, reason) {
|
|
|
|
if(!this.canBeIntegrated(otherChunk)) {
|
2017-01-05 00:17:49 +08:00
|
|
|
return false;
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
|
2017-05-20 20:46:21 +08:00
|
|
|
// Array.from is used here to create a clone, because moveModule modifies otherChunk._modules
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const module of Array.from(otherChunk._modules)) {
|
|
|
|
otherChunk.moveModule(module, this);
|
|
|
|
}
|
2017-04-21 16:05:56 +08:00
|
|
|
otherChunk._modules.clear();
|
2017-01-05 00:17:49 +08:00
|
|
|
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const parentChunk of otherChunk._parents) {
|
|
|
|
parentChunk.replaceChunk(otherChunk, this);
|
|
|
|
}
|
|
|
|
otherChunk._parents.clear();
|
2017-01-26 14:56:42 +08:00
|
|
|
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const chunk of otherChunk._chunks) {
|
|
|
|
chunk.replaceParentChunk(otherChunk, this);
|
|
|
|
}
|
2017-06-21 20:56:58 +08:00
|
|
|
otherChunk._chunks.clear();
|
2017-01-26 14:56:42 +08:00
|
|
|
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const b of otherChunk._blocks) {
|
2017-01-26 15:08:27 +08:00
|
|
|
b.chunks = b.chunks ? b.chunks.map(c => {
|
2017-01-26 15:43:39 +08:00
|
|
|
return c === otherChunk ? this : c;
|
2017-01-26 15:08:58 +08:00
|
|
|
}) : [this];
|
2017-01-05 00:17:49 +08:00
|
|
|
b.chunkReason = reason;
|
|
|
|
this.addBlock(b);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
|
|
|
otherChunk._blocks.clear();
|
2017-01-26 15:08:58 +08:00
|
|
|
|
2017-01-26 15:43:39 +08:00
|
|
|
otherChunk.origins.forEach(origin => {
|
2017-01-05 00:17:49 +08:00
|
|
|
this.origins.push(origin);
|
2017-01-26 15:08:58 +08:00
|
|
|
});
|
2017-11-11 18:27:02 +08:00
|
|
|
for(const b of this._blocks) {
|
2017-10-13 01:13:35 +08:00
|
|
|
b.chunkReason = reason;
|
2017-11-11 18:27:02 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
this.origins.forEach(origin => {
|
|
|
|
if(!origin.reasons) {
|
|
|
|
origin.reasons = [reason];
|
|
|
|
} else if(origin.reasons[0] !== reason) {
|
|
|
|
origin.reasons.unshift(reason);
|
|
|
|
}
|
|
|
|
});
|
2017-06-21 20:56:58 +08:00
|
|
|
this._chunks.delete(otherChunk);
|
|
|
|
this._chunks.delete(this);
|
2017-11-11 18:27:02 +08:00
|
|
|
this._parents.delete(otherChunk);
|
|
|
|
this._parents.delete(this);
|
2017-01-05 00:17:49 +08:00
|
|
|
return true;
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2014-02-04 01:12:19 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
split(newChunk) {
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const block of this._blocks) {
|
|
|
|
newChunk._blocks.add(block);
|
2017-01-26 15:43:39 +08:00
|
|
|
block.chunks.push(newChunk);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
|
|
|
for(const chunk of this._chunks) {
|
2017-06-21 20:56:58 +08:00
|
|
|
newChunk.addChunk(chunk);
|
2017-09-22 22:38:47 +08:00
|
|
|
chunk._parents.add(newChunk);
|
|
|
|
}
|
|
|
|
for(const parentChunk of this._parents) {
|
2017-06-21 20:56:58 +08:00
|
|
|
parentChunk.addChunk(newChunk);
|
2017-09-22 22:38:47 +08:00
|
|
|
newChunk._parents.add(parentChunk);
|
|
|
|
}
|
2017-11-06 23:41:26 +08:00
|
|
|
for(const entrypoint of this._entrypoints) {
|
2017-01-26 15:43:39 +08:00
|
|
|
entrypoint.insertChunk(newChunk, this);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
2014-06-25 00:53:32 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
|
|
|
|
isEmpty() {
|
2017-04-21 16:05:56 +08:00
|
|
|
return this._modules.size === 0;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
updateHash(hash) {
|
|
|
|
hash.update(`${this.id} `);
|
|
|
|
hash.update(this.ids ? this.ids.join(",") : "");
|
|
|
|
hash.update(`${this.name || ""} `);
|
2017-10-30 20:56:57 +08:00
|
|
|
this._modules.forEach(m => hash.update(m.hash));
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
|
|
|
|
2017-01-26 15:47:45 +08:00
|
|
|
canBeIntegrated(otherChunk) {
|
|
|
|
if(otherChunk.isInitial()) {
|
2017-01-05 00:17:49 +08:00
|
|
|
return false;
|
2014-08-22 19:51:24 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
if(this.isInitial()) {
|
2017-09-22 22:38:47 +08:00
|
|
|
if(otherChunk.getNumberOfParents() !== 1 || otherChunk.getParents()[0] !== this) {
|
2017-01-05 00:17:49 +08:00
|
|
|
return false;
|
|
|
|
}
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
return true;
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
|
2017-01-26 15:41:51 +08:00
|
|
|
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() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._modules.getFromUnorderedCache(getModulesSize);
|
2017-01-26 15:41:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
size(options) {
|
|
|
|
return this.addMultiplierAndOverhead(this.modulesSize(), options);
|
|
|
|
}
|
|
|
|
|
2017-01-26 15:47:45 +08:00
|
|
|
integratedSize(otherChunk, options) {
|
2017-01-05 00:17:49 +08:00
|
|
|
// Chunk if it's possible to integrate this chunk
|
2017-01-26 15:47:45 +08:00
|
|
|
if(!this.canBeIntegrated(otherChunk)) {
|
2014-06-04 03:03:21 +08:00
|
|
|
return false;
|
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
|
2017-01-26 21:24:33 +08:00
|
|
|
let integratedModulesSize = this.modulesSize();
|
|
|
|
// only count modules that do not exist in this chunk!
|
2017-05-20 20:46:21 +08:00
|
|
|
for(const otherModule of otherChunk._modules) {
|
2017-04-21 16:05:56 +08:00
|
|
|
if(!this._modules.has(otherModule)) {
|
2017-01-26 21:24:33 +08:00
|
|
|
integratedModulesSize += otherModule.size();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.addMultiplierAndOverhead(integratedModulesSize, options);
|
2014-02-04 01:12:19 +08:00
|
|
|
}
|
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
getChunkMaps(includeEntries, realHash) {
|
2017-10-30 20:56:57 +08:00
|
|
|
const chunksProcessed = new Set();
|
|
|
|
const chunkHashMap = Object.create(null);
|
|
|
|
const chunkNameMap = Object.create(null);
|
2017-11-08 18:32:05 +08:00
|
|
|
const addChunk = chunk => {
|
2017-10-30 20:56:57 +08:00
|
|
|
if(chunksProcessed.has(chunk)) return;
|
|
|
|
chunksProcessed.add(chunk);
|
2017-01-26 15:41:19 +08:00
|
|
|
if(!chunk.hasRuntime() || includeEntries) {
|
|
|
|
chunkHashMap[chunk.id] = realHash ? chunk.hash : chunk.renderedHash;
|
|
|
|
if(chunk.name)
|
|
|
|
chunkNameMap[chunk.id] = chunk.name;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2017-06-21 20:56:58 +08:00
|
|
|
chunk._chunks.forEach(addChunk);
|
2017-11-08 18:32:05 +08:00
|
|
|
};
|
|
|
|
addChunk(this);
|
2017-01-05 00:17:49 +08:00
|
|
|
return {
|
|
|
|
hash: chunkHashMap,
|
|
|
|
name: chunkNameMap
|
|
|
|
};
|
2014-06-04 03:03:21 +08:00
|
|
|
}
|
2014-02-04 01:12:19 +08:00
|
|
|
|
2017-10-30 20:56:57 +08:00
|
|
|
getChunkModuleMaps(includeEntries, filterFn) {
|
|
|
|
const chunksProcessed = new Set();
|
|
|
|
const chunkModuleIdMap = Object.create(null);
|
|
|
|
const chunkModuleHashMap = Object.create(null);
|
|
|
|
(function addChunk(chunk) {
|
|
|
|
if(chunksProcessed.has(chunk)) return;
|
|
|
|
chunksProcessed.add(chunk);
|
|
|
|
if(!chunk.hasRuntime() || includeEntries) {
|
|
|
|
const array = chunk.getModules().filter(filterFn);
|
|
|
|
if(array.length > 0)
|
|
|
|
chunkModuleIdMap[chunk.id] = array.map(m => m.id).sort();
|
|
|
|
for(const m of array) {
|
|
|
|
chunkModuleHashMap[m.id] = m.renderedHash;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
chunk._chunks.forEach(addChunk);
|
|
|
|
}(this));
|
|
|
|
return {
|
|
|
|
id: chunkModuleIdMap,
|
|
|
|
hash: chunkModuleHashMap
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-07-07 04:40:58 +08:00
|
|
|
sortModules(sortByFn) {
|
|
|
|
this._modules.sortWith(sortByFn || sortById);
|
2017-07-07 04:08:58 +08:00
|
|
|
}
|
|
|
|
|
2017-09-22 23:23:49 +08:00
|
|
|
sortItems(sortChunks) {
|
2017-07-07 04:08:58 +08:00
|
|
|
this.sortModules();
|
2017-01-05 00:17:49 +08:00
|
|
|
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();
|
|
|
|
});
|
2017-09-22 23:23:49 +08:00
|
|
|
if(sortChunks) {
|
|
|
|
this._parents.sort();
|
|
|
|
this._chunks.sort();
|
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2013-06-18 00:55:11 +08:00
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
toString() {
|
2017-04-21 16:05:56 +08:00
|
|
|
return `Chunk[${Array.from(this._modules).join()}]`;
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
checkConstraints() {
|
|
|
|
const chunk = this;
|
2017-09-22 22:38:47 +08:00
|
|
|
for(const child of chunk._chunks) {
|
|
|
|
if(!child._parents.has(chunk))
|
2017-01-05 00:17:49 +08:00
|
|
|
throw new Error(`checkConstraints: child missing parent ${chunk.debugId} -> ${child.debugId}`);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
|
|
|
for(const parentChunk of chunk._parents) {
|
|
|
|
if(!parentChunk._chunks.has(chunk))
|
2017-01-26 15:46:49 +08:00
|
|
|
throw new Error(`checkConstraints: parent missing child ${parentChunk.debugId} <- ${chunk.debugId}`);
|
2017-09-22 22:38:47 +08:00
|
|
|
}
|
2017-01-05 00:17:49 +08:00
|
|
|
}
|
2016-07-13 17:03:14 +08:00
|
|
|
}
|
|
|
|
|
2017-04-21 16:05:56 +08:00
|
|
|
Object.defineProperty(Chunk.prototype, "modules", {
|
|
|
|
configurable: false,
|
|
|
|
get: util.deprecate(function() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._modules.getFromCache(getFrozenArray);
|
2017-04-21 16:05:56 +08:00
|
|
|
}, "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.")
|
|
|
|
});
|
|
|
|
|
2017-06-24 09:03:48 +08:00
|
|
|
Object.defineProperty(Chunk.prototype, "chunks", {
|
|
|
|
configurable: false,
|
|
|
|
get: util.deprecate(function() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._chunks.getFromCache(getFrozenArray);
|
2017-06-24 09:03:48 +08:00
|
|
|
}, "Chunk.chunks: Use Chunk.getChunks() instead"),
|
|
|
|
set() {
|
|
|
|
throw new Error("Readonly. Use Chunk.addChunk/removeChunk/getChunks to access/modify chunks.");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-09-22 22:38:47 +08:00
|
|
|
Object.defineProperty(Chunk.prototype, "parents", {
|
|
|
|
configurable: false,
|
|
|
|
get: util.deprecate(function() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._parents.getFromCache(getFrozenArray);
|
2017-09-22 22:38:47 +08:00
|
|
|
}, "Chunk.parents: Use Chunk.getParents() instead"),
|
|
|
|
set: util.deprecate(function(value) {
|
|
|
|
this.setParents(value);
|
|
|
|
}, "Chunk.parents: Use Chunk.addParent/removeParent/setParents to modify parents.")
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.defineProperty(Chunk.prototype, "blocks", {
|
|
|
|
configurable: false,
|
|
|
|
get: util.deprecate(function() {
|
2017-11-06 19:15:23 +08:00
|
|
|
return this._blocks.getFromCache(getFrozenArray);
|
2017-09-22 22:38:47 +08:00
|
|
|
}, "Chunk.blocks: Use Chunk.getBlocks() instead"),
|
|
|
|
set: util.deprecate(function(value) {
|
|
|
|
this.setBlocks(value);
|
|
|
|
}, "Chunk.blocks: Use Chunk.addBlock/removeBlock/setBlocks to modify blocks.")
|
|
|
|
});
|
|
|
|
|
2017-11-06 23:41:26 +08:00
|
|
|
Object.defineProperty(Chunk.prototype, "entrypoints", {
|
|
|
|
configurable: false,
|
|
|
|
get: util.deprecate(function() {
|
|
|
|
return this._entrypoints.getFromCache(getFrozenArray);
|
|
|
|
}, "Chunk.entrypoints: Use Chunk.getEntrypoints() instead"),
|
|
|
|
set: util.deprecate(function(value) {
|
|
|
|
this.setBlocks(value);
|
|
|
|
}, "Chunk.entrypoints: Use Chunk.addEntrypoint/setEntrypoints to modify entrypoints.")
|
|
|
|
});
|
|
|
|
|
2017-01-05 00:17:49 +08:00
|
|
|
module.exports = Chunk;
|