| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2015-04-04 08:09:49 +08:00
										 |  |  | var path = require("path"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | function RecordIdsPlugin() {} | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | module.exports = RecordIdsPlugin; | 
					
						
							| 
									
										
										
										
											2015-04-04 08:09:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | function makeRelative(compiler, identifier) { | 
					
						
							|  |  |  | 	var context = compiler.context; | 
					
						
							|  |  |  | 	return identifier.split("|").map(function(str) { | 
					
						
							| 
									
										
										
										
											2016-06-05 01:54:01 +08:00
										 |  |  | 		return str.split("!").map(function(str) { | 
					
						
							| 
									
										
										
										
											2015-10-29 02:45:39 +08:00
										 |  |  | 			return path.relative(context, str); | 
					
						
							|  |  |  | 		}).join("!"); | 
					
						
							| 
									
										
										
										
											2015-04-04 08:09:49 +08:00
										 |  |  | 	}).join("|"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | RecordIdsPlugin.prototype.apply = function(compiler) { | 
					
						
							|  |  |  | 	compiler.plugin("compilation", function(compilation) { | 
					
						
							|  |  |  | 		compilation.plugin("record-modules", function(modules, records) { | 
					
						
							|  |  |  | 			if(!records.modules) records.modules = {}; | 
					
						
							|  |  |  | 			if(!records.modules.byIdentifier) records.modules.byIdentifier = {}; | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 			if(!records.modules.usedIds) records.modules.usedIds = {}; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			modules.forEach(function(module) { | 
					
						
							| 
									
										
										
										
											2016-09-29 23:01:26 +08:00
										 |  |  | 				if(!module.portableId) module.portableId = makeRelative(compiler, module.identifier()); | 
					
						
							|  |  |  | 				var identifier = module.portableId; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 				records.modules.byIdentifier[identifier] = module.id; | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 				records.modules.usedIds[module.id] = module.id; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		compilation.plugin("revive-modules", function(modules, records) { | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 			if(!records.modules) return; | 
					
						
							|  |  |  | 			if(records.modules.byIdentifier) { | 
					
						
							|  |  |  | 				var usedIds = {}; | 
					
						
							|  |  |  | 				modules.forEach(function(module) { | 
					
						
							|  |  |  | 					if(module.id !== null) return; | 
					
						
							| 
									
										
										
										
											2016-09-29 23:01:26 +08:00
										 |  |  | 					if(!module.portableId) module.portableId = makeRelative(compiler, module.identifier()); | 
					
						
							|  |  |  | 					var identifier = module.portableId; | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 					var id = records.modules.byIdentifier[identifier]; | 
					
						
							|  |  |  | 					if(id === undefined) return; | 
					
						
							|  |  |  | 					if(usedIds[id]) return; | 
					
						
							|  |  |  | 					usedIds[id] = true; | 
					
						
							|  |  |  | 					module.id = id; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			compilation.usedModuleIds = records.modules.usedIds; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-21 14:35:34 +08:00
										 |  |  | 		function getDepBlockIdent(chunk, block) { | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			var ident = []; | 
					
						
							| 
									
										
										
										
											2015-04-21 14:35:34 +08:00
										 |  |  | 			if(block.chunks.length > 1) | 
					
						
							|  |  |  | 				ident.push(block.chunks.indexOf(chunk)); | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			while(block.parent) { | 
					
						
							|  |  |  | 				var p = block.parent; | 
					
						
							|  |  |  | 				var idx = p.blocks.indexOf(block); | 
					
						
							|  |  |  | 				var l = p.blocks.length - 1; | 
					
						
							|  |  |  | 				ident.unshift(idx + "/" + l); | 
					
						
							|  |  |  | 				block = block.parent; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if(!block.identifier) return null; | 
					
						
							| 
									
										
										
										
											2015-04-04 08:09:49 +08:00
										 |  |  | 			ident.unshift(makeRelative(compiler, block.identifier())); | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			return ident.join(":"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		compilation.plugin("record-chunks", function(chunks, records) { | 
					
						
							|  |  |  | 			records.nextFreeChunkId = compilation.nextFreeChunkId; | 
					
						
							|  |  |  | 			if(!records.chunks) records.chunks = {}; | 
					
						
							|  |  |  | 			if(!records.chunks.byName) records.chunks.byName = {}; | 
					
						
							|  |  |  | 			if(!records.chunks.byBlocks) records.chunks.byBlocks = {}; | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 			records.chunks.usedIds = {}; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			chunks.forEach(function(chunk) { | 
					
						
							|  |  |  | 				var name = chunk.name; | 
					
						
							| 
									
										
										
										
											2015-04-21 14:35:34 +08:00
										 |  |  | 				var blockIdents = chunk.blocks.map(getDepBlockIdent.bind(null, chunk)).filter(Boolean); | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 				if(name) records.chunks.byName[name] = chunk.id; | 
					
						
							|  |  |  | 				blockIdents.forEach(function(blockIdent) { | 
					
						
							|  |  |  | 					records.chunks.byBlocks[blockIdent] = chunk.id; | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 				records.chunks.usedIds[chunk.id] = chunk.id; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		compilation.plugin("revive-chunks", function(chunks, records) { | 
					
						
							|  |  |  | 			if(!records.chunks) return; | 
					
						
							| 
									
										
										
										
											2014-02-11 20:27:41 +08:00
										 |  |  | 			var usedIds = {}; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 			if(records.chunks.byName) { | 
					
						
							|  |  |  | 				chunks.forEach(function(chunk) { | 
					
						
							|  |  |  | 					if(chunk.id !== null) return; | 
					
						
							|  |  |  | 					if(!chunk.name) return; | 
					
						
							|  |  |  | 					var id = records.chunks.byName[chunk.name]; | 
					
						
							| 
									
										
										
										
											2013-06-19 17:53:03 +08:00
										 |  |  | 					if(id === undefined) return; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 					if(usedIds[id]) return; | 
					
						
							|  |  |  | 					usedIds[id] = true; | 
					
						
							|  |  |  | 					chunk.id = id; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if(records.chunks.byBlocks) { | 
					
						
							|  |  |  | 				var argumentedChunks = chunks.filter(function(chunk) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 					return chunk.id === null; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 				}).map(function(chunk) { | 
					
						
							|  |  |  | 					return { | 
					
						
							|  |  |  | 						chunk: chunk, | 
					
						
							| 
									
										
										
										
											2015-04-21 14:35:34 +08:00
										 |  |  | 						blockIdents: chunk.blocks.map(getDepBlockIdent.bind(null, chunk)).filter(Boolean) | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 					}; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 				}).filter(function(arg) { | 
					
						
							|  |  |  | 					return arg.blockIdents.length > 0; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				var blockIdentsCount = {}; | 
					
						
							|  |  |  | 				argumentedChunks.forEach(function(arg, idx) { | 
					
						
							|  |  |  | 					arg.blockIdents.forEach(function(blockIdent) { | 
					
						
							| 
									
										
										
										
											2015-04-21 14:35:34 +08:00
										 |  |  | 						var id = records.chunks.byBlocks[blockIdent]; | 
					
						
							|  |  |  | 						if(typeof id !== "number") return; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 						var accessor = id + ":" + idx; | 
					
						
							|  |  |  | 						blockIdentsCount[accessor] = (blockIdentsCount[accessor] || 0) + 1; | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				blockIdentsCount = Object.keys(blockIdentsCount).map(function(accessor) { | 
					
						
							|  |  |  | 					return [blockIdentsCount[accessor]].concat(accessor.split(":").map(Number)); | 
					
						
							|  |  |  | 				}).sort(function(a, b) { | 
					
						
							|  |  |  | 					return b[0] - a[0]; | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 				blockIdentsCount.forEach(function(arg) { | 
					
						
							|  |  |  | 					var id = arg[1]; | 
					
						
							|  |  |  | 					if(usedIds[id]) return; | 
					
						
							|  |  |  | 					var idx = arg[2]; | 
					
						
							|  |  |  | 					var chunk = argumentedChunks[idx].chunk; | 
					
						
							|  |  |  | 					if(chunk.id !== null) return; | 
					
						
							|  |  |  | 					usedIds[id] = true; | 
					
						
							|  |  |  | 					chunk.id = id; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-07-18 06:41:26 +08:00
										 |  |  | 			compilation.usedChunkIds = records.chunks.usedIds; | 
					
						
							| 
									
										
										
										
											2013-05-31 18:22:40 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2015-04-04 08:09:49 +08:00
										 |  |  | }; |