| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Sean Larkin @thelarkinn*/"use strict";const { find } = require("../util/SetHelpers");const AssetsOverSizeLimitWarning = require("./AssetsOverSizeLimitWarning");const EntrypointsOverSizeLimitWarning = require("./EntrypointsOverSizeLimitWarning");const NoAsyncChunksWarning = require("./NoAsyncChunksWarning");/** @typedef {import("webpack-sources").Source} Source *//** @typedef {import("../../declarations/WebpackOptions").PerformanceOptions} PerformanceOptions *//** @typedef {import("../ChunkGroup")} ChunkGroup *//** @typedef {import("../Compilation").Asset} Asset *//** @typedef {import("../Compiler")} Compiler *//** @typedef {import("../Entrypoint")} Entrypoint *//** @typedef {import("../WebpackError")} WebpackError *//** * @typedef {object} AssetDetails * @property {string} name * @property {number} size *//** * @typedef {object} EntrypointDetails * @property {string} name * @property {number} size * @property {string[]} files */const isOverSizeLimitSet = new WeakSet();/** * @param {Asset["name"]} name the name * @param {Asset["source"]} source the source * @param {Asset["info"]} info the info * @returns {boolean} result */const excludeSourceMap = (name, source, info) => !info.development;module.exports = class SizeLimitsPlugin {	/**	 * @param {PerformanceOptions} options the plugin options	 */	constructor(options) {		this.hints = options.hints;		this.maxAssetSize = options.maxAssetSize;		this.maxEntrypointSize = options.maxEntrypointSize;		this.assetFilter = options.assetFilter;	}	/**	 * @param {ChunkGroup | Source} thing the resource to test	 * @returns {boolean} true if over the limit	 */	static isOverSizeLimit(thing) {		return isOverSizeLimitSet.has(thing);	}	/**	 * Apply the plugin	 * @param {Compiler} compiler the compiler instance	 * @returns {void}	 */	apply(compiler) {		const entrypointSizeLimit = this.maxEntrypointSize;		const assetSizeLimit = this.maxAssetSize;		const hints = this.hints;		const assetFilter = this.assetFilter || excludeSourceMap;		compiler.hooks.afterEmit.tap("SizeLimitsPlugin", compilation => {			/** @type {WebpackError[]} */			const warnings = [];			/**			 * @param {Entrypoint} entrypoint an entrypoint			 * @returns {number} the size of the entrypoint			 */			const getEntrypointSize = entrypoint => {				let size = 0;				for (const file of entrypoint.getFiles()) {					const asset = compilation.getAsset(file);					if (						asset &&						assetFilter(asset.name, asset.source, asset.info) &&						asset.source					) {						size += asset.info.size || asset.source.size();					}				}				return size;			};			/** @type {AssetDetails[]} */			const assetsOverSizeLimit = [];			for (const { name, source, info } of compilation.getAssets()) {				if (!assetFilter(name, source, info) || !source) {					continue;				}				const size = info.size || source.size();				if (size > /** @type {number} */ (assetSizeLimit)) {					assetsOverSizeLimit.push({						name,						size					});					isOverSizeLimitSet.add(source);				}			}			/**			 * @param {Asset["name"]} name the name			 * @returns {boolean | undefined} result			 */			const fileFilter = name => {				const asset = compilation.getAsset(name);				return asset && assetFilter(asset.name, asset.source, asset.info);			};			/** @type {EntrypointDetails[]} */			const entrypointsOverLimit = [];			for (const [name, entry] of compilation.entrypoints) {				const size = getEntrypointSize(entry);				if (size > /** @type {number} */ (entrypointSizeLimit)) {					entrypointsOverLimit.push({						name: name,						size: size,						files: entry.getFiles().filter(fileFilter)					});					isOverSizeLimitSet.add(entry);				}			}			if (hints) {				// 1. Individual Chunk: Size < 250kb				// 2. Collective Initial Chunks [entrypoint] (Each Set?): Size < 250kb				// 3. No Async Chunks				// if !1, then 2, if !2 return				if (assetsOverSizeLimit.length > 0) {					warnings.push(						new AssetsOverSizeLimitWarning(							assetsOverSizeLimit,							/** @type {number} */ (assetSizeLimit)						)					);				}				if (entrypointsOverLimit.length > 0) {					warnings.push(						new EntrypointsOverSizeLimitWarning(							entrypointsOverLimit,							/** @type {number} */ (entrypointSizeLimit)						)					);				}				if (warnings.length > 0) {					const someAsyncChunk = find(						compilation.chunks,						chunk => !chunk.canBeInitial()					);					if (!someAsyncChunk) {						warnings.push(new NoAsyncChunksWarning());					}					if (hints === "error") {						compilation.errors.push(...warnings);					} else {						compilation.warnings.push(...warnings);					}				}			}		});	}};
 |