Skip to content

Commit 9e8c5f8

Browse files
TheLarkInnsokra
authored andcommitted
feat(perfbudgets): Add separate classes for warnings, logic rewrite for plugin
1 parent fc85e63 commit 9e8c5f8

File tree

3 files changed

+105
-82
lines changed

3 files changed

+105
-82
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
function AssetsOverSizeLimitWarning(assetsOverSizeLimit, compilation) {
6+
Error.call(this);
7+
Error.captureStackTrace(this, AssetsOverSizeLimitWarning);
8+
this.name = "AssetsOverSizeLimitWarning";
9+
this.assets = assetsOverSizeLimit;
10+
11+
var assetLists = this.assets.map(function(asset) {
12+
return asset.name;
13+
}).join("\n -");
14+
15+
this.message = "The following assets exceed the recommended size limit.\n" +
16+
"This can impact web performance.\n" +
17+
"Assets: " + assetLists;
18+
}
19+
module.exports = AssetsOverSizeLimitWarning;
20+
21+
AssetsOverSizeLimitWarning.prototype = Object.create(Error.prototype);
22+
AssetsOverSizeLimitWarning.prototype.constructor = AssetsOverSizeLimitWarning;

lib/performance/EmittedAssetSizeLimitPlugin.js

Lines changed: 60 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
*/
55
var path = require('path');
66

7+
var EntrypointsOverSizeLimitWarning = require('./EntrypointsOverSizeLimitWarning');
8+
var AssetsOverSizeLimitWarning = require('./AssetsOverSizeLimitWarning');
9+
710
function EmittedAssetSizeLimitPlugin(performanceOptions) {
811
this.maxAssetSize = performanceOptions.maxAssetSize;
912
this.maxInitialSize = performanceOptions.maxInitialChunkSize;
@@ -25,50 +28,32 @@ function formatSize(size) {
2528
};
2629
}
2730

28-
function doesExceed(sizeLimit, assetSize) {
29-
return sizeLimit < assetSize;
30-
}
31-
32-
function doesExceedEntrypointLimit(initialLimit, actualInitialSize) {
33-
return initialLimit < actualInitialSize;
31+
function doesExceedLimit(limit, actualSize) {
32+
return limit < actualSize;
3433
}
3534

3635
function isAssetJsFile(assetFilename) {
3736
var jsRegex = /\.js($|\?)/i;
38-
39-
return jsRegex.test(assetFilename);
40-
}
41-
42-
function isOverLimit(assetOrEntrypoint) {
4337

38+
return jsRegex.test(assetFilename);
4439
}
45-
// function getJSWarnings(noOfAssets, sizeLimit, assetSize) {
46-
// var warnings = [];
47-
48-
// if(normalizeAndCompare(sizeLimit, assetSize)) {
49-
// if(noOfAssets === 1) {
50-
// warnings.push(new Error("EmmittedAssetSizeWarning: ChunkSizeExceeded" + "This asset exceeds " + sizeLimit + "kB. \nConsider reducing the size for optimal web performance."));
51-
// } else {
52-
// 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"));
53-
// }
54-
// }
55-
56-
// return warnings;
57-
// }
5840

5941
EmittedAssetSizeLimitPlugin.prototype.apply = function(compiler) {
6042
if(!this.hints) {
6143
return;
6244
}
6345

64-
var totalInitialChunkSize = this.maxInitialSize;
46+
var entrypointSizeLimit = this.maxInitialSize;
6547
var sizeLimit = this.maxAssetSize;
6648
var hints = this.hints;
6749

6850
compiler.plugin("after-emit", function(compilation, callback) {
6951
var warnings = [];
7052
var assetsByFile = {};
7153
var assetsByChunkName = {};
54+
var assetsOverSizeLimit = [];
55+
var entrypointsOverSizeLimit = [];
56+
7257
var assets = Object.keys(compilation.assets).map(function(asset) {
7358
var obj = {
7459
name: asset,
@@ -77,8 +62,11 @@ EmittedAssetSizeLimitPlugin.prototype.apply = function(compiler) {
7762
chunkNames: [],
7863
emitted: compilation.assets[asset].emitted
7964
};
80-
81-
obj.isOverSizeLimit = obj.size.number > sizeLimit;
65+
66+
if(obj.size.number > sizeLimit) {
67+
obj.isOverSizeLimit = true;
68+
assetsOverSizeLimit.push(obj);
69+
}
8270

8371
assetsByFile[asset] = obj;
8472
return obj;
@@ -88,13 +76,13 @@ EmittedAssetSizeLimitPlugin.prototype.apply = function(compiler) {
8876

8977
compilation.chunks.forEach(function(chunk) {
9078
chunk.files.forEach(function(asset) {
91-
if (assetsByFile[asset]) {
79+
if(assetsByFile[asset]) {
9280
chunk.ids.forEach(function(id) {
9381
assetsByFile[asset].chunks.push(id);
9482
});
95-
if (chunk.name) {
83+
if(chunk.name) {
9684
assetsByFile[asset].chunkNames.push(chunk.name);
97-
if (assetsByChunkName[chunk.name]) {
85+
if(assetsByChunkName[chunk.name]) {
9886
assetsByChunkName[chunk.name] = [].concat(assetsByChunkName[chunk.name]).concat([asset]);
9987
} else {
10088
assetsByChunkName[chunk.name] = asset;
@@ -104,80 +92,70 @@ EmittedAssetSizeLimitPlugin.prototype.apply = function(compiler) {
10492
});
10593
});
10694

95+
var hasAsyncChunks = compilation.chunks.filter(function(chunk) {
96+
return chunk.isAsync();
97+
}).length > 0;
98+
10799
var entrypoints = Object.keys(compilation.entrypoints).map(function(ep) {
108100
var files = [];
109101
var entrypoint = compilation.entrypoints[ep];
110-
var hasAsyncChunks = compilation.chunks.filter(function(chunk) {
111-
return chunk.isAsync();
112-
}).length > 0;
113-
102+
114103
entrypoint.assets = {};
104+
entrypoint.size = 0;
115105

116106
// TODO: Need to use keys or even better Set for distinct values
117-
entrypoint.chunks.forEach(function(chunk){
118-
chunk.files.forEach(function(file){
107+
entrypoint.chunks.forEach(function(chunk) {
108+
chunk.files.forEach(function(file) {
119109
files.push(file);
120110
});
121111
});
122112

123-
files.forEach(function(file){
124-
console.log(file, entrypoint);
113+
files.forEach(function(file) {
125114
entrypoint.assets[file] = assetsByFile[file];
115+
entrypoint.size = entrypoint.size + assetsByFile[file].size.number;
126116
entrypoint.isOverSizeLimit = false;
127-
if (entrypoint.assets[file].isOverSizeLimit) {
117+
if(entrypoint.assets[file].isOverSizeLimit) {
128118
entrypoint.isOverSizeLimit = true;
129-
}
130-
console.log(assetsByFile[file]);
119+
};
120+
131121
});
122+
123+
if(!entrypoint.isOverSizeLimit) {
124+
entrypoint.isOverSizeLimit = doesExceedLimit(entrypointSizeLimit, entrypoint.size);
125+
}
126+
127+
return entrypoint;
132128
});
133129

134-
if(!hasAsyncChunks) {
135-
warnings.push(new Error("EmittedAssetSizeWarning: NoAsyncChunks: " +
136-
"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."));
137-
}
138-
139-
if (!!warnings.length) {
140-
Array.prototype.push.apply(compilation.warnings, warnings);
141-
}
142-
130+
entrypointsOverSizeLimit = entrypoints.filter(function(ep) {
131+
return ep.isOverSizeLimit;
132+
})
133+
143134
// 1. Individual Chunk: Size < 200kb
144135
// 2. Collective Initial Chunks (Each Set?): Size < 200kb
145136
// 3. No Async Chunks
146137
// if !1, then 2, if !2 return
147138
// if 1, then 2, then 3,
148139

149-
// assets.forEach(function(file) {
150-
// var assetSize = compilation.assets[file].size();
151-
// var assetsByChunks = compilation.getAssetsByChunks().chunks;
152-
153-
// for(var chunkKey in assetsByChunks) {
154-
// var chunk = assetsByChunks[chunkKey];
155-
156-
// actualTotalInitialSize += chunk.size;
157-
// }
158-
159-
// warnings = jsRegex.test(file) && getJSWarnings(noOfAssets, sizeLimit, assetSize);
160-
// });
161-
162-
// if(doesExceedInitialLimit(totalInitialChunkSize, actualTotalInitialSize)) {
163-
// //TODO# Maybe separate warning name
164-
// warnings.push(
165-
// new Error(
166-
// "EmittedAssetSizeWarning: TotalSizeExceeded " +
167-
// "The total initial download cost for these assets are likey to impact web performance. \nConsider keeping the total size of your initial assets < " +
168-
// totalInitialChunkSize +
169-
// "kB")
170-
// );
171-
// }
172-
173-
// if(!hasAsyncChunks) {
174-
// warnings.push(new Error("EmittedAssetSizeWarning: NoAsyncChunks: " +
175-
// "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."));
176-
// }
177-
178-
// if(warnings.length > 0) {
179-
// Array.prototype.push.apply(compilation.warnings, warnings);
180-
// }
140+
if(assetsOverSizeLimit.length) {
141+
warnings.push(new AssetsOverSizeLimitWarning(assetsOverSizeLimit, compilation));
142+
warnings.push(new EntrypointsOverSizeLimitWarning(entrypointsOverSizeLimit, compilation));
143+
} else {
144+
if(entrypointsOverSizeLimit.legnth) {
145+
warnings.push(new EntrypointsOverSizeLimitWarning(entrypointsOverSizeLimit, compilation));
146+
}
147+
}
148+
149+
if(!hasAsyncChunks) {
150+
warnings.push(new Error("EmittedAssetSizeWarning: NoAsyncChunks: " +
151+
"You can limit the size of your bundles by using System.import() or require.ensure to lazy load some parts of your application.\n" +
152+
"For more info visit https://webpack.github.io/docs/code-splitting.html"
153+
));
154+
}
155+
156+
if(!!warnings.length) {
157+
Array.prototype.push.apply(compilation.warnings, warnings);
158+
}
181159

182160
callback();
183161
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
function EntrypointsOverSizeLimitWarning(entrypoints, compilation) {
6+
Error.call(this);
7+
Error.captureStackTrace(this, EntrypointsOverSizeLimitWarning);
8+
this.name = "EntrypointsOverSizeLimitWarning";
9+
this.entrypoints = entrypoints;
10+
11+
var entrypointList = this.entrypoints.map(function(ep) {
12+
return ep.name;
13+
}).join("\n -");
14+
15+
this.message = "The following Entrypoints combined asset size exceeds the recommended limit." +
16+
"This can impact web performance!!\n" +
17+
"Entrypoints: \n" +
18+
entrypointList;
19+
}
20+
module.exports = EntrypointsOverSizeLimitWarning;
21+
22+
EntrypointsOverSizeLimitWarning.prototype = Object.create(Error.prototype);
23+
EntrypointsOverSizeLimitWarning.prototype.constructor = EntrypointsOverSizeLimitWarning;

0 commit comments

Comments
 (0)