| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | function OccurrenceOrderPlugin(preferEntry) { | 
					
						
							| 
									
										
										
										
											2015-05-28 00:46:47 +08:00
										 |  |  | 	if(preferEntry !== undefined && typeof preferEntry !== "boolean") { | 
					
						
							| 
									
										
										
										
											2015-07-21 06:29:53 +08:00
										 |  |  | 		throw new Error("Argument should be a boolean.\nFor more info on this plugin, see https://webpack.github.io/docs/list-of-plugins.html"); | 
					
						
							| 
									
										
										
										
											2015-05-28 00:46:47 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 	this.preferEntry = preferEntry; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = OccurrenceOrderPlugin; | 
					
						
							|  |  |  | OccurrenceOrderPlugin.prototype.apply = function(compiler) { | 
					
						
							|  |  |  | 	var preferEntry = this.preferEntry; | 
					
						
							|  |  |  | 	compiler.plugin("compilation", function(compilation) { | 
					
						
							|  |  |  | 		compilation.plugin("optimize-module-order", function(modules) { | 
					
						
							|  |  |  | 			function entryChunks(m) { | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 				return m.chunks.map(function(c) { | 
					
						
							|  |  |  | 					var sum = (c.isInitial() ? 1 : 0) + (c.entryModule === m ? 1 : 0); | 
					
						
							|  |  |  | 					return sum; | 
					
						
							|  |  |  | 				}).reduce(function(a, b) { | 
					
						
							|  |  |  | 					return a + b; | 
					
						
							|  |  |  | 				}, 0); | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			function occursInEntry(m) { | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				if(typeof m.__OccurenceOrderPlugin_occursInEntry === "number") return m.__OccurenceOrderPlugin_occursInEntry; | 
					
						
							|  |  |  | 				var result = m.reasons.map(function(r) { | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 					if(!r.module) return 0; | 
					
						
							|  |  |  | 					return entryChunks(r.module); | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 				}).reduce(function(a, b) { | 
					
						
							|  |  |  | 					return a + b; | 
					
						
							|  |  |  | 				}, 0) + entryChunks(m); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				return m.__OccurenceOrderPlugin_occursInEntry = result; | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			function occurs(m) { | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				if(typeof m.__OccurenceOrderPlugin_occurs === "number") return m.__OccurenceOrderPlugin_occurs; | 
					
						
							|  |  |  | 				var result = m.reasons.map(function(r) { | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 					if(!r.module) return 0; | 
					
						
							|  |  |  | 					return r.module.chunks.length; | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 				}).reduce(function(a, b) { | 
					
						
							|  |  |  | 					return a + b; | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 				}, 0) + m.chunks.length + m.chunks.filter(function(c) { | 
					
						
							|  |  |  | 					c.entryModule === m; | 
					
						
							|  |  |  | 				}).length; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				return m.__OccurenceOrderPlugin_occurs = result; | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			modules.sort(function(a, b) { | 
					
						
							|  |  |  | 				if(preferEntry) { | 
					
						
							|  |  |  | 					var aEntryOccurs = occursInEntry(a); | 
					
						
							|  |  |  | 					var bEntryOccurs = occursInEntry(b); | 
					
						
							|  |  |  | 					if(aEntryOccurs > bEntryOccurs) return -1; | 
					
						
							|  |  |  | 					if(aEntryOccurs < bEntryOccurs) return 1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				var aOccurs = occurs(a); | 
					
						
							|  |  |  | 				var bOccurs = occurs(b); | 
					
						
							|  |  |  | 				if(aOccurs > bOccurs) return -1; | 
					
						
							|  |  |  | 				if(aOccurs < bOccurs) return 1; | 
					
						
							|  |  |  | 				if(a.identifier() > b.identifier()) return 1; | 
					
						
							|  |  |  | 				if(a.identifier() < b.identifier()) return -1; | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 			// TODO refactor to Map
 | 
					
						
							|  |  |  | 			modules.forEach(function(m) { | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				m.__OccurenceOrderPlugin_occursInEntry = undefined; | 
					
						
							|  |  |  | 				m.__OccurenceOrderPlugin_occurs = undefined; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 		compilation.plugin("optimize-chunk-order", function(chunks) { | 
					
						
							|  |  |  | 			function occursInEntry(c) { | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				if(typeof c.__OccurenceOrderPlugin_occursInEntry === "number") return c.__OccurenceOrderPlugin_occursInEntry; | 
					
						
							|  |  |  | 				var result = c.parents.filter(function(p) { | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 					return p.isInitial(); | 
					
						
							|  |  |  | 				}).length; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				return c.__OccurenceOrderPlugin_occursInEntry = result; | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			function occurs(c) { | 
					
						
							| 
									
										
										
										
											2016-07-13 17:03:14 +08:00
										 |  |  | 				return c.blocks.length; | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			chunks.forEach(function(c) { | 
					
						
							|  |  |  | 				c.modules.sort(function(a, b) { | 
					
						
							|  |  |  | 					if(a.identifier() > b.identifier()) return 1; | 
					
						
							|  |  |  | 					if(a.identifier() < b.identifier()) return -1; | 
					
						
							|  |  |  | 					return 0; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			chunks.sort(function(a, b) { | 
					
						
							|  |  |  | 				var aEntryOccurs = occursInEntry(a); | 
					
						
							|  |  |  | 				var bEntryOccurs = occursInEntry(b); | 
					
						
							|  |  |  | 				if(aEntryOccurs > bEntryOccurs) return -1; | 
					
						
							|  |  |  | 				if(aEntryOccurs < bEntryOccurs) return 1; | 
					
						
							|  |  |  | 				var aOccurs = occurs(a); | 
					
						
							|  |  |  | 				var bOccurs = occurs(b); | 
					
						
							|  |  |  | 				if(aOccurs > bOccurs) return -1; | 
					
						
							|  |  |  | 				if(aOccurs < bOccurs) return 1; | 
					
						
							|  |  |  | 				if(a.modules.length > b.modules.length) return -1; | 
					
						
							|  |  |  | 				if(a.modules.length < b.modules.length) return 1; | 
					
						
							|  |  |  | 				for(var i = 0; i < a.modules.length; i++) { | 
					
						
							|  |  |  | 					if(a.modules[i].identifier() > b.modules[i].identifier()) return -1; | 
					
						
							|  |  |  | 					if(a.modules[i].identifier() < b.modules[i].identifier()) return 1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 			// TODO refactor to Map
 | 
					
						
							|  |  |  | 			chunks.forEach(function(c) { | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 				c.__OccurenceOrderPlugin_occursInEntry = undefined; | 
					
						
							| 
									
										
										
										
											2016-12-05 06:47:19 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-02-25 15:51:40 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2015-07-08 20:39:02 +08:00
										 |  |  | }; |