SizeLimitsPlugin.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Sean Larkin @thelarkinn
  4. */
  5. "use strict";
  6. const EntrypointsOverSizeLimitWarning = require("./EntrypointsOverSizeLimitWarning");
  7. const AssetsOverSizeLimitWarning = require("./AssetsOverSizeLimitWarning");
  8. const NoAsyncChunksWarning = require("./NoAsyncChunksWarning");
  9. module.exports = class SizeLimitsPlugin {
  10. constructor(options) {
  11. this.hints = options.hints;
  12. this.maxAssetSize = options.maxAssetSize;
  13. this.maxEntrypointSize = options.maxEntrypointSize;
  14. this.assetFilter = options.assetFilter;
  15. }
  16. apply(compiler) {
  17. const entrypointSizeLimit = this.maxEntrypointSize;
  18. const assetSizeLimit = this.maxAssetSize;
  19. const hints = this.hints;
  20. const assetFilter = this.assetFilter || (asset => !asset.endsWith(".map"));
  21. compiler.hooks.afterEmit.tap("SizeLimitsPlugin", compilation => {
  22. const warnings = [];
  23. const getEntrypointSize = entrypoint =>
  24. entrypoint.getFiles().reduce((currentSize, file) => {
  25. if (assetFilter(file) && compilation.assets[file]) {
  26. return currentSize + compilation.assets[file].size();
  27. }
  28. return currentSize;
  29. }, 0);
  30. const assetsOverSizeLimit = [];
  31. for (const assetName of Object.keys(compilation.assets)) {
  32. if (!assetFilter(assetName)) {
  33. continue;
  34. }
  35. const asset = compilation.assets[assetName];
  36. const size = asset.size();
  37. if (size > assetSizeLimit) {
  38. assetsOverSizeLimit.push({
  39. name: assetName,
  40. size: size
  41. });
  42. asset.isOverSizeLimit = true;
  43. }
  44. }
  45. const entrypointsOverLimit = [];
  46. for (const pair of compilation.entrypoints) {
  47. const name = pair[0];
  48. const entry = pair[1];
  49. const size = getEntrypointSize(entry);
  50. if (size > entrypointSizeLimit) {
  51. entrypointsOverLimit.push({
  52. name: name,
  53. size: size,
  54. files: entry.getFiles().filter(assetFilter)
  55. });
  56. entry.isOverSizeLimit = true;
  57. }
  58. }
  59. if (hints) {
  60. // 1. Individual Chunk: Size < 250kb
  61. // 2. Collective Initial Chunks [entrypoint] (Each Set?): Size < 250kb
  62. // 3. No Async Chunks
  63. // if !1, then 2, if !2 return
  64. if (assetsOverSizeLimit.length > 0) {
  65. warnings.push(
  66. new AssetsOverSizeLimitWarning(assetsOverSizeLimit, assetSizeLimit)
  67. );
  68. }
  69. if (entrypointsOverLimit.length > 0) {
  70. warnings.push(
  71. new EntrypointsOverSizeLimitWarning(
  72. entrypointsOverLimit,
  73. entrypointSizeLimit
  74. )
  75. );
  76. }
  77. if (warnings.length > 0) {
  78. const hasAsyncChunks =
  79. compilation.chunks.filter(chunk => !chunk.canBeInitial()).length >
  80. 0;
  81. if (!hasAsyncChunks) {
  82. warnings.push(new NoAsyncChunksWarning());
  83. }
  84. if (hints === "error") {
  85. compilation.errors.push(...warnings);
  86. } else {
  87. compilation.warnings.push(...warnings);
  88. }
  89. }
  90. }
  91. });
  92. }
  93. };