| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const validateOptions = require("schema-utils");const schema = require("../../schemas/plugins/optimize/OccurrenceOrderModuleIdsPlugin.json");/** @typedef {import("../../declarations/plugins/optimize/OccurrenceOrderModuleIdsPlugin").OccurrenceOrderModuleIdsPluginOptions} OccurrenceOrderModuleIdsPluginOptions */class OccurrenceOrderModuleIdsPlugin {	/**	 * @param {OccurrenceOrderModuleIdsPluginOptions=} options options object	 */	constructor(options = {}) {		validateOptions(schema, options, "Occurrence Order Module Ids Plugin");		this.options = options;	}	apply(compiler) {		const prioritiseInitial = this.options.prioritiseInitial;		compiler.hooks.compilation.tap(			"OccurrenceOrderModuleIdsPlugin",			compilation => {				compilation.hooks.optimizeModuleOrder.tap(					"OccurrenceOrderModuleIdsPlugin",					modules => {						const occursInInitialChunksMap = new Map();						const occursInAllChunksMap = new Map();						const initialChunkChunkMap = new Map();						const entryCountMap = new Map();						for (const m of modules) {							let initial = 0;							let entry = 0;							for (const c of m.chunksIterable) {								if (c.canBeInitial()) initial++;								if (c.entryModule === m) entry++;							}							initialChunkChunkMap.set(m, initial);							entryCountMap.set(m, entry);						}						const countOccursInEntry = (sum, r) => {							if (!r.module) {								return sum;							}							const count = initialChunkChunkMap.get(r.module);							if (!count) {								return sum;							}							return sum + count;						};						const countOccurs = (sum, r) => {							if (!r.module) {								return sum;							}							let factor = 1;							if (typeof r.dependency.getNumberOfIdOccurrences === "function") {								factor = r.dependency.getNumberOfIdOccurrences();							}							if (factor === 0) {								return sum;							}							return sum + factor * r.module.getNumberOfChunks();						};						if (prioritiseInitial) {							for (const m of modules) {								const result =									m.reasons.reduce(countOccursInEntry, 0) +									initialChunkChunkMap.get(m) +									entryCountMap.get(m);								occursInInitialChunksMap.set(m, result);							}						}						const originalOrder = new Map();						let i = 0;						for (const m of modules) {							const result =								m.reasons.reduce(countOccurs, 0) +								m.getNumberOfChunks() +								entryCountMap.get(m);							occursInAllChunksMap.set(m, result);							originalOrder.set(m, i++);						}						modules.sort((a, b) => {							if (prioritiseInitial) {								const aEntryOccurs = occursInInitialChunksMap.get(a);								const bEntryOccurs = occursInInitialChunksMap.get(b);								if (aEntryOccurs > bEntryOccurs) return -1;								if (aEntryOccurs < bEntryOccurs) return 1;							}							const aOccurs = occursInAllChunksMap.get(a);							const bOccurs = occursInAllChunksMap.get(b);							if (aOccurs > bOccurs) return -1;							if (aOccurs < bOccurs) return 1;							const orgA = originalOrder.get(a);							const orgB = originalOrder.get(b);							return orgA - orgB;						});					}				);			}		);	}}module.exports = OccurrenceOrderModuleIdsPlugin;
 |