| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-01-09 02:11:26 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | const Template = require("./Template"); | 
					
						
							|  |  |  | const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency"); | 
					
						
							|  |  |  | const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency"); | 
					
						
							|  |  |  | const RawSource = require("webpack-sources").RawSource; | 
					
						
							|  |  |  | const ConstDependency = require("./dependencies/ConstDependency"); | 
					
						
							|  |  |  | const NullFactory = require("./NullFactory"); | 
					
						
							| 
									
										
										
										
											2017-01-09 02:11:26 +08:00
										 |  |  | const ParserHelpers = require("./ParserHelpers"); | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | const createHash = require("./util/createHash"); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:41 +08:00
										 |  |  | const SyncBailHook = require("tapable").SyncBailHook; | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | module.exports = class HotModuleReplacementPlugin { | 
					
						
							|  |  |  | 	constructor(options) { | 
					
						
							|  |  |  | 		this.options = options || {}; | 
					
						
							|  |  |  | 		this.multiStep = this.options.multiStep; | 
					
						
							|  |  |  | 		this.fullBuildTimeout = this.options.fullBuildTimeout || 200; | 
					
						
							|  |  |  | 		this.requestTimeout = this.options.requestTimeout || 10000; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	apply(compiler) { | 
					
						
							|  |  |  | 		const multiStep = this.multiStep; | 
					
						
							|  |  |  | 		const fullBuildTimeout = this.fullBuildTimeout; | 
					
						
							|  |  |  | 		const requestTimeout = this.requestTimeout; | 
					
						
							|  |  |  | 		const hotUpdateChunkFilename = compiler.options.output.hotUpdateChunkFilename; | 
					
						
							|  |  |  | 		const hotUpdateMainFilename = compiler.options.output.hotUpdateMainFilename; | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 		compiler.hooks.additionalPass.tapAsync("HotModuleReplacementPlugin", (callback) => { | 
					
						
							| 
									
										
										
										
											2017-11-23 18:09:59 +08:00
										 |  |  | 			if(multiStep) | 
					
						
							|  |  |  | 				return setTimeout(callback, fullBuildTimeout); | 
					
						
							|  |  |  | 			return callback(); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("HotModuleReplacementPlugin", (compilation, { | 
					
						
							|  |  |  | 			normalModuleFactory | 
					
						
							|  |  |  | 		}) => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 			const hotUpdateChunkTemplate = compilation.hotUpdateChunkTemplate; | 
					
						
							|  |  |  | 			if(!hotUpdateChunkTemplate) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			compilation.dependencyFactories.set(ConstDependency, new NullFactory()); | 
					
						
							|  |  |  | 			compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			compilation.dependencyFactories.set(ModuleHotAcceptDependency, normalModuleFactory); | 
					
						
							|  |  |  | 			compilation.dependencyTemplates.set(ModuleHotAcceptDependency, new ModuleHotAcceptDependency.Template()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			compilation.dependencyFactories.set(ModuleHotDeclineDependency, normalModuleFactory); | 
					
						
							|  |  |  | 			compilation.dependencyTemplates.set(ModuleHotDeclineDependency, new ModuleHotDeclineDependency.Template()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 			compilation.hooks.record.tap("HotModuleReplacementPlugin", (compilation, records) => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				if(records.hash === compilation.hash) return; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				records.hash = compilation.hash; | 
					
						
							|  |  |  | 				records.moduleHashs = {}; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				compilation.modules.forEach(module => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					const identifier = module.identifier(); | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | 					const hash = createHash(compilation.outputOptions.hashFunction); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					module.updateHash(hash); | 
					
						
							|  |  |  | 					records.moduleHashs[identifier] = hash.digest("hex"); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				records.chunkHashs = {}; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				compilation.chunks.forEach(chunk => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					records.chunkHashs[chunk.id] = chunk.hash; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				records.chunkModuleIds = {}; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				compilation.chunks.forEach(chunk => { | 
					
						
							| 
									
										
										
										
											2018-01-24 03:08:32 +08:00
										 |  |  | 					records.chunkModuleIds[chunk.id] = Array.from(chunk.modulesIterable, m => m.id); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			let initialPass = false; | 
					
						
							|  |  |  | 			let recompilation = false; | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 			compilation.hooks.afterHash.tap("HotModuleReplacementPlugin", () => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				let records = compilation.records; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				if(!records) { | 
					
						
							|  |  |  | 					initialPass = true; | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if(!records.hash) | 
					
						
							|  |  |  | 					initialPass = true; | 
					
						
							|  |  |  | 				const preHash = records.preHash || "x"; | 
					
						
							|  |  |  | 				const prepreHash = records.prepreHash || "x"; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				if(preHash === compilation.hash) { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					recompilation = true; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					compilation.modifyHash(prepreHash); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				records.prepreHash = records.hash || "x"; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				records.preHash = compilation.hash; | 
					
						
							|  |  |  | 				compilation.modifyHash(records.prepreHash); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 			compilation.hooks.shouldGenerateChunkAssets.tap("HotModuleReplacementPlugin", () => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				if(multiStep && !recompilation && !initialPass) | 
					
						
							|  |  |  | 					return false; | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 			compilation.hooks.needAdditionalPass.tap("HotModuleReplacementPlugin", () => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				if(multiStep && !recompilation && !initialPass) | 
					
						
							|  |  |  | 					return true; | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 			compilation.hooks.additionalChunkAssets.tap("HotModuleReplacementPlugin", () => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				const records = compilation.records; | 
					
						
							|  |  |  | 				if(records.hash === compilation.hash) return; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				if(!records.moduleHashs || !records.chunkHashs || !records.chunkModuleIds) return; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				compilation.modules.forEach(module => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					const identifier = module.identifier(); | 
					
						
							| 
									
										
										
										
											2017-11-23 17:59:29 +08:00
										 |  |  | 					let hash = createHash(compilation.outputOptions.hashFunction); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					module.updateHash(hash); | 
					
						
							|  |  |  | 					hash = hash.digest("hex"); | 
					
						
							|  |  |  | 					module.hotUpdate = records.moduleHashs[identifier] !== hash; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 				const hotUpdateMainContent = { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					h: compilation.hash, | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					c: {}, | 
					
						
							|  |  |  | 				}; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				Object.keys(records.chunkHashs).forEach(chunkId => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					chunkId = isNaN(+chunkId) ? chunkId : +chunkId; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					const currentChunk = compilation.chunks.find(chunk => chunk.id === chunkId); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					if(currentChunk) { | 
					
						
							|  |  |  | 						const newModules = currentChunk.getModules().filter(module => module.hotUpdate); | 
					
						
							| 
									
										
										
										
											2018-01-04 19:48:09 +08:00
										 |  |  | 						const allModules = new Set(); | 
					
						
							|  |  |  | 						for(const module of currentChunk.modulesIterable) { | 
					
						
							|  |  |  | 							allModules.add(module.id); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						const removedModules = records.chunkModuleIds[chunkId].filter(id => !allModules.has(id)); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 						if(newModules.length > 0 || removedModules.length > 0) { | 
					
						
							| 
									
										
										
										
											2017-11-11 18:27:02 +08:00
										 |  |  | 							const source = hotUpdateChunkTemplate.render(chunkId, newModules, removedModules, compilation.hash, compilation.moduleTemplates.javascript, compilation.dependencyTemplates); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 							const filename = compilation.getPath(hotUpdateChunkFilename, { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 								hash: records.hash, | 
					
						
							|  |  |  | 								chunk: currentChunk | 
					
						
							|  |  |  | 							}); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 							compilation.additionalChunkAssets.push(filename); | 
					
						
							|  |  |  | 							compilation.assets[filename] = source; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 							hotUpdateMainContent.c[chunkId] = true; | 
					
						
							|  |  |  | 							currentChunk.files.push(filename); | 
					
						
							| 
									
										
										
										
											2018-01-22 22:23:52 +08:00
										 |  |  | 							compilation.hooks.chunkAsset.call("HotModuleReplacementPlugin", currentChunk, filename); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						hotUpdateMainContent.c[chunkId] = false; | 
					
						
							| 
									
										
										
										
											2013-07-01 19:59:02 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				}, compilation); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				const source = new RawSource(JSON.stringify(hotUpdateMainContent)); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				const filename = compilation.getPath(hotUpdateMainFilename, { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					hash: records.hash | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				compilation.assets[filename] = source; | 
					
						
							| 
									
										
										
										
											2014-08-22 19:51:24 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 			const mainTemplate = compilation.mainTemplate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:39 +08:00
										 |  |  | 			mainTemplate.hooks.hash.tap("HotModuleReplacementPlugin", hash => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				hash.update("HotMainTemplateDecorator"); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:39 +08:00
										 |  |  | 			mainTemplate.hooks.moduleRequire.tap("HotModuleReplacementPlugin", (_, chunk, hash, varModuleId) => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				return `hotCreateRequire(${varModuleId})`; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-08-25 15:50:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:39 +08:00
										 |  |  | 			mainTemplate.hooks.requireExtensions.tap("HotModuleReplacementPlugin", source => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				const buf = [source]; | 
					
						
							|  |  |  | 				buf.push(""); | 
					
						
							|  |  |  | 				buf.push("// __webpack_hash__"); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				buf.push(mainTemplate.requireFn + ".h = function() { return hotCurrentHash; };"); | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 				return Template.asString(buf); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 			const needChunkLoadingCode = chunk => { | 
					
						
							|  |  |  | 				for(const chunkGroup of chunk.groupsIterable) { | 
					
						
							|  |  |  | 					if(chunkGroup.chunks.length > 1) return true; | 
					
						
							|  |  |  | 					if(chunkGroup.getNumberOfChildren() > 0) return true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:39 +08:00
										 |  |  | 			mainTemplate.hooks.bootstrap.tap("HotModuleReplacementPlugin", (source, chunk, hash) => { | 
					
						
							| 
									
										
										
										
											2017-11-29 01:43:01 +08:00
										 |  |  | 				source = mainTemplate.hooks.hotBootstrap.call(source, chunk, hash); | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 				return Template.asString([ | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					source, | 
					
						
							|  |  |  | 					"", | 
					
						
							|  |  |  | 					hotInitCode | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					.replace(/\$require\$/g, mainTemplate.requireFn) | 
					
						
							| 
									
										
										
										
											2017-07-02 00:55:45 +08:00
										 |  |  | 					.replace(/\$hash\$/g, JSON.stringify(hash)) | 
					
						
							|  |  |  | 					.replace(/\$requestTimeout\$/g, requestTimeout) | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 					.replace(/\/\*foreachInstalledChunks\*\//g, needChunkLoadingCode(chunk) ? "for(var chunkId in installedChunks)" : `var chunkId = ${JSON.stringify(chunk.id)};`) | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				]); | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-04-20 03:35:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:39 +08:00
										 |  |  | 			mainTemplate.hooks.globalHash.tap("HotModuleReplacementPlugin", () => true); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:39 +08:00
										 |  |  | 			mainTemplate.hooks.currentHash.tap("HotModuleReplacementPlugin", (_, length) => { | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				if(isFinite(length)) | 
					
						
							|  |  |  | 					return `hotCurrentHash.substr(0, ${length})`; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					return "hotCurrentHash"; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 22:16:39 +08:00
										 |  |  | 			mainTemplate.hooks.moduleObj.tap("HotModuleReplacementPlugin", (source, chunk, hash, varModuleId) => { | 
					
						
							| 
									
										
										
										
											2017-12-07 16:42:33 +08:00
										 |  |  | 				return Template.asString([ | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					`${source},`, | 
					
						
							|  |  |  | 					`hot: hotCreateModule(${varModuleId}),`, | 
					
						
							|  |  |  | 					"parents: (hotCurrentParentsTemp = hotCurrentParents, hotCurrentParents = [], hotCurrentParentsTemp),", | 
					
						
							|  |  |  | 					"children: []" | 
					
						
							|  |  |  | 				]); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 17:22:27 +08:00
										 |  |  | 			const handler = (parser, parserOptions) => { | 
					
						
							| 
									
										
										
										
											2017-12-19 21:35:30 +08:00
										 |  |  | 				parser.hooks.expression.for("__webpack_hash__").tap("HotModuleReplacementPlugin", ParserHelpers.toConstantDependencyWithWebpackRequire(parser, "__webpack_require__.h()")); | 
					
						
							|  |  |  | 				parser.hooks.evaluateTypeof.for("__webpack_hash__").tap("HotModuleReplacementPlugin", ParserHelpers.evaluateToString("string")); | 
					
						
							|  |  |  | 				parser.hooks.evaluateIdentifier.for("module.hot").tap("HotModuleReplacementPlugin", expr => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					return ParserHelpers.evaluateToIdentifier("module.hot", !!parser.state.compilation.hotUpdateChunkTemplate)(expr); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:41 +08:00
										 |  |  | 				// TODO webpack 5: refactor this, no custom hooks
 | 
					
						
							|  |  |  | 				if(!parser.hooks.hotAcceptCallback) | 
					
						
							|  |  |  | 					parser.hooks.hotAcceptCallback = new SyncBailHook(["expression", "requests"]); | 
					
						
							|  |  |  | 				if(!parser.hooks.hotAcceptWithoutCallback) | 
					
						
							|  |  |  | 					parser.hooks.hotAcceptWithoutCallback = new SyncBailHook(["expression", "requests"]); | 
					
						
							| 
									
										
										
										
											2017-12-19 21:35:30 +08:00
										 |  |  | 				parser.hooks.call.for("module.hot.accept").tap("HotModuleReplacementPlugin", expr => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					if(!parser.state.compilation.hotUpdateChunkTemplate) return false; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					if(expr.arguments.length >= 1) { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 						const arg = parser.evaluateExpression(expr.arguments[0]); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 						let params = []; | 
					
						
							|  |  |  | 						let requests = []; | 
					
						
							|  |  |  | 						if(arg.isString()) { | 
					
						
							|  |  |  | 							params = [arg]; | 
					
						
							|  |  |  | 						} else if(arg.isArray()) { | 
					
						
							|  |  |  | 							params = arg.items.filter(param => param.isString()); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if(params.length > 0) { | 
					
						
							|  |  |  | 							params.forEach((param, idx) => { | 
					
						
							|  |  |  | 								const request = param.string; | 
					
						
							|  |  |  | 								const dep = new ModuleHotAcceptDependency(request, param.range); | 
					
						
							|  |  |  | 								dep.optional = true; | 
					
						
							|  |  |  | 								dep.loc = Object.create(expr.loc); | 
					
						
							|  |  |  | 								dep.loc.index = idx; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 								parser.state.module.addDependency(dep); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 								requests.push(request); | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 							if(expr.arguments.length > 1) | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:41 +08:00
										 |  |  | 								parser.hooks.hotAcceptCallback.call(expr.arguments[1], requests); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 							else | 
					
						
							| 
									
										
										
										
											2017-11-27 22:27:41 +08:00
										 |  |  | 								parser.hooks.hotAcceptWithoutCallback.call(expr, requests); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-12-19 21:35:30 +08:00
										 |  |  | 				parser.hooks.call.for("module.hot.decline").tap("HotModuleReplacementPlugin", expr => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 					if(!parser.state.compilation.hotUpdateChunkTemplate) return false; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 					if(expr.arguments.length === 1) { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 						const arg = parser.evaluateExpression(expr.arguments[0]); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 						let params = []; | 
					
						
							|  |  |  | 						if(arg.isString()) { | 
					
						
							|  |  |  | 							params = [arg]; | 
					
						
							|  |  |  | 						} else if(arg.isArray()) { | 
					
						
							|  |  |  | 							params = arg.items.filter(param => param.isString()); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						params.forEach((param, idx) => { | 
					
						
							|  |  |  | 							const dep = new ModuleHotDeclineDependency(param.string, param.range); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 							dep.optional = true; | 
					
						
							|  |  |  | 							dep.loc = Object.create(expr.loc); | 
					
						
							|  |  |  | 							dep.loc.index = idx; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 							parser.state.module.addDependency(dep); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 						}); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2017-12-19 21:35:30 +08:00
										 |  |  | 				parser.hooks.expression.for("module.hot").tap("HotModuleReplacementPlugin", ParserHelpers.skipTraversal); | 
					
						
							| 
									
										
										
										
											2017-12-14 17:22:27 +08:00
										 |  |  | 			}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// TODO add HMR support for javascript/esm
 | 
					
						
							|  |  |  | 			normalModuleFactory.hooks.parser.for("javascript/auto").tap("HotModuleReplacementPlugin", handler); | 
					
						
							|  |  |  | 			normalModuleFactory.hooks.parser.for("javascript/dynamic").tap("HotModuleReplacementPlugin", handler); | 
					
						
							| 
									
										
										
										
											2018-01-03 19:27:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			compilation.hooks.normalModuleLoader.tap("HotModuleReplacementPlugin", context => { | 
					
						
							|  |  |  | 				context.hot = true; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | const hotInitCode = Template.getFunctionContent(require("./HotModuleReplacement.runtime.js")); |