Izmjenjena struktura, dodan backand

This commit is contained in:
GotPPay
2017-10-16 11:19:46 +02:00
parent 1ec88afacb
commit 048e32c4aa
37153 changed files with 2975854 additions and 1 deletions

View File

@@ -0,0 +1,121 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class AggressiveMergingPlugin {
constructor(options) {
if(options !== undefined && typeof options !== "object" || Array.isArray(options)) {
throw new Error("Argument should be an options object. To use defaults, pass in nothing.\nFor more info on options, see https://webpack.js.org/plugins/");
}
this.options = options || {};
}
apply(compiler) {
const options = this.options;
const minSizeReduce = options.minSizeReduce || 1.5;
function getParentsWeight(chunk) {
return chunk.parents.map((p) => {
return p.isInitial() ? options.entryChunkMultiplicator || 10 : 1;
}).reduce((a, b) => {
return a + b;
}, 0);
}
compiler.plugin("compilation", (compilation) => {
compilation.plugin("optimize-chunks-advanced", (chunks) => {
let combinations = [];
chunks.forEach((a, idx) => {
if(a.isInitial()) return;
for(let i = 0; i < idx; i++) {
const b = chunks[i];
if(b.isInitial()) continue;
combinations.push([b, a]);
}
});
combinations.forEach((pair) => {
const a = pair[0].size({
chunkOverhead: 0
});
const b = pair[1].size({
chunkOverhead: 0
});
const ab = pair[0].integratedSize(pair[1], {
chunkOverhead: 0
});
pair.push({
a: a,
b: b,
ab: ab
});
let newSize;
if(ab === false) {
pair.unshift(false);
} else if(options.moveToParents) {
const aOnly = ab - b;
const bOnly = ab - a;
const common = a + b - ab;
newSize = common + getParentsWeight(pair[0]) * aOnly + getParentsWeight(pair[1]) * bOnly;
pair.push({
aOnly: aOnly,
bOnly: bOnly,
common: common,
newSize: newSize
});
} else {
newSize = ab;
}
pair.unshift((a + b) / newSize);
});
combinations = combinations.filter((pair) => {
return pair[0] !== false;
});
combinations.sort((a, b) => {
return b[0] - a[0];
});
const pair = combinations[0];
if(!pair) return;
if(pair[0] < minSizeReduce) return;
if(options.moveToParents) {
const commonModules = pair[1].modules.filter((m) => {
return pair[2].modules.indexOf(m) >= 0;
});
const aOnlyModules = pair[1].modules.filter((m) => {
return commonModules.indexOf(m) < 0;
});
const bOnlyModules = pair[2].modules.filter((m) => {
return commonModules.indexOf(m) < 0;
});
aOnlyModules.forEach((m) => {
pair[1].removeModule(m);
m.removeChunk(pair[1]);
pair[1].parents.forEach((c) => {
c.addModule(m);
m.addChunk(c);
});
});
bOnlyModules.forEach((m) => {
pair[2].removeModule(m);
m.removeChunk(pair[2]);
pair[2].parents.forEach((c) => {
c.addModule(m);
m.addChunk(c);
});
});
}
if(pair[1].integrate(pair[2], "aggressive-merge")) {
chunks.splice(chunks.indexOf(pair[2]), 1);
return true;
}
});
});
}
}
module.exports = AggressiveMergingPlugin;

View File

@@ -0,0 +1,192 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const identifierUtils = require("../util/identifier");
function toIndexOf(list) {
return function(item) {
return list.indexOf(item);
};
}
function toChunkModuleIndices(modules) {
return function(idx) {
return modules[idx];
};
}
function moveModuleBetween(oldChunk, newChunk) {
return function(module) {
oldChunk.moveModule(module, newChunk);
};
}
function isNotAEntryModule(entryModule) {
return function(module) {
return entryModule !== module;
};
}
function copyWithReason(obj) {
const newObj = {};
Object.keys(obj).forEach((key) => {
newObj[key] = obj[key];
});
if(!newObj.reasons || newObj.reasons.indexOf("aggressive-splitted") < 0)
newObj.reasons = (newObj.reasons || []).concat("aggressive-splitted");
return newObj;
}
class AggressiveSplittingPlugin {
constructor(options) {
this.options = options || {};
if(typeof this.options.minSize !== "number") this.options.minSize = 30 * 1024;
if(typeof this.options.maxSize !== "number") this.options.maxSize = 50 * 1024;
if(typeof this.options.chunkOverhead !== "number") this.options.chunkOverhead = 0;
if(typeof this.options.entryChunkMultiplicator !== "number") this.options.entryChunkMultiplicator = 1;
}
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.plugin("optimize-chunks-advanced", (chunks) => {
const savedSplits = compilation.records && compilation.records.aggressiveSplits || [];
const usedSplits = compilation._aggressiveSplittingSplits ?
savedSplits.concat(compilation._aggressiveSplittingSplits) : savedSplits;
const minSize = this.options.minSize;
const maxSize = this.options.maxSize;
// 1. try to restore to recorded splitting
for(let j = 0; j < usedSplits.length; j++) {
const splitData = usedSplits[j];
for(let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const chunkModuleNames = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier()));
if(chunkModuleNames.length < splitData.modules.length)
continue;
const moduleIndicies = splitData.modules.map(toIndexOf(chunkModuleNames));
const hasAllModules = moduleIndicies.every((idx) => {
return idx >= 0;
});
if(hasAllModules) {
if(chunkModuleNames.length > splitData.modules.length) {
const selectedModules = moduleIndicies.map(toChunkModuleIndices(chunk.modules));
const newChunk = compilation.addChunk();
selectedModules.forEach(moveModuleBetween(chunk, newChunk));
chunk.split(newChunk);
chunk.name = null;
newChunk._fromAggressiveSplitting = true;
if(j < savedSplits.length)
newChunk._fromAggressiveSplittingIndex = j;
if(splitData.id !== null && splitData.id !== undefined) {
newChunk.id = splitData.id;
}
newChunk.origins = chunk.origins.map(copyWithReason);
chunk.origins = chunk.origins.map(copyWithReason);
return true;
} else {
if(j < savedSplits.length)
chunk._fromAggressiveSplittingIndex = j;
chunk.name = null;
if(splitData.id !== null && splitData.id !== undefined) {
chunk.id = splitData.id;
}
}
}
}
}
// 2. for any other chunk which isn't splitted yet, split it
for(let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const size = chunk.size(this.options);
if(size > maxSize && chunk.modules.length > 1) {
const newChunk = compilation.addChunk();
const modules = chunk.modules
.filter(isNotAEntryModule(chunk.entryModule))
.sort((a, b) => {
a = a.identifier();
b = b.identifier();
if(a > b) return 1;
if(a < b) return -1;
return 0;
});
for(let k = 0; k < modules.length; k++) {
chunk.moveModule(modules[k], newChunk);
const newSize = newChunk.size(this.options);
const chunkSize = chunk.size(this.options);
// break early if it's fine
if(chunkSize < maxSize && newSize < maxSize && newSize >= minSize && chunkSize >= minSize)
break;
if(newSize > maxSize && k === 0) {
// break if there is a single module which is bigger than maxSize
break;
}
if(newSize > maxSize || chunkSize < minSize) {
// move it back
newChunk.moveModule(modules[k], chunk);
// check if it's fine now
if(newSize < maxSize && newSize >= minSize && chunkSize >= minSize)
break;
}
}
if(newChunk.modules.length > 0) {
chunk.split(newChunk);
chunk.name = null;
newChunk.origins = chunk.origins.map(copyWithReason);
chunk.origins = chunk.origins.map(copyWithReason);
compilation._aggressiveSplittingSplits = (compilation._aggressiveSplittingSplits || []).concat({
modules: newChunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier()))
});
return true;
} else {
chunks.splice(chunks.indexOf(newChunk), 1);
}
}
}
});
compilation.plugin("record-hash", (records) => {
// 3. save to made splittings to records
const minSize = this.options.minSize;
if(!records.aggressiveSplits) records.aggressiveSplits = [];
compilation.chunks.forEach((chunk) => {
if(chunk.hasEntryModule()) return;
const size = chunk.size(this.options);
const incorrectSize = size < minSize;
const modules = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier()));
if(typeof chunk._fromAggressiveSplittingIndex === "undefined") {
if(incorrectSize) return;
chunk.recorded = true;
records.aggressiveSplits.push({
modules: modules,
hash: chunk.hash,
id: chunk.id
});
} else {
const splitData = records.aggressiveSplits[chunk._fromAggressiveSplittingIndex];
if(splitData.hash !== chunk.hash || incorrectSize) {
if(chunk._fromAggressiveSplitting) {
chunk._aggressiveSplittingInvalid = true;
splitData.invalid = true;
} else {
splitData.hash = chunk.hash;
}
}
}
});
records.aggressiveSplits = records.aggressiveSplits.filter((splitData) => {
return !splitData.invalid;
});
});
compilation.plugin("need-additional-seal", (callback) => {
const invalid = compilation.chunks.some((chunk) => {
return chunk._aggressiveSplittingInvalid;
});
if(invalid)
return true;
});
});
}
}
module.exports = AggressiveSplittingPlugin;

View File

@@ -0,0 +1,55 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class ChunkModuleIdRangePlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
const options = this.options;
compiler.plugin("compilation", (compilation) => {
compilation.plugin("module-ids", (modules) => {
const chunk = this.chunks.filter((chunk) => {
return chunk.name === options.name;
})[0];
if(!chunk) throw new Error("ChunkModuleIdRangePlugin: Chunk with name '" + options.name + "' was not found");
let currentId = options.start;
let chunkModules;
if(options.order) {
chunkModules = chunk.modules.slice();
switch(options.order) {
case "index":
chunkModules.sort((a, b) => {
return a.index - b.index;
});
break;
case "index2":
chunkModules.sort((a, b) => {
return a.index2 - b.index2;
});
break;
default:
throw new Error("ChunkModuleIdRangePlugin: unexpected value of order");
}
} else {
chunkModules = modules.filter((m) => {
return m.chunks.indexOf(chunk) >= 0;
});
}
for(let i = 0; i < chunkModules.length; i++) {
const m = chunkModules[i];
if(m.id === null) {
m.id = currentId++;
}
if(options.end && currentId > options.end)
break;
}
});
});
}
}
module.exports = ChunkModuleIdRangePlugin;

View File

@@ -0,0 +1,362 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
let nextIdent = 0;
class CommonsChunkPlugin {
constructor(options) {
if(arguments.length > 1) {
throw new Error(`Deprecation notice: CommonsChunkPlugin now only takes a single argument. Either an options
object *or* the name of the chunk.
Example: if your old code looked like this:
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js')
You would change it to:
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.bundle.js' })
The available options are:
name: string
names: string[]
filename: string
minChunks: number
chunks: string[]
children: boolean
async: boolean
minSize: number`);
}
const normalizedOptions = this.normalizeOptions(options);
this.chunkNames = normalizedOptions.chunkNames;
this.filenameTemplate = normalizedOptions.filenameTemplate;
this.minChunks = normalizedOptions.minChunks;
this.selectedChunks = normalizedOptions.selectedChunks;
this.children = normalizedOptions.children;
this.async = normalizedOptions.async;
this.minSize = normalizedOptions.minSize;
this.ident = __filename + (nextIdent++);
}
normalizeOptions(options) {
if(Array.isArray(options)) {
return {
chunkNames: options,
};
}
if(typeof options === "string") {
return {
chunkNames: [options],
};
}
// options.children and options.chunk may not be used together
if(options.children && options.chunks) {
throw new Error("You can't and it does not make any sense to use \"children\" and \"chunk\" options together.");
}
/**
* options.async and options.filename are also not possible together
* as filename specifies how the chunk is called but "async" implies
* that webpack will take care of loading this file.
*/
if(options.async && options.filename) {
throw new Error(`You can not specify a filename if you use the \"async\" option.
You can however specify the name of the async chunk by passing the desired string as the \"async\" option.`);
}
/**
* Make sure this is either an array or undefined.
* "name" can be a string and
* "names" a string or an array
*/
const chunkNames = options.name || options.names ? [].concat(options.name || options.names) : undefined;
return {
chunkNames: chunkNames,
filenameTemplate: options.filename,
minChunks: options.minChunks,
selectedChunks: options.chunks,
children: options.children,
async: options.async,
minSize: options.minSize
};
}
apply(compiler) {
compiler.plugin("this-compilation", (compilation) => {
compilation.plugin(["optimize-chunks", "optimize-extracted-chunks"], (chunks) => {
// only optimize once
if(compilation[this.ident]) return;
compilation[this.ident] = true;
/**
* Creates a list of "common"" chunks based on the options.
* The list is made up of preexisting or newly created chunks.
* - If chunk has the name as specified in the chunkNames it is put in the list
* - If no chunk with the name as given in chunkNames exists a new chunk is created and added to the list
*
* These chunks are the "targets" for extracted modules.
*/
const targetChunks = this.getTargetChunks(chunks, compilation, this.chunkNames, this.children, this.async);
// iterate over all our new chunks
targetChunks.forEach((targetChunk, idx) => {
/**
* These chunks are subject to get "common" modules extracted and moved to the common chunk
*/
const affectedChunks = this.getAffectedChunks(compilation, chunks, targetChunk, targetChunks, idx, this.selectedChunks, this.async, this.children);
// bail if no chunk is affected
if(!affectedChunks) {
return;
}
// If we are async create an async chunk now
// override the "commonChunk" with the newly created async one and use it as commonChunk from now on
let asyncChunk;
if(this.async) {
asyncChunk = this.createAsyncChunk(compilation, this.async, targetChunk);
targetChunk = asyncChunk;
}
/**
* Check which modules are "common" and could be extracted to a "common" chunk
*/
const extractableModules = this.getExtractableModules(this.minChunks, affectedChunks, targetChunk);
// If the minSize option is set check if the size extracted from the chunk is reached
// else bail out here.
// As all modules/commons are interlinked with each other, common modules would be extracted
// if we reach this mark at a later common chunk. (quirky I guess).
if(this.minSize) {
const modulesSize = this.calculateModulesSize(extractableModules);
// if too small, bail
if(modulesSize < this.minSize)
return;
}
// Remove modules that are moved to commons chunk from their original chunks
// return all chunks that are affected by having modules removed - we need them later (apparently)
const chunksWithExtractedModules = this.extractModulesAndReturnAffectedChunks(extractableModules, affectedChunks);
// connect all extracted modules with the common chunk
this.addExtractedModulesToTargetChunk(targetChunk, extractableModules);
// set filenameTemplate for chunk
if(this.filenameTemplate)
targetChunk.filenameTemplate = this.filenameTemplate;
// if we are async connect the blocks of the "reallyUsedChunk" - the ones that had modules removed -
// with the commonChunk and get the origins for the asyncChunk (remember "asyncChunk === commonChunk" at this moment).
// bail out
if(this.async) {
this.moveExtractedChunkBlocksToTargetChunk(chunksWithExtractedModules, targetChunk);
asyncChunk.origins = this.extractOriginsOfChunksWithExtractedModules(chunksWithExtractedModules);
return;
}
// we are not in "async" mode
// connect used chunks with commonChunk - shouldnt this be reallyUsedChunks here?
this.makeTargetChunkParentOfAffectedChunks(affectedChunks, targetChunk);
});
return true;
});
});
}
getTargetChunks(allChunks, compilation, chunkNames, children, asyncOption) {
const asyncOrNoSelectedChunk = children || asyncOption;
// we have specified chunk names
if(chunkNames) {
// map chunks by chunkName for quick access
const allChunksNameMap = allChunks.reduce((map, chunk) => {
if(chunk.name) {
map.set(chunk.name, chunk);
}
return map;
}, new Map());
// Ensure we have a chunk per specified chunk name.
// Reuse existing chunks if possible
return chunkNames.map(chunkName => {
if(allChunksNameMap.has(chunkName)) {
return allChunksNameMap.get(chunkName);
}
// add the filtered chunks to the compilation
return compilation.addChunk(chunkName);
});
}
// we dont have named chunks specified, so we just take all of them
if(asyncOrNoSelectedChunk) {
return allChunks.filter(chunk => !chunk.isInitial());
}
/**
* No chunk name(s) was specified nor is this an async/children commons chunk
*/
throw new Error(`You did not specify any valid target chunk settings.
Take a look at the "name"/"names" or async/children option.`);
}
getAffectedChunks(compilation, allChunks, targetChunk, targetChunks, currentIndex, selectedChunks, asyncOption, children) {
const asyncOrNoSelectedChunk = children || asyncOption;
if(Array.isArray(selectedChunks)) {
return allChunks.filter(chunk => {
const notCommmonChunk = chunk !== targetChunk;
const isSelectedChunk = selectedChunks.indexOf(chunk.name) > -1;
return notCommmonChunk && isSelectedChunk;
});
}
if(asyncOrNoSelectedChunk) {
// nothing to do here
if(!targetChunk.chunks) {
return [];
}
return targetChunk.chunks.filter((chunk) => {
// we can only move modules from this chunk if the "commonChunk" is the only parent
return asyncOption || chunk.parents.length === 1;
});
}
/**
* past this point only entry chunks are allowed to become commonChunks
*/
if(targetChunk.parents.length > 0) {
compilation.errors.push(new Error("CommonsChunkPlugin: While running in normal mode it's not allowed to use a non-entry chunk (" + targetChunk.name + ")"));
return;
}
/**
* If we find a "targetchunk" that is also a normal chunk (meaning it is probably specified as an entry)
* and the current target chunk comes after that and the found chunk has a runtime*
* make that chunk be an 'affected' chunk of the current target chunk.
*
* To understand what that means take a look at the "examples/chunkhash", this basically will
* result in the runtime to be extracted to the current target chunk.
*
* *runtime: the "runtime" is the "webpack"-block you may have seen in the bundles that resolves modules etc.
*/
return allChunks.filter((chunk) => {
const found = targetChunks.indexOf(chunk);
if(found >= currentIndex) return false;
return chunk.hasRuntime();
});
}
createAsyncChunk(compilation, asyncOption, targetChunk) {
const asyncChunk = compilation.addChunk(typeof asyncOption === "string" ? asyncOption : undefined);
asyncChunk.chunkReason = "async commons chunk";
asyncChunk.extraAsync = true;
asyncChunk.addParent(targetChunk);
targetChunk.addChunk(asyncChunk);
return asyncChunk;
}
// If minChunks is a function use that
// otherwhise check if a module is used at least minChunks or 2 or usedChunks.length time
getModuleFilter(minChunks, targetChunk, usedChunksLength) {
if(typeof minChunks === "function") {
return minChunks;
}
const minCount = (minChunks || Math.max(2, usedChunksLength));
const isUsedAtLeastMinTimes = (module, count) => count >= minCount;
return isUsedAtLeastMinTimes;
}
getExtractableModules(minChunks, usedChunks, targetChunk) {
if(minChunks === Infinity) {
return [];
}
// count how many chunks contain a module
const commonModulesToCountMap = usedChunks.reduce((map, chunk) => {
for(let module of chunk.modules) {
const count = map.has(module) ? map.get(module) : 0;
map.set(module, count + 1);
}
return map;
}, new Map());
// filter by minChunks
const moduleFilterCount = this.getModuleFilter(minChunks, targetChunk, usedChunks.length);
// filter by condition
const moduleFilterCondition = (module, chunk) => {
if(!module.chunkCondition) {
return true;
}
return module.chunkCondition(chunk);
};
return Array.from(commonModulesToCountMap).filter(entry => {
const module = entry[0];
const count = entry[1];
// if the module passes both filters, keep it.
return moduleFilterCount(module, count) && moduleFilterCondition(module, targetChunk);
}).map(entry => entry[0]);
}
calculateModulesSize(modules) {
return modules.reduce((totalSize, module) => totalSize + module.size(), 0);
}
extractModulesAndReturnAffectedChunks(reallyUsedModules, usedChunks) {
return reallyUsedModules.reduce((affectedChunksSet, module) => {
for(let chunk of usedChunks) {
// removeChunk returns true if the chunk was contained and succesfully removed
// false if the module did not have a connection to the chunk in question
if(module.removeChunk(chunk)) {
affectedChunksSet.add(chunk);
}
}
return affectedChunksSet;
}, new Set());
}
addExtractedModulesToTargetChunk(chunk, modules) {
for(let module of modules) {
chunk.addModule(module);
module.addChunk(chunk);
}
}
makeTargetChunkParentOfAffectedChunks(usedChunks, commonChunk) {
for(let chunk of usedChunks) {
// set commonChunk as new sole parent
chunk.parents = [commonChunk];
// add chunk to commonChunk
commonChunk.addChunk(chunk);
for(let entrypoint of chunk.entrypoints) {
entrypoint.insertChunk(commonChunk, chunk);
}
}
}
moveExtractedChunkBlocksToTargetChunk(chunks, targetChunk) {
for(let chunk of chunks) {
for(let block of chunk.blocks) {
block.chunks.unshift(targetChunk);
targetChunk.addBlock(block);
}
}
}
extractOriginsOfChunksWithExtractedModules(chunks) {
const origins = [];
for(let chunk of chunks) {
for(let origin of chunk.origins) {
const newOrigin = Object.create(origin);
newOrigin.reasons = (origin.reasons || []).concat("async commons");
origins.push(newOrigin);
}
}
return origins;
}
}
module.exports = CommonsChunkPlugin;

15
web/node_modules/webpack/lib/optimize/DedupePlugin.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class DedupePlugin {
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.warnings.push(new Error("DedupePlugin: This plugin was removed from webpack. Remove it from your configuration."));
});
}
}
module.exports = DedupePlugin;

View File

@@ -0,0 +1,36 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class EnsureChunkConditionsPlugin {
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => {
let changed = false;
chunks.forEach((chunk) => {
chunk.modules.slice().forEach((module) => {
if(!module.chunkCondition) return;
if(!module.chunkCondition(chunk)) {
const usedChunks = module._EnsureChunkConditionsPlugin_usedChunks = (module._EnsureChunkConditionsPlugin_usedChunks || []).concat(chunk);
const newChunks = [];
chunk.parents.forEach((parent) => {
if(usedChunks.indexOf(parent) < 0) {
parent.addModule(module);
newChunks.push(parent);
}
});
module.rewriteChunkInReasons(chunk, newChunks);
chunk.removeModule(module);
changed = true;
}
});
});
if(changed) return true;
});
});
}
}
module.exports = EnsureChunkConditionsPlugin;

View File

@@ -0,0 +1,35 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class FlagIncludedChunksPlugin {
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.plugin("optimize-chunk-ids", (chunks) => {
chunks.forEach((chunkA) => {
chunks.forEach((chunkB) => {
// as we iterate the same iterables twice
// skip if we find ourselves
if(chunkA === chunkB) return;
// instead of swapping A and B just bail
// as we loop twice the current A will be B and B then A
if(chunkA.modules.length < chunkB.modules.length) return;
if(chunkB.modules.length === 0) return;
// is chunkB in chunkA?
for(let i = 0; i < chunkB.modules.length; i++) {
if(chunkA.modules.indexOf(chunkB.modules[i]) < 0) return;
}
chunkA.ids.push(chunkB.id);
});
});
});
});
}
}
module.exports = FlagIncludedChunksPlugin;

View File

@@ -0,0 +1,59 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class LimitChunkCountPlugin {
constructor(options) {
if(options !== undefined && typeof options !== "object" || Array.isArray(options)) {
throw new Error("Argument should be an options object.\nFor more info on options, see https://webpack.js.org/plugins/");
}
this.options = options || {};
}
apply(compiler) {
const options = this.options;
compiler.plugin("compilation", (compilation) => {
compilation.plugin("optimize-chunks-advanced", (chunks) => {
const maxChunks = options.maxChunks;
if(!maxChunks) return;
if(maxChunks < 1) return;
if(chunks.length <= maxChunks) return;
if(chunks.length > maxChunks) {
const sortedExtendedPairCombinations = chunks.reduce((combinations, a, idx) => {
// create combination pairs
for(let i = 0; i < idx; i++) {
const b = chunks[i];
combinations.push([b, a]);
}
return combinations;
}, []).map((pair) => {
// extend combination pairs with size and integrated size
const a = pair[0].size(options);
const b = pair[1].size(options);
const ab = pair[0].integratedSize(pair[1], options);
return [a + b - ab, ab, pair[0], pair[1], a, b];
}).filter((extendedPair) => {
// filter pairs that do not have an integratedSize
// meaning they can NOT be integrated!
return extendedPair[1] !== false;
}).sort((a, b) => { // sadly javascript does an inplace sort here
// sort them by size
const diff = b[0] - a[0];
if(diff !== 0) return diff;
return a[1] - b[1];
});
const pair = sortedExtendedPairCombinations[0];
if(pair && pair[2].integrate(pair[3], "limit")) {
chunks.splice(chunks.indexOf(pair[3]), 1);
return true;
}
}
});
});
}
}
module.exports = LimitChunkCountPlugin;

View File

@@ -0,0 +1,33 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
function getChunkIdentifier(chunk) {
return chunk.modules.map((m) => {
return m.identifier();
}).sort().join(", ");
}
class MergeDuplicateChunksPlugin {
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.plugin("optimize-chunks-basic", (chunks) => {
const map = {};
chunks.slice().forEach((chunk) => {
if(chunk.hasRuntime() || chunk.hasEntryModule()) return;
const ident = getChunkIdentifier(chunk);
if(map[ident]) {
if(map[ident].integrate(chunk, "duplicate"))
chunks.splice(chunks.indexOf(chunk), 1);
return;
}
map[ident] = chunk;
});
});
});
}
}
module.exports = MergeDuplicateChunksPlugin;

View File

@@ -0,0 +1,65 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class MinChunkSizePlugin {
constructor(options) {
if(typeof options !== "object" || Array.isArray(options)) {
throw new Error("Argument should be an options object.\nFor more info on options, see https://webpack.js.org/plugins/");
}
this.options = options;
}
apply(compiler) {
const options = this.options;
const minChunkSize = options.minChunkSize;
compiler.plugin("compilation", (compilation) => {
compilation.plugin("optimize-chunks-advanced", (chunks) => {
const equalOptions = {
chunkOverhead: 1,
entryChunkMultiplicator: 1
};
const sortedSizeFilteredExtendedPairCombinations = chunks.reduce((combinations, a, idx) => {
// create combination pairs
for(let i = 0; i < idx; i++) {
const b = chunks[i];
combinations.push([b, a]);
}
return combinations;
}, []).filter((pair) => {
// check if one of the chunks sizes is smaller than the minChunkSize
const p0SmallerThanMinChunkSize = pair[0].size(equalOptions) < minChunkSize;
const p1SmallerThanMinChunkSize = pair[1].size(equalOptions) < minChunkSize;
return p0SmallerThanMinChunkSize || p1SmallerThanMinChunkSize;
}).map((pair) => {
// extend combination pairs with size and integrated size
const a = pair[0].size(options);
const b = pair[1].size(options);
const ab = pair[0].integratedSize(pair[1], options);
return [a + b - ab, ab, pair[0], pair[1]];
}).filter((pair) => {
// filter pairs that do not have an integratedSize
// meaning they can NOT be integrated!
return pair[1] !== false;
}).sort((a, b) => { // sadly javascript does an inplace sort here
// sort by size
const diff = b[0] - a[0];
if(diff !== 0) return diff;
return a[1] - b[1];
});
if(sortedSizeFilteredExtendedPairCombinations.length === 0) return;
const pair = sortedSizeFilteredExtendedPairCombinations[0];
pair[2].integrate(pair[3], "min-size");
chunks.splice(chunks.indexOf(pair[3]), 1);
return true;
});
});
}
}
module.exports = MinChunkSizePlugin;

View File

@@ -0,0 +1,116 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class OccurrenceOrderPlugin {
constructor(preferEntry) {
if(preferEntry !== undefined && typeof preferEntry !== "boolean") {
throw new Error("Argument should be a boolean.\nFor more info on this plugin, see https://webpack.js.org/plugins/");
}
this.preferEntry = preferEntry;
}
apply(compiler) {
const preferEntry = this.preferEntry;
compiler.plugin("compilation", (compilation) => {
compilation.plugin("optimize-module-order", (modules) => {
function entryChunks(m) {
return m.chunks.map((c) => {
const sum = (c.isInitial() ? 1 : 0) + (c.entryModule === m ? 1 : 0);
return sum;
}).reduce((a, b) => {
return a + b;
}, 0);
}
function occursInEntry(m) {
if(typeof m.__OccurenceOrderPlugin_occursInEntry === "number") return m.__OccurenceOrderPlugin_occursInEntry;
const result = m.reasons.map((r) => {
if(!r.module) return 0;
return entryChunks(r.module);
}).reduce((a, b) => {
return a + b;
}, 0) + entryChunks(m);
return m.__OccurenceOrderPlugin_occursInEntry = result;
}
function occurs(m) {
if(typeof m.__OccurenceOrderPlugin_occurs === "number") return m.__OccurenceOrderPlugin_occurs;
const result = m.reasons.map((r) => {
if(!r.module) return 0;
return r.module.chunks.length;
}).reduce((a, b) => {
return a + b;
}, 0) + m.chunks.length + m.chunks.filter((c) => {
return c.entryModule === m;
}).length;
return m.__OccurenceOrderPlugin_occurs = result;
}
modules.sort((a, b) => {
if(preferEntry) {
const aEntryOccurs = occursInEntry(a);
const bEntryOccurs = occursInEntry(b);
if(aEntryOccurs > bEntryOccurs) return -1;
if(aEntryOccurs < bEntryOccurs) return 1;
}
const aOccurs = occurs(a);
const bOccurs = occurs(b);
if(aOccurs > bOccurs) return -1;
if(aOccurs < bOccurs) return 1;
if(a.identifier() > b.identifier()) return 1;
if(a.identifier() < b.identifier()) return -1;
return 0;
});
// TODO refactor to Map
modules.forEach((m) => {
m.__OccurenceOrderPlugin_occursInEntry = undefined;
m.__OccurenceOrderPlugin_occurs = undefined;
});
});
compilation.plugin("optimize-chunk-order", (chunks) => {
function occursInEntry(c) {
if(typeof c.__OccurenceOrderPlugin_occursInEntry === "number") return c.__OccurenceOrderPlugin_occursInEntry;
const result = c.parents.filter((p) => {
return p.isInitial();
}).length;
return c.__OccurenceOrderPlugin_occursInEntry = result;
}
function occurs(c) {
return c.blocks.length;
}
chunks.forEach((c) => {
c.modules.sort((a, b) => {
if(a.identifier() > b.identifier()) return 1;
if(a.identifier() < b.identifier()) return -1;
return 0;
});
});
chunks.sort((a, b) => {
const aEntryOccurs = occursInEntry(a);
const bEntryOccurs = occursInEntry(b);
if(aEntryOccurs > bEntryOccurs) return -1;
if(aEntryOccurs < bEntryOccurs) return 1;
const aOccurs = occurs(a);
const bOccurs = occurs(b);
if(aOccurs > bOccurs) return -1;
if(aOccurs < bOccurs) return 1;
if(a.modules.length > b.modules.length) return -1;
if(a.modules.length < b.modules.length) return 1;
for(let i = 0; i < a.modules.length; i++) {
if(a.modules[i].identifier() > b.modules[i].identifier()) return -1;
if(a.modules[i].identifier() < b.modules[i].identifier()) return 1;
}
return 0;
});
// TODO refactor to Map
chunks.forEach((c) => {
c.__OccurenceOrderPlugin_occursInEntry = undefined;
});
});
});
}
}
module.exports = OccurrenceOrderPlugin;

View File

@@ -0,0 +1,21 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
class RemoveEmptyChunksPlugin {
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => {
chunks.filter((chunk) => chunk.isEmpty() && !chunk.hasRuntime() && !chunk.hasEntryModule())
.forEach((chunk) => {
chunk.remove("empty");
chunks.splice(chunks.indexOf(chunk), 1);
});
});
});
}
}
module.exports = RemoveEmptyChunksPlugin;

View File

@@ -0,0 +1,91 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
function chunkContainsModule(chunk, module) {
const chunks = module.chunks;
const modules = chunk.modules;
if(chunks.length < modules.length) {
return chunks.indexOf(chunk) >= 0;
} else {
return modules.indexOf(module) >= 0;
}
}
function hasModule(chunk, module, checkedChunks) {
if(chunkContainsModule(chunk, module)) return [chunk];
if(chunk.parents.length === 0) return false;
return allHaveModule(chunk.parents.filter((c) => {
return checkedChunks.indexOf(c) < 0;
}), module, checkedChunks);
}
function allHaveModule(someChunks, module, checkedChunks) {
if(!checkedChunks) checkedChunks = [];
var chunks = [];
for(var i = 0; i < someChunks.length; i++) {
checkedChunks.push(someChunks[i]);
var subChunks = hasModule(someChunks[i], module, checkedChunks);
if(!subChunks) return false;
for(var index = 0; index < subChunks.length; index++) {
var item = subChunks[index];
if(!chunks.length || chunks.indexOf(item) < 0) {
chunks.push(item);
}
}
}
return chunks;
}
function debugIds(chunks) {
var list = [];
for(var i = 0; i < chunks.length; i++) {
var debugId = chunks[i].debugId;
if(typeof debugId !== "number") {
return "no";
}
list.push(debugId);
}
list.sort();
return list.join(",");
}
class RemoveParentModulesPlugin {
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => {
for(var index = 0; index < chunks.length; index++) {
var chunk = chunks[index];
if(chunk.parents.length === 0) continue;
// TODO consider Map when performance has improved https://gist.github.com/sokra/b36098368da7b8f6792fd7c85fca6311
var cache = Object.create(null);
var modules = chunk.modules.slice();
for(var i = 0; i < modules.length; i++) {
var module = modules[i];
var dId = debugIds(module.chunks);
var parentChunksWithModule;
if((dId in cache) && dId !== "no") {
parentChunksWithModule = cache[dId];
} else {
parentChunksWithModule = cache[dId] = allHaveModule(chunk.parents, module);
}
if(parentChunksWithModule) {
module.rewriteChunkInReasons(chunk, parentChunksWithModule);
chunk.removeModule(module);
}
}
}
});
});
}
}
module.exports = RemoveParentModulesPlugin;

236
web/node_modules/webpack/lib/optimize/UglifyJsPlugin.js generated vendored Normal file
View File

@@ -0,0 +1,236 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const SourceMapConsumer = require("source-map").SourceMapConsumer;
const SourceMapSource = require("webpack-sources").SourceMapSource;
const RawSource = require("webpack-sources").RawSource;
const ConcatSource = require("webpack-sources").ConcatSource;
const RequestShortener = require("../RequestShortener");
const ModuleFilenameHelpers = require("../ModuleFilenameHelpers");
const uglify = require("uglify-js");
class UglifyJsPlugin {
constructor(options) {
if(typeof options !== "object" || Array.isArray(options)) options = {};
if(typeof options.compressor !== "undefined") options.compress = options.compressor;
this.options = options;
}
apply(compiler) {
const options = this.options;
options.test = options.test || /\.js($|\?)/i;
const warningsFilter = options.warningsFilter || (() => true);
const requestShortener = new RequestShortener(compiler.context);
compiler.plugin("compilation", (compilation) => {
if(options.sourceMap) {
compilation.plugin("build-module", (module) => {
// to get detailed location info about errors
module.useSourceMap = true;
});
}
compilation.plugin("optimize-chunk-assets", (chunks, callback) => {
const files = [];
chunks.forEach((chunk) => files.push.apply(files, chunk.files));
files.push.apply(files, compilation.additionalChunkAssets);
const filterdFiles = files.filter(ModuleFilenameHelpers.matchObject.bind(undefined, options));
filterdFiles.forEach((file) => {
const oldWarnFunction = uglify.AST_Node.warn_function;
const warnings = [];
let sourceMap;
try {
const asset = compilation.assets[file];
if(asset.__UglifyJsPlugin) {
compilation.assets[file] = asset.__UglifyJsPlugin;
return;
}
let input;
let inputSourceMap;
if(options.sourceMap) {
if(asset.sourceAndMap) {
const sourceAndMap = asset.sourceAndMap();
inputSourceMap = sourceAndMap.map;
input = sourceAndMap.source;
} else {
inputSourceMap = asset.map();
input = asset.source();
}
sourceMap = new SourceMapConsumer(inputSourceMap);
uglify.AST_Node.warn_function = (warning) => { // eslint-disable-line camelcase
const match = /\[.+:([0-9]+),([0-9]+)\]/.exec(warning);
const line = +match[1];
const column = +match[2];
const original = sourceMap.originalPositionFor({
line: line,
column: column
});
if(!original || !original.source || original.source === file) return;
if(!warningsFilter(original.source)) return;
warnings.push(warning.replace(/\[.+:([0-9]+),([0-9]+)\]/, "") +
"[" + requestShortener.shorten(original.source) + ":" + original.line + "," + original.column + "]");
};
} else {
input = asset.source();
uglify.AST_Node.warn_function = (warning) => { // eslint-disable-line camelcase
warnings.push(warning);
};
}
uglify.base54.reset();
let ast = uglify.parse(input, {
filename: file
});
if(options.compress !== false) {
ast.figure_out_scope();
const compress = uglify.Compressor(options.compress || {
warnings: false
}); // eslint-disable-line new-cap
ast = compress.compress(ast);
}
if(options.mangle !== false) {
ast.figure_out_scope(options.mangle || {});
ast.compute_char_frequency(options.mangle || {});
ast.mangle_names(options.mangle || {});
if(options.mangle && options.mangle.props) {
uglify.mangle_properties(ast, options.mangle.props);
}
}
const output = {};
output.comments = Object.prototype.hasOwnProperty.call(options, "comments") ? options.comments : /^\**!|@preserve|@license/;
output.beautify = options.beautify;
for(let k in options.output) {
output[k] = options.output[k];
}
const extractedComments = [];
if(options.extractComments) {
const condition = {};
if(typeof options.extractComments === "string" || options.extractComments instanceof RegExp) {
// extractComments specifies the extract condition and output.comments specifies the preserve condition
condition.preserve = output.comments;
condition.extract = options.extractComments;
} else if(Object.prototype.hasOwnProperty.call(options.extractComments, "condition")) {
// Extract condition is given in extractComments.condition
condition.preserve = output.comments;
condition.extract = options.extractComments.condition;
} else {
// No extract condition is given. Extract comments that match output.comments instead of preserving them
condition.preserve = false;
condition.extract = output.comments;
}
// Ensure that both conditions are functions
["preserve", "extract"].forEach(key => {
switch(typeof condition[key]) {
case "boolean":
var b = condition[key];
condition[key] = () => b;
break;
case "function":
break;
case "string":
if(condition[key] === "all") {
condition[key] = () => true;
break;
}
var regex = new RegExp(condition[key]);
condition[key] = (astNode, comment) => regex.test(comment.value);
break;
default:
regex = condition[key];
condition[key] = (astNode, comment) => regex.test(comment.value);
}
});
// Redefine the comments function to extract and preserve
// comments according to the two conditions
output.comments = (astNode, comment) => {
if(condition.extract(astNode, comment)) {
extractedComments.push(
comment.type === "comment2" ? "/*" + comment.value + "*/" : "//" + comment.value
);
}
return condition.preserve(astNode, comment);
};
}
let map;
if(options.sourceMap) {
map = uglify.SourceMap({ // eslint-disable-line new-cap
file: file,
root: ""
});
output.source_map = map; // eslint-disable-line camelcase
}
const stream = uglify.OutputStream(output); // eslint-disable-line new-cap
ast.print(stream);
if(map) map = map + "";
const stringifiedStream = stream + "";
let outputSource = (map ?
new SourceMapSource(stringifiedStream, file, JSON.parse(map), input, inputSourceMap) :
new RawSource(stringifiedStream));
if(extractedComments.length > 0) {
let commentsFile = options.extractComments.filename || file + ".LICENSE";
if(typeof commentsFile === "function") {
commentsFile = commentsFile(file);
}
// Write extracted comments to commentsFile
const commentsSource = new RawSource(extractedComments.join("\n\n") + "\n");
if(commentsFile in compilation.assets) {
// commentsFile already exists, append new comments...
if(compilation.assets[commentsFile] instanceof ConcatSource) {
compilation.assets[commentsFile].add("\n");
compilation.assets[commentsFile].add(commentsSource);
} else {
compilation.assets[commentsFile] = new ConcatSource(
compilation.assets[commentsFile], "\n", commentsSource
);
}
} else {
compilation.assets[commentsFile] = commentsSource;
}
// Add a banner to the original file
if(options.extractComments.banner !== false) {
let banner = options.extractComments.banner || "For license information please see " + commentsFile;
if(typeof banner === "function") {
banner = banner(commentsFile);
}
if(banner) {
outputSource = new ConcatSource(
"/*! " + banner + " */\n", outputSource
);
}
}
}
asset.__UglifyJsPlugin = compilation.assets[file] = outputSource;
if(warnings.length > 0) {
compilation.warnings.push(new Error(file + " from UglifyJs\n" + warnings.join("\n")));
}
} catch(err) {
if(err.line) {
const original = sourceMap && sourceMap.originalPositionFor({
line: err.line,
column: err.col
});
if(original && original.source) {
compilation.errors.push(new Error(file + " from UglifyJs\n" + err.message + " [" + requestShortener.shorten(original.source) + ":" + original.line + "," + original.column + "][" + file + ":" + err.line + "," + err.col + "]"));
} else {
compilation.errors.push(new Error(file + " from UglifyJs\n" + err.message + " [" + file + ":" + err.line + "," + err.col + "]"));
}
} else if(err.msg) {
compilation.errors.push(new Error(file + " from UglifyJs\n" + err.msg));
} else
compilation.errors.push(new Error(file + " from UglifyJs\n" + err.stack));
} finally {
uglify.AST_Node.warn_function = oldWarnFunction; // eslint-disable-line camelcase
}
});
callback();
});
});
}
}
module.exports = UglifyJsPlugin;