chore(cleanup): refactored the emittedAssets Warning to be more modular

This commit is contained in:
Sean Larkin 2016-11-05 02:53:53 -05:00 committed by Tobias Koppers
parent 3fe1692e33
commit fc85e639c0
1 changed files with 140 additions and 54 deletions

View File

@ -12,35 +12,51 @@ function EmittedAssetSizeLimitPlugin(performanceOptions) {
module.exports = EmittedAssetSizeLimitPlugin; module.exports = EmittedAssetSizeLimitPlugin;
function normalizeAndCompare(sizeLimit, assetSize) { function formatSize(size) {
// sizeLimit=maxAssetSize is always expressed in kB if(size <= 0) return "0 bytes";
// assetSize is expressed in byte size
sizeLimit *= 1024; var abbreviations = ["bytes", "kB", "MB", "GB"];
var index = Math.floor(Math.log(size) / Math.log(1000));
var numberFormat = +(size / Math.pow(1000, index)).toPrecision(3);
return {
number: numberFormat,
string: numberFormat + " " + abbreviations[index]
};
}
function doesExceed(sizeLimit, assetSize) {
return sizeLimit < assetSize; return sizeLimit < assetSize;
} }
function doesExceedInitialLimit(initialLimit, actualInitialSize) { function doesExceedEntrypointLimit(initialLimit, actualInitialSize) {
initialLimit *= 1024;
return initialLimit < actualInitialSize; return initialLimit < actualInitialSize;
} }
function getJSWarnings(noOfAssets, sizeLimit, assetSize) { function isAssetJsFile(assetFilename) {
var warnings = []; var jsRegex = /\.js($|\?)/i;
if(normalizeAndCompare(sizeLimit, assetSize)) { return jsRegex.test(assetFilename);
if(noOfAssets === 1) {
warnings.push(new Error("EmmittedAssetSizeWarning: ChunkSizeExceeded" + "This asset exceeds " + sizeLimit + "kB. \nConsider reducing the size for optimal web performance."));
} else {
warnings.push(new Error("EmmittedAssetSizeWarning: ChunkSizeExceeded" + "Highlighted chunks are large and are likely to impact web performance. \nConsider keeping total chunks of page < " + sizeLimit + "kB"));
}
}
return warnings;
} }
EmittedAssetSizeLimitPlugin.prototype.apply = function(compiler) { function isOverLimit(assetOrEntrypoint) {
}
// function getJSWarnings(noOfAssets, sizeLimit, assetSize) {
// var warnings = [];
// if(normalizeAndCompare(sizeLimit, assetSize)) {
// if(noOfAssets === 1) {
// warnings.push(new Error("EmmittedAssetSizeWarning: ChunkSizeExceeded" + "This asset exceeds " + sizeLimit + "kB. \nConsider reducing the size for optimal web performance."));
// } else {
// warnings.push(new Error("EmmittedAssetSizeWarning: ChunkSizeExceeded" + "Highlighted chunks are large and are likely to impact web performance. \nConsider keeping total chunks of page < " + sizeLimit + "kB"));
// }
// }
// return warnings;
// }
EmittedAssetSizeLimitPlugin.prototype.apply = function(compiler) {
if(!this.hints) { if(!this.hints) {
return; return;
} }
@ -48,51 +64,121 @@ EmittedAssetSizeLimitPlugin.prototype.apply = function(compiler) {
var totalInitialChunkSize = this.maxInitialSize; var totalInitialChunkSize = this.maxInitialSize;
var sizeLimit = this.maxAssetSize; var sizeLimit = this.maxAssetSize;
var hints = this.hints; var hints = this.hints;
var jsRegex = /\.js($|\?)/i;
compiler.plugin("after-emit", function(compilation, callback) { compiler.plugin("after-emit", function(compilation, callback) {
var assets = Object.keys(compilation.assets);
var noOfAssets = assets.length;
var warnings = []; var warnings = [];
var actualTotalInitialSize = 0; var assetsByFile = {};
var hasAsyncChunks = compilation.chunks.filter(function(chunk) { var assetsByChunkName = {};
return chunk.isAsync(); var assets = Object.keys(compilation.assets).map(function(asset) {
}).length > 0; var obj = {
name: asset,
size: formatSize(compilation.assets[asset].size()),
chunks: [],
chunkNames: [],
emitted: compilation.assets[asset].emitted
};
assets.forEach(function(file) { obj.isOverSizeLimit = obj.size.number > sizeLimit;
var assetSize = compilation.assets[file].size();
var assetsByChunks = compilation.getAssetsByChunks().chunks;
for(var chunkKey in assetsByChunks) { assetsByFile[asset] = obj;
var chunk = assetsByChunks[chunkKey]; return obj;
}).filter(function(asset) {
actualTotalInitialSize += chunk.size; return asset.emitted;
}
warnings = jsRegex.test(file) && getJSWarnings(noOfAssets, sizeLimit, assetSize);
}); });
if(doesExceedInitialLimit(totalInitialChunkSize, actualTotalInitialSize)) { compilation.chunks.forEach(function(chunk) {
//TODO# Maybe separate warning name chunk.files.forEach(function(asset) {
warnings.push( if (assetsByFile[asset]) {
new Error( chunk.ids.forEach(function(id) {
"EmittedAssetSizeWarning: TotalSizeExceeded " + assetsByFile[asset].chunks.push(id);
"The total initial download cost for these assets are likey to impact web performance. \nConsider keeping the total size of your initial assets < " + });
totalInitialChunkSize + if (chunk.name) {
"kB") assetsByFile[asset].chunkNames.push(chunk.name);
); if (assetsByChunkName[chunk.name]) {
} assetsByChunkName[chunk.name] = [].concat(assetsByChunkName[chunk.name]).concat([asset]);
} else {
assetsByChunkName[chunk.name] = asset;
}
}
}
});
});
if (!hasAsyncChunks) { var entrypoints = Object.keys(compilation.entrypoints).map(function(ep) {
var files = [];
var entrypoint = compilation.entrypoints[ep];
var hasAsyncChunks = compilation.chunks.filter(function(chunk) {
return chunk.isAsync();
}).length > 0;
entrypoint.assets = {};
// TODO: Need to use keys or even better Set for distinct values
entrypoint.chunks.forEach(function(chunk){
chunk.files.forEach(function(file){
files.push(file);
});
});
files.forEach(function(file){
console.log(file, entrypoint);
entrypoint.assets[file] = assetsByFile[file];
entrypoint.isOverSizeLimit = false;
if (entrypoint.assets[file].isOverSizeLimit) {
entrypoint.isOverSizeLimit = true;
}
console.log(assetsByFile[file]);
});
});
if(!hasAsyncChunks) {
warnings.push(new Error("EmittedAssetSizeWarning: NoAsyncChunks: " + warnings.push(new Error("EmittedAssetSizeWarning: NoAsyncChunks: " +
"You can limit the size of your bundles by using System.import() or require.ensure to lazy load some parts of your application after the page has loaded.") "You can limit the size of your bundles by using System.import() or require.ensure to lazy load some parts of your application after the page has loaded."));
);
} }
if(warnings.length > 0) { if (!!warnings.length) {
Array.prototype.push.apply(compilation.warnings, warnings); Array.prototype.push.apply(compilation.warnings, warnings);
} }
// 1. Individual Chunk: Size < 200kb
// 2. Collective Initial Chunks (Each Set?): Size < 200kb
// 3. No Async Chunks
// if !1, then 2, if !2 return
// if 1, then 2, then 3,
// assets.forEach(function(file) {
// var assetSize = compilation.assets[file].size();
// var assetsByChunks = compilation.getAssetsByChunks().chunks;
// for(var chunkKey in assetsByChunks) {
// var chunk = assetsByChunks[chunkKey];
// actualTotalInitialSize += chunk.size;
// }
// warnings = jsRegex.test(file) && getJSWarnings(noOfAssets, sizeLimit, assetSize);
// });
// if(doesExceedInitialLimit(totalInitialChunkSize, actualTotalInitialSize)) {
// //TODO# Maybe separate warning name
// warnings.push(
// new Error(
// "EmittedAssetSizeWarning: TotalSizeExceeded " +
// "The total initial download cost for these assets are likey to impact web performance. \nConsider keeping the total size of your initial assets < " +
// totalInitialChunkSize +
// "kB")
// );
// }
// if(!hasAsyncChunks) {
// warnings.push(new Error("EmittedAssetSizeWarning: NoAsyncChunks: " +
// "You can limit the size of your bundles by using System.import() or require.ensure to lazy load some parts of your application after the page has loaded."));
// }
// if(warnings.length > 0) {
// Array.prototype.push.apply(compilation.warnings, warnings);
// }
callback(); callback();
}); });