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,50 +64,120 @@ 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
};
obj.isOverSizeLimit = obj.size.number > sizeLimit;
assets.forEach(function(file) { assetsByFile[asset] = obj;
var assetSize = compilation.assets[file].size(); return obj;
var assetsByChunks = compilation.getAssetsByChunks().chunks; }).filter(function(asset) {
return asset.emitted;
for(var chunkKey in assetsByChunks) {
var chunk = assetsByChunks[chunkKey];
actualTotalInitialSize += chunk.size;
}
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) {
warnings.push(new Error("EmittedAssetSizeWarning: NoAsyncChunks: " + var files = [];
"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.") var entrypoint = compilation.entrypoints[ep];
); var hasAsyncChunks = compilation.chunks.filter(function(chunk) {
} return chunk.isAsync();
}).length > 0;
entrypoint.assets = {};
if(warnings.length > 0) { // 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: " +
"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) {
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();
}); });