source: frontend/node_modules/webpack/lib/performance/SizeLimitsPlugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Sean Larkin @thelarkinn
4*/
5
6"use strict";
7
8const { find } = require("../util/SetHelpers");
9const AssetsOverSizeLimitWarning = require("./AssetsOverSizeLimitWarning");
10const EntrypointsOverSizeLimitWarning = require("./EntrypointsOverSizeLimitWarning");
11const NoAsyncChunksWarning = require("./NoAsyncChunksWarning");
12
13/** @typedef {import("webpack-sources").Source} Source */
14/** @typedef {import("../../declarations/WebpackOptions").PerformanceOptions} PerformanceOptions */
15/** @typedef {import("../ChunkGroup")} ChunkGroup */
16/** @typedef {import("../Compilation").Asset} Asset */
17/** @typedef {import("../Compiler")} Compiler */
18/** @typedef {import("../Entrypoint")} Entrypoint */
19/** @typedef {import("../errors/WebpackError")} WebpackError */
20
21/**
22 * Defines the asset details type used by this module.
23 * @typedef {object} AssetDetails
24 * @property {string} name
25 * @property {number} size
26 */
27
28/**
29 * Defines the entrypoint details type used by this module.
30 * @typedef {object} EntrypointDetails
31 * @property {string} name
32 * @property {number} size
33 * @property {string[]} files
34 */
35
36/** @type {WeakSet<Entrypoint | ChunkGroup | Source>} */
37const isOverSizeLimitSet = new WeakSet();
38
39/** @typedef {(name: Asset["name"], source: Asset["source"], assetInfo: Asset["info"]) => boolean} AssetFilter */
40
41/** @type {AssetFilter} */
42const excludeSourceMap = (name, source, info) => !info.development;
43
44const PLUGIN_NAME = "SizeLimitsPlugin";
45
46module.exports = class SizeLimitsPlugin {
47 /**
48 * Creates an instance of SizeLimitsPlugin.
49 * @param {PerformanceOptions} options the plugin options
50 */
51 constructor(options) {
52 /** @type {PerformanceOptions["hints"]} */
53 this.hints = options.hints;
54 /** @type {number | undefined} */
55 this.maxAssetSize = options.maxAssetSize;
56 /** @type {number | undefined} */
57 this.maxEntrypointSize = options.maxEntrypointSize;
58 /** @type {AssetFilter | undefined} */
59 this.assetFilter = options.assetFilter;
60 }
61
62 /**
63 * Checks whether this size limits plugin is over size limit.
64 * @param {Entrypoint | ChunkGroup | Source} thing the resource to test
65 * @returns {boolean} true if over the limit
66 */
67 static isOverSizeLimit(thing) {
68 return isOverSizeLimitSet.has(thing);
69 }
70
71 /**
72 * Applies the plugin by registering its hooks on the compiler.
73 * @param {Compiler} compiler the compiler instance
74 * @returns {void}
75 */
76 apply(compiler) {
77 const entrypointSizeLimit = this.maxEntrypointSize;
78 const assetSizeLimit = this.maxAssetSize;
79 const hints = this.hints;
80 const assetFilter = this.assetFilter || excludeSourceMap;
81
82 compiler.hooks.afterEmit.tap(PLUGIN_NAME, (compilation) => {
83 /** @type {WebpackError[]} */
84 const warnings = [];
85
86 /**
87 * Gets entrypoint size.
88 * @param {Entrypoint} entrypoint an entrypoint
89 * @returns {number} the size of the entrypoint
90 */
91 const getEntrypointSize = (entrypoint) => {
92 let size = 0;
93 for (const file of entrypoint.getFiles()) {
94 const asset = compilation.getAsset(file);
95 if (
96 asset &&
97 assetFilter(asset.name, asset.source, asset.info) &&
98 asset.source
99 ) {
100 size += asset.info.size || asset.source.size();
101 }
102 }
103 return size;
104 };
105
106 /** @type {AssetDetails[]} */
107 const assetsOverSizeLimit = [];
108 for (const { name, source, info } of compilation.getAssets()) {
109 if (!assetFilter(name, source, info) || !source) {
110 continue;
111 }
112
113 const size = info.size || source.size();
114 if (size > /** @type {number} */ (assetSizeLimit)) {
115 assetsOverSizeLimit.push({
116 name,
117 size
118 });
119 isOverSizeLimitSet.add(source);
120 }
121 }
122
123 /**
124 * Returns result.
125 * @param {Asset["name"]} name the name
126 * @returns {boolean | undefined} result
127 */
128 const fileFilter = (name) => {
129 const asset = compilation.getAsset(name);
130 return asset && assetFilter(asset.name, asset.source, asset.info);
131 };
132
133 /** @type {EntrypointDetails[]} */
134 const entrypointsOverLimit = [];
135 for (const [name, entry] of compilation.entrypoints) {
136 const size = getEntrypointSize(entry);
137
138 if (size > /** @type {number} */ (entrypointSizeLimit)) {
139 entrypointsOverLimit.push({
140 name,
141 size,
142 files: entry.getFiles().filter(fileFilter)
143 });
144 isOverSizeLimitSet.add(entry);
145 }
146 }
147
148 if (hints) {
149 // 1. Individual Chunk: Size < 250kb
150 // 2. Collective Initial Chunks [entrypoint] (Each Set?): Size < 250kb
151 // 3. No Async Chunks
152 // if !1, then 2, if !2 return
153 if (assetsOverSizeLimit.length > 0) {
154 warnings.push(
155 new AssetsOverSizeLimitWarning(
156 assetsOverSizeLimit,
157 /** @type {number} */ (assetSizeLimit)
158 )
159 );
160 }
161 if (entrypointsOverLimit.length > 0) {
162 warnings.push(
163 new EntrypointsOverSizeLimitWarning(
164 entrypointsOverLimit,
165 /** @type {number} */ (entrypointSizeLimit)
166 )
167 );
168 }
169
170 if (warnings.length > 0) {
171 const someAsyncChunk = find(
172 compilation.chunks,
173 (chunk) => !chunk.canBeInitial()
174 );
175
176 if (!someAsyncChunk) {
177 warnings.push(new NoAsyncChunksWarning());
178 }
179
180 if (hints === "error") {
181 compilation.errors.push(...warnings);
182 } else {
183 compilation.warnings.push(...warnings);
184 }
185 }
186 }
187 });
188 }
189};
Note: See TracBrowser for help on using the repository browser.