| 
									
										
										
										
											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"; | 
					
						
							| 
									
										
										
										
											2018-03-22 19:05:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | const { SyncBailHook } = require("tapable"); | 
					
						
							|  |  |  | const { RawSource } = require("webpack-sources"); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | const Template = require("./Template"); | 
					
						
							|  |  |  | const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency"); | 
					
						
							|  |  |  | const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency"); | 
					
						
							|  |  |  | const ConstDependency = require("./dependencies/ConstDependency"); | 
					
						
							|  |  |  | const NullFactory = require("./NullFactory"); | 
					
						
							| 
									
										
										
										
											2017-01-09 02:11:26 +08:00
										 |  |  | const ParserHelpers = require("./ParserHelpers"); | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		const hotUpdateChunkFilename = | 
					
						
							|  |  |  | 			compiler.options.output.hotUpdateChunkFilename; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 		const hotUpdateMainFilename = compiler.options.output.hotUpdateMainFilename; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		compiler.hooks.additionalPass.tapAsync( | 
					
						
							|  |  |  | 			"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 			callback => { | 
					
						
							|  |  |  | 				if (multiStep) return setTimeout(callback, fullBuildTimeout); | 
					
						
							|  |  |  | 				return callback(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 		compiler.hooks.compilation.tap( | 
					
						
							|  |  |  | 			"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 			(compilation, { normalModuleFactory }) => { | 
					
						
							|  |  |  | 				const hotUpdateChunkTemplate = compilation.hotUpdateChunkTemplate; | 
					
						
							|  |  |  | 				if (!hotUpdateChunkTemplate) return; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				compilation.dependencyFactories.set(ConstDependency, new NullFactory()); | 
					
						
							|  |  |  | 				compilation.dependencyTemplates.set( | 
					
						
							|  |  |  | 					ConstDependency, | 
					
						
							|  |  |  | 					new ConstDependency.Template() | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				compilation.dependencyFactories.set( | 
					
						
							|  |  |  | 					ModuleHotAcceptDependency, | 
					
						
							|  |  |  | 					normalModuleFactory | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				compilation.dependencyTemplates.set( | 
					
						
							|  |  |  | 					ModuleHotAcceptDependency, | 
					
						
							|  |  |  | 					new ModuleHotAcceptDependency.Template() | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				compilation.dependencyFactories.set( | 
					
						
							|  |  |  | 					ModuleHotDeclineDependency, | 
					
						
							|  |  |  | 					normalModuleFactory | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				compilation.dependencyTemplates.set( | 
					
						
							|  |  |  | 					ModuleHotDeclineDependency, | 
					
						
							|  |  |  | 					new ModuleHotDeclineDependency.Template() | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				compilation.hooks.record.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					(compilation, records) => { | 
					
						
							|  |  |  | 						if (records.hash === compilation.hash) return; | 
					
						
							|  |  |  | 						records.hash = compilation.hash; | 
					
						
							|  |  |  | 						records.moduleHashs = {}; | 
					
						
							|  |  |  | 						for (const module of compilation.modules) { | 
					
						
							|  |  |  | 							const identifier = module.identifier(); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:25:15 +08:00
										 |  |  | 							records.moduleHashs[identifier] = module.hash; | 
					
						
							| 
									
										
										
										
											2018-01-04 19:48:09 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						records.chunkHashs = {}; | 
					
						
							|  |  |  | 						for (const chunk of compilation.chunks) { | 
					
						
							|  |  |  | 							records.chunkHashs[chunk.id] = chunk.hash; | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						records.chunkModuleIds = {}; | 
					
						
							|  |  |  | 						for (const chunk of compilation.chunks) { | 
					
						
							|  |  |  | 							records.chunkModuleIds[chunk.id] = Array.from( | 
					
						
							|  |  |  | 								chunk.modulesIterable, | 
					
						
							|  |  |  | 								m => m.id | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				let initialPass = false; | 
					
						
							|  |  |  | 				let recompilation = false; | 
					
						
							|  |  |  | 				compilation.hooks.afterHash.tap("HotModuleReplacementPlugin", () => { | 
					
						
							|  |  |  | 					let records = compilation.records; | 
					
						
							|  |  |  | 					if (!records) { | 
					
						
							|  |  |  | 						initialPass = true; | 
					
						
							|  |  |  | 						return; | 
					
						
							| 
									
										
										
										
											2013-07-01 19:59:02 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					if (!records.hash) initialPass = true; | 
					
						
							|  |  |  | 					const preHash = records.preHash || "x"; | 
					
						
							|  |  |  | 					const prepreHash = records.prepreHash || "x"; | 
					
						
							|  |  |  | 					if (preHash === compilation.hash) { | 
					
						
							|  |  |  | 						recompilation = true; | 
					
						
							|  |  |  | 						compilation.modifyHash(prepreHash); | 
					
						
							|  |  |  | 						return; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					records.prepreHash = records.hash || "x"; | 
					
						
							|  |  |  | 					records.preHash = compilation.hash; | 
					
						
							|  |  |  | 					compilation.modifyHash(records.prepreHash); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				compilation.hooks.shouldGenerateChunkAssets.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					() => { | 
					
						
							|  |  |  | 						if (multiStep && !recompilation && !initialPass) return false; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				compilation.hooks.needAdditionalPass.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					() => { | 
					
						
							|  |  |  | 						if (multiStep && !recompilation && !initialPass) return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				compilation.hooks.additionalChunkAssets.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					() => { | 
					
						
							|  |  |  | 						const records = compilation.records; | 
					
						
							|  |  |  | 						if (records.hash === compilation.hash) return; | 
					
						
							|  |  |  | 						if ( | 
					
						
							|  |  |  | 							!records.moduleHashs || | 
					
						
							|  |  |  | 							!records.chunkHashs || | 
					
						
							|  |  |  | 							!records.chunkModuleIds | 
					
						
							|  |  |  | 						) | 
					
						
							|  |  |  | 							return; | 
					
						
							|  |  |  | 						for (const module of compilation.modules) { | 
					
						
							|  |  |  | 							const identifier = module.identifier(); | 
					
						
							| 
									
										
										
										
											2018-04-27 20:25:15 +08:00
										 |  |  | 							let hash = module.hash; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							module.hotUpdate = records.moduleHashs[identifier] !== hash; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						const hotUpdateMainContent = { | 
					
						
							|  |  |  | 							h: compilation.hash, | 
					
						
							|  |  |  | 							c: {} | 
					
						
							|  |  |  | 						}; | 
					
						
							| 
									
										
										
										
											2018-04-12 07:04:52 +08:00
										 |  |  | 						for (const key of Object.keys(records.chunkHashs)) { | 
					
						
							|  |  |  | 							const chunkId = isNaN(+key) ? key : +key; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							const currentChunk = compilation.chunks.find( | 
					
						
							|  |  |  | 								chunk => chunk.id === chunkId | 
					
						
							|  |  |  | 							); | 
					
						
							|  |  |  | 							if (currentChunk) { | 
					
						
							|  |  |  | 								const newModules = currentChunk | 
					
						
							|  |  |  | 									.getModules() | 
					
						
							|  |  |  | 									.filter(module => module.hotUpdate); | 
					
						
							|  |  |  | 								const allModules = new Set(); | 
					
						
							|  |  |  | 								for (const module of currentChunk.modulesIterable) { | 
					
						
							|  |  |  | 									allModules.add(module.id); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 								const removedModules = records.chunkModuleIds[chunkId].filter( | 
					
						
							|  |  |  | 									id => !allModules.has(id) | 
					
						
							|  |  |  | 								); | 
					
						
							|  |  |  | 								if (newModules.length > 0 || removedModules.length > 0) { | 
					
						
							|  |  |  | 									const source = hotUpdateChunkTemplate.render( | 
					
						
							|  |  |  | 										chunkId, | 
					
						
							|  |  |  | 										newModules, | 
					
						
							|  |  |  | 										removedModules, | 
					
						
							|  |  |  | 										compilation.hash, | 
					
						
							|  |  |  | 										compilation.moduleTemplates.javascript, | 
					
						
							|  |  |  | 										compilation.dependencyTemplates | 
					
						
							|  |  |  | 									); | 
					
						
							|  |  |  | 									const filename = compilation.getPath(hotUpdateChunkFilename, { | 
					
						
							|  |  |  | 										hash: records.hash, | 
					
						
							|  |  |  | 										chunk: currentChunk | 
					
						
							|  |  |  | 									}); | 
					
						
							|  |  |  | 									compilation.additionalChunkAssets.push(filename); | 
					
						
							|  |  |  | 									compilation.assets[filename] = source; | 
					
						
							|  |  |  | 									hotUpdateMainContent.c[chunkId] = true; | 
					
						
							|  |  |  | 									currentChunk.files.push(filename); | 
					
						
							|  |  |  | 									compilation.hooks.chunkAsset.call( | 
					
						
							|  |  |  | 										"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 										currentChunk, | 
					
						
							|  |  |  | 										filename | 
					
						
							|  |  |  | 									); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} else { | 
					
						
							|  |  |  | 								hotUpdateMainContent.c[chunkId] = false; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						const source = new RawSource(JSON.stringify(hotUpdateMainContent)); | 
					
						
							|  |  |  | 						const filename = compilation.getPath(hotUpdateMainFilename, { | 
					
						
							|  |  |  | 							hash: records.hash | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 						compilation.assets[filename] = source; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				const mainTemplate = compilation.mainTemplate; | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				mainTemplate.hooks.hash.tap("HotModuleReplacementPlugin", hash => { | 
					
						
							|  |  |  | 					hash.update("HotMainTemplateDecorator"); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2014-08-25 15:50:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				mainTemplate.hooks.moduleRequire.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					(_, chunk, hash, varModuleId) => { | 
					
						
							|  |  |  | 						return `hotCreateRequire(${varModuleId})`; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				mainTemplate.hooks.requireExtensions.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					source => { | 
					
						
							|  |  |  | 						const buf = [source]; | 
					
						
							|  |  |  | 						buf.push(""); | 
					
						
							|  |  |  | 						buf.push("// __webpack_hash__"); | 
					
						
							|  |  |  | 						buf.push( | 
					
						
							|  |  |  | 							mainTemplate.requireFn + | 
					
						
							|  |  |  | 								".h = function() { return hotCurrentHash; };" | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 						return Template.asString(buf); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2018-01-20 00:06:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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; | 
					
						
							|  |  |  | 				}; | 
					
						
							| 
									
										
										
										
											2014-04-20 03:35:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				mainTemplate.hooks.bootstrap.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					(source, chunk, hash) => { | 
					
						
							|  |  |  | 						source = mainTemplate.hooks.hotBootstrap.call(source, chunk, hash); | 
					
						
							|  |  |  | 						return Template.asString([ | 
					
						
							|  |  |  | 							source, | 
					
						
							|  |  |  | 							"", | 
					
						
							|  |  |  | 							hotInitCode | 
					
						
							|  |  |  | 								.replace(/\$require\$/g, mainTemplate.requireFn) | 
					
						
							|  |  |  | 								.replace(/\$hash\$/g, JSON.stringify(hash)) | 
					
						
							|  |  |  | 								.replace(/\$requestTimeout\$/g, requestTimeout) | 
					
						
							|  |  |  | 								.replace( | 
					
						
							|  |  |  | 									/\/\*foreachInstalledChunks\*\//g, | 
					
						
							|  |  |  | 									needChunkLoadingCode(chunk) | 
					
						
							|  |  |  | 										? "for(var chunkId in installedChunks)" | 
					
						
							|  |  |  | 										: `var chunkId = ${JSON.stringify(chunk.id)};` | 
					
						
							|  |  |  | 								) | 
					
						
							|  |  |  | 						]); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				mainTemplate.hooks.globalHash.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					() => true | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				mainTemplate.hooks.currentHash.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					(_, length) => { | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 						if (isFinite(length)) { | 
					
						
							|  |  |  | 							return `hotCurrentHash.substr(0, ${length})`; | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							return "hotCurrentHash"; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				mainTemplate.hooks.moduleObj.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					(source, chunk, hash, varModuleId) => { | 
					
						
							|  |  |  | 						return Template.asString([ | 
					
						
							|  |  |  | 							`${source},`, | 
					
						
							|  |  |  | 							`hot: hotCreateModule(${varModuleId}),`, | 
					
						
							|  |  |  | 							"parents: (hotCurrentParentsTemp = hotCurrentParents, hotCurrentParents = [], hotCurrentParentsTemp),", | 
					
						
							|  |  |  | 							"children: []" | 
					
						
							|  |  |  | 						]); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				const handler = (parser, parserOptions) => { | 
					
						
							|  |  |  | 					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( | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							name: "HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 							before: "NodeStuffPlugin" | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						expr => { | 
					
						
							|  |  |  | 							return ParserHelpers.evaluateToIdentifier( | 
					
						
							|  |  |  | 								"module.hot", | 
					
						
							|  |  |  | 								!!parser.state.compilation.hotUpdateChunkTemplate | 
					
						
							|  |  |  | 							)(expr); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 					// TODO webpack 5: refactor this, no custom hooks
 | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					if (!parser.hooks.hotAcceptCallback) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						parser.hooks.hotAcceptCallback = new SyncBailHook([ | 
					
						
							|  |  |  | 							"expression", | 
					
						
							|  |  |  | 							"requests" | 
					
						
							|  |  |  | 						]); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					if (!parser.hooks.hotAcceptWithoutCallback) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 						parser.hooks.hotAcceptWithoutCallback = new SyncBailHook([ | 
					
						
							|  |  |  | 							"expression", | 
					
						
							|  |  |  | 							"requests" | 
					
						
							|  |  |  | 						]); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					parser.hooks.call | 
					
						
							|  |  |  | 						.for("module.hot.accept") | 
					
						
							|  |  |  | 						.tap("HotModuleReplacementPlugin", expr => { | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 							if (!parser.state.compilation.hotUpdateChunkTemplate) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								return false; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							if (expr.arguments.length >= 1) { | 
					
						
							|  |  |  | 								const arg = parser.evaluateExpression(expr.arguments[0]); | 
					
						
							|  |  |  | 								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; | 
					
						
							|  |  |  | 										parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 										requests.push(request); | 
					
						
							|  |  |  | 									}); | 
					
						
							| 
									
										
										
										
											2018-04-04 23:40:23 +08:00
										 |  |  | 									if (expr.arguments.length > 1) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 										parser.hooks.hotAcceptCallback.call( | 
					
						
							|  |  |  | 											expr.arguments[1], | 
					
						
							|  |  |  | 											requests | 
					
						
							|  |  |  | 										); | 
					
						
							| 
									
										
										
										
											2018-04-04 23:40:23 +08:00
										 |  |  | 										parser.walkExpression(expr.arguments[1]); // other args are ignored
 | 
					
						
							|  |  |  | 										return true; | 
					
						
							|  |  |  | 									} else { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 										parser.hooks.hotAcceptWithoutCallback.call(expr, requests); | 
					
						
							| 
									
										
										
										
											2018-04-04 23:40:23 +08:00
										 |  |  | 										return true; | 
					
						
							|  |  |  | 									} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 					parser.hooks.call | 
					
						
							|  |  |  | 						.for("module.hot.decline") | 
					
						
							|  |  |  | 						.tap("HotModuleReplacementPlugin", expr => { | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 							if (!parser.state.compilation.hotUpdateChunkTemplate) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 								return false; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 							if (expr.arguments.length === 1) { | 
					
						
							|  |  |  | 								const arg = parser.evaluateExpression(expr.arguments[0]); | 
					
						
							|  |  |  | 								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 | 
					
						
							|  |  |  | 									); | 
					
						
							|  |  |  | 									dep.optional = true; | 
					
						
							|  |  |  | 									dep.loc = Object.create(expr.loc); | 
					
						
							|  |  |  | 									dep.loc.index = idx; | 
					
						
							|  |  |  | 									parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 								}); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 					parser.hooks.expression | 
					
						
							|  |  |  | 						.for("module.hot") | 
					
						
							|  |  |  | 						.tap("HotModuleReplacementPlugin", ParserHelpers.skipTraversal); | 
					
						
							|  |  |  | 				}; | 
					
						
							| 
									
										
										
										
											2017-12-14 17:22:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 				compilation.hooks.normalModuleLoader.tap( | 
					
						
							|  |  |  | 					"HotModuleReplacementPlugin", | 
					
						
							|  |  |  | 					context => { | 
					
						
							|  |  |  | 						context.hot = true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2017-06-18 02:57:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-06-19 19:49:57 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | const hotInitCode = Template.getFunctionContent( | 
					
						
							|  |  |  | 	require("./HotModuleReplacement.runtime.js") | 
					
						
							|  |  |  | ); |