mirror of https://github.com/webpack/webpack.git
				
				
				
			support import.meta.hot
This commit is contained in:
		
							parent
							
								
									8aaff95a1b
								
							
						
					
					
						commit
						104845a419
					
				|  | @ -4,6 +4,7 @@ | ||||||
|   "words": [ |   "words": [ | ||||||
|     "webpack", |     "webpack", | ||||||
|     "webpack's", |     "webpack's", | ||||||
|  |     "endregion", | ||||||
|     "entrypoint", |     "entrypoint", | ||||||
|     "entrypoints", |     "entrypoints", | ||||||
|     "splitted", |     "splitted", | ||||||
|  |  | ||||||
|  | @ -12,9 +12,11 @@ const Compilation = require("./Compilation"); | ||||||
| const HotUpdateChunk = require("./HotUpdateChunk"); | const HotUpdateChunk = require("./HotUpdateChunk"); | ||||||
| const NormalModule = require("./NormalModule"); | const NormalModule = require("./NormalModule"); | ||||||
| const RuntimeGlobals = require("./RuntimeGlobals"); | const RuntimeGlobals = require("./RuntimeGlobals"); | ||||||
|  | const HMRApiDependency = require("./dependencies/HMRApiDependency"); | ||||||
|  | const ImportMetaHotAcceptDependency = require("./dependencies/ImportMetaHotAcceptDependency"); | ||||||
|  | const ImportMetaHotDeclineDependency = require("./dependencies/ImportMetaHotDeclineDependency"); | ||||||
| const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency"); | const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency"); | ||||||
| const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency"); | const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency"); | ||||||
| const ModuleHotDependency = require("./dependencies/ModuleHotDependency"); |  | ||||||
| const HotModuleReplacementRuntimeModule = require("./hmr/HotModuleReplacementRuntimeModule"); | const HotModuleReplacementRuntimeModule = require("./hmr/HotModuleReplacementRuntimeModule"); | ||||||
| const JavascriptParser = require("./javascript/JavascriptParser"); | const JavascriptParser = require("./javascript/JavascriptParser"); | ||||||
| const { | const { | ||||||
|  | @ -82,12 +84,83 @@ class HotModuleReplacementPlugin { | ||||||
| 			} | 			} | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		const addParserPlugins = (parser, parserOptions) => { | 		const createAcceptHandler = (parser, paramDependency) => { | ||||||
| 			const { | 			const { | ||||||
| 				hotAcceptCallback, | 				hotAcceptCallback, | ||||||
| 				hotAcceptWithoutCallback | 				hotAcceptWithoutCallback | ||||||
| 			} = HotModuleReplacementPlugin.getParserHooks(parser); | 			} = HotModuleReplacementPlugin.getParserHooks(parser); | ||||||
| 
 | 
 | ||||||
|  | 			return expr => { | ||||||
|  | 				const dep = new HMRApiDependency(expr.callee.range, "accept"); | ||||||
|  | 				dep.loc = expr.loc; | ||||||
|  | 				parser.state.module.addDependency(dep); | ||||||
|  | 				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 paramDependency(request, param.range); | ||||||
|  | 							dep.optional = true; | ||||||
|  | 							dep.loc = Object.create(expr.loc); | ||||||
|  | 							dep.loc.index = idx; | ||||||
|  | 							parser.state.module.addDependency(dep); | ||||||
|  | 							requests.push(request); | ||||||
|  | 						}); | ||||||
|  | 						if (expr.arguments.length > 1) { | ||||||
|  | 							hotAcceptCallback.call(expr.arguments[1], requests); | ||||||
|  | 							parser.walkExpression(expr.arguments[1]); // other args are ignored
 | ||||||
|  | 							return true; | ||||||
|  | 						} else { | ||||||
|  | 							hotAcceptWithoutCallback.call(expr, requests); | ||||||
|  | 							return true; | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				parser.walkExpressions(expr.arguments); | ||||||
|  | 				return true; | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		const createDeclineHandler = (parser, paramDependency) => expr => { | ||||||
|  | 			const dep = new HMRApiDependency(expr.callee.range, "decline"); | ||||||
|  | 			dep.loc = expr.loc; | ||||||
|  | 			parser.state.module.addDependency(dep); | ||||||
|  | 			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 paramDependency(param.string, param.range); | ||||||
|  | 					dep.optional = true; | ||||||
|  | 					dep.loc = Object.create(expr.loc); | ||||||
|  | 					dep.loc.index = idx; | ||||||
|  | 					parser.state.module.addDependency(dep); | ||||||
|  | 				}); | ||||||
|  | 			} | ||||||
|  | 			return true; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		const createHMRExpressionHandler = parser => expr => { | ||||||
|  | 			const dep = new HMRApiDependency(expr.range); | ||||||
|  | 			dep.loc = expr.loc; | ||||||
|  | 			parser.state.module.addDependency(dep); | ||||||
|  | 			return true; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		const addParserPlugins = (parser, parserOptions) => { | ||||||
|  | 			const hmrExpressionHandler = createHMRExpressionHandler(parser); | ||||||
|  | 
 | ||||||
| 			parser.hooks.expression | 			parser.hooks.expression | ||||||
| 				.for("__webpack_hash__") | 				.for("__webpack_hash__") | ||||||
| 				.tap( | 				.tap( | ||||||
|  | @ -99,6 +172,8 @@ class HotModuleReplacementPlugin { | ||||||
| 			parser.hooks.evaluateTypeof | 			parser.hooks.evaluateTypeof | ||||||
| 				.for("__webpack_hash__") | 				.for("__webpack_hash__") | ||||||
| 				.tap("HotModuleReplacementPlugin", evaluateToString("string")); | 				.tap("HotModuleReplacementPlugin", evaluateToString("string")); | ||||||
|  | 
 | ||||||
|  | 			//#region module.hot.* API
 | ||||||
| 			parser.hooks.evaluateIdentifier.for("module.hot").tap( | 			parser.hooks.evaluateIdentifier.for("module.hot").tap( | ||||||
| 				{ | 				{ | ||||||
| 					name: "HotModuleReplacementPlugin", | 					name: "HotModuleReplacementPlugin", | ||||||
|  | @ -115,77 +190,48 @@ class HotModuleReplacementPlugin { | ||||||
| 			); | 			); | ||||||
| 			parser.hooks.call | 			parser.hooks.call | ||||||
| 				.for("module.hot.accept") | 				.for("module.hot.accept") | ||||||
| 				.tap("HotModuleReplacementPlugin", expr => { | 				.tap( | ||||||
| 					const dep = new ModuleHotDependency(expr.callee.range, "accept"); | 					"HotModuleReplacementPlugin", | ||||||
| 					dep.loc = expr.loc; | 					createAcceptHandler(parser, ModuleHotAcceptDependency) | ||||||
| 					parser.state.module.addDependency(dep); | 				); | ||||||
| 					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); |  | ||||||
| 							}); |  | ||||||
| 							if (expr.arguments.length > 1) { |  | ||||||
| 								hotAcceptCallback.call(expr.arguments[1], requests); |  | ||||||
| 								parser.walkExpression(expr.arguments[1]); // other args are ignored
 |  | ||||||
| 								return true; |  | ||||||
| 							} else { |  | ||||||
| 								hotAcceptWithoutCallback.call(expr, requests); |  | ||||||
| 								return true; |  | ||||||
| 							} |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 					parser.walkExpressions(expr.arguments); |  | ||||||
| 					return true; |  | ||||||
| 				}); |  | ||||||
| 			parser.hooks.call | 			parser.hooks.call | ||||||
| 				.for("module.hot.decline") | 				.for("module.hot.decline") | ||||||
| 				.tap("HotModuleReplacementPlugin", expr => { | 				.tap( | ||||||
| 					const dep = new ModuleHotDependency(expr.callee.range, "decline"); | 					"HotModuleReplacementPlugin", | ||||||
| 					dep.loc = expr.loc; | 					createDeclineHandler(parser, ModuleHotDeclineDependency) | ||||||
| 					parser.state.module.addDependency(dep); | 				); | ||||||
| 					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); |  | ||||||
| 						}); |  | ||||||
| 					} |  | ||||||
| 					return true; |  | ||||||
| 				}); |  | ||||||
| 			parser.hooks.expression | 			parser.hooks.expression | ||||||
| 				.for("module.hot") | 				.for("module.hot") | ||||||
|  | 				.tap("HotModuleReplacementPlugin", hmrExpressionHandler); | ||||||
|  | 			//#endregion
 | ||||||
|  | 
 | ||||||
|  | 			//#region import.meta.hot.* API
 | ||||||
|  | 			parser.hooks.evaluateIdentifier | ||||||
|  | 				.for("import.meta.hot") | ||||||
| 				.tap("HotModuleReplacementPlugin", expr => { | 				.tap("HotModuleReplacementPlugin", expr => { | ||||||
| 					const dep = new ModuleHotDependency(expr.range); | 					return evaluateToIdentifier( | ||||||
| 					dep.loc = expr.loc; | 						"import.meta.hot", | ||||||
| 					parser.state.module.addDependency(dep); | 						"import.meta", | ||||||
| 					return true; | 						() => ["hot"], | ||||||
|  | 						true | ||||||
|  | 					)(expr); | ||||||
| 				}); | 				}); | ||||||
|  | 			parser.hooks.call | ||||||
|  | 				.for("import.meta.hot.accept") | ||||||
|  | 				.tap( | ||||||
|  | 					"HotModuleReplacementPlugin", | ||||||
|  | 					createAcceptHandler(parser, ImportMetaHotAcceptDependency) | ||||||
|  | 				); | ||||||
|  | 			parser.hooks.call | ||||||
|  | 				.for("import.meta.hot.decline") | ||||||
|  | 				.tap( | ||||||
|  | 					"HotModuleReplacementPlugin", | ||||||
|  | 					createDeclineHandler(parser, ImportMetaHotDeclineDependency) | ||||||
|  | 				); | ||||||
|  | 			parser.hooks.expression | ||||||
|  | 				.for("import.meta.hot") | ||||||
|  | 				.tap("HotModuleReplacementPlugin", hmrExpressionHandler); | ||||||
|  | 			//#endregion
 | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		compiler.hooks.compilation.tap( | 		compiler.hooks.compilation.tap( | ||||||
|  | @ -195,6 +241,7 @@ class HotModuleReplacementPlugin { | ||||||
| 				// It should not affect child compilations
 | 				// It should not affect child compilations
 | ||||||
| 				if (compilation.compiler !== compiler) return; | 				if (compilation.compiler !== compiler) return; | ||||||
| 
 | 
 | ||||||
|  | 				//#region module.hot.* API
 | ||||||
| 				compilation.dependencyFactories.set( | 				compilation.dependencyFactories.set( | ||||||
| 					ModuleHotAcceptDependency, | 					ModuleHotAcceptDependency, | ||||||
| 					normalModuleFactory | 					normalModuleFactory | ||||||
|  | @ -203,7 +250,6 @@ class HotModuleReplacementPlugin { | ||||||
| 					ModuleHotAcceptDependency, | 					ModuleHotAcceptDependency, | ||||||
| 					new ModuleHotAcceptDependency.Template() | 					new ModuleHotAcceptDependency.Template() | ||||||
| 				); | 				); | ||||||
| 
 |  | ||||||
| 				compilation.dependencyFactories.set( | 				compilation.dependencyFactories.set( | ||||||
| 					ModuleHotDeclineDependency, | 					ModuleHotDeclineDependency, | ||||||
| 					normalModuleFactory | 					normalModuleFactory | ||||||
|  | @ -212,10 +258,30 @@ class HotModuleReplacementPlugin { | ||||||
| 					ModuleHotDeclineDependency, | 					ModuleHotDeclineDependency, | ||||||
| 					new ModuleHotDeclineDependency.Template() | 					new ModuleHotDeclineDependency.Template() | ||||||
| 				); | 				); | ||||||
|  | 				//#endregion
 | ||||||
|  | 
 | ||||||
|  | 				//#region import.meta.hot.* API
 | ||||||
|  | 				compilation.dependencyFactories.set( | ||||||
|  | 					ImportMetaHotAcceptDependency, | ||||||
|  | 					normalModuleFactory | ||||||
|  | 				); | ||||||
|  | 				compilation.dependencyTemplates.set( | ||||||
|  | 					ImportMetaHotAcceptDependency, | ||||||
|  | 					new ImportMetaHotAcceptDependency.Template() | ||||||
|  | 				); | ||||||
|  | 				compilation.dependencyFactories.set( | ||||||
|  | 					ImportMetaHotDeclineDependency, | ||||||
|  | 					normalModuleFactory | ||||||
|  | 				); | ||||||
|  | 				compilation.dependencyTemplates.set( | ||||||
|  | 					ImportMetaHotDeclineDependency, | ||||||
|  | 					new ImportMetaHotDeclineDependency.Template() | ||||||
|  | 				); | ||||||
|  | 				//#endregion
 | ||||||
| 
 | 
 | ||||||
| 				compilation.dependencyTemplates.set( | 				compilation.dependencyTemplates.set( | ||||||
| 					ModuleHotDependency, | 					HMRApiDependency, | ||||||
| 					new ModuleHotDependency.Template() | 					new HMRApiDependency.Template() | ||||||
| 				); | 				); | ||||||
| 
 | 
 | ||||||
| 				compilation.hooks.record.tap( | 				compilation.hooks.record.tap( | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ const NullDependency = require("./NullDependency"); | ||||||
| /** @typedef {import("../Dependency")} Dependency */ | /** @typedef {import("../Dependency")} Dependency */ | ||||||
| /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ | /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ | ||||||
| 
 | 
 | ||||||
| class ModuleHotDependency extends NullDependency { | class HMRApiDependency extends NullDependency { | ||||||
| 	constructor(range, apiMethod) { | 	constructor(range, apiMethod) { | ||||||
| 		super(); | 		super(); | ||||||
| 
 | 
 | ||||||
|  | @ -22,7 +22,7 @@ class ModuleHotDependency extends NullDependency { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	get type() { | 	get type() { | ||||||
| 		return "module.hot"; | 		return "module.hot and import.meta.hot"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	serialize(context) { | 	serialize(context) { | ||||||
|  | @ -44,12 +44,9 @@ class ModuleHotDependency extends NullDependency { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| makeSerializable( | makeSerializable(HMRApiDependency, "webpack/lib/dependencies/HMRApiDependency"); | ||||||
| 	ModuleHotDependency, |  | ||||||
| 	"webpack/lib/dependencies/ModuleHotDependency" |  | ||||||
| ); |  | ||||||
| 
 | 
 | ||||||
| ModuleHotDependency.Template = class ModuleHotDependencyTemplate extends NullDependency.Template { | HMRApiDependency.Template = class HMRApiDependencyTemplate extends NullDependency.Template { | ||||||
| 	/** | 	/** | ||||||
| 	 * @param {Dependency} dependency the dependency for which the template should be applied | 	 * @param {Dependency} dependency the dependency for which the template should be applied | ||||||
| 	 * @param {ReplaceSource} source the current replace source which can be modified | 	 * @param {ReplaceSource} source the current replace source which can be modified | ||||||
|  | @ -57,7 +54,7 @@ ModuleHotDependency.Template = class ModuleHotDependencyTemplate extends NullDep | ||||||
| 	 * @returns {void} | 	 * @returns {void} | ||||||
| 	 */ | 	 */ | ||||||
| 	apply(dependency, source, { module, runtimeRequirements }) { | 	apply(dependency, source, { module, runtimeRequirements }) { | ||||||
| 		const dep = /** @type {ModuleHotDependency} */ (dependency); | 		const dep = /** @type {HMRApiDependency} */ (dependency); | ||||||
| 		runtimeRequirements.add(RuntimeGlobals.module); | 		runtimeRequirements.add(RuntimeGlobals.module); | ||||||
| 		source.replace( | 		source.replace( | ||||||
| 			dep.range[0], | 			dep.range[0], | ||||||
|  | @ -67,4 +64,4 @@ ModuleHotDependency.Template = class ModuleHotDependencyTemplate extends NullDep | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| module.exports = ModuleHotDependency; | module.exports = HMRApiDependency; | ||||||
|  | @ -0,0 +1,35 @@ | ||||||
|  | /* | ||||||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||||||
|  | 	Author Ivan Kopeykin @vankop | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const makeSerializable = require("../util/makeSerializable"); | ||||||
|  | const ModuleDependency = require("./ModuleDependency"); | ||||||
|  | const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); | ||||||
|  | 
 | ||||||
|  | class ImportMetaHotAcceptDependency extends ModuleDependency { | ||||||
|  | 	constructor(request, range) { | ||||||
|  | 		super(request); | ||||||
|  | 		this.range = range; | ||||||
|  | 		this.weak = true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	get type() { | ||||||
|  | 		return "import.meta.hot.accept"; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	get category() { | ||||||
|  | 		return "esm"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | makeSerializable( | ||||||
|  | 	ImportMetaHotAcceptDependency, | ||||||
|  | 	"webpack/lib/dependencies/ImportMetaHotAcceptDependency" | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | ImportMetaHotAcceptDependency.Template = ModuleDependencyTemplateAsId; | ||||||
|  | 
 | ||||||
|  | module.exports = ImportMetaHotAcceptDependency; | ||||||
|  | @ -0,0 +1,36 @@ | ||||||
|  | /* | ||||||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||||||
|  | 	Author Ivan Kopeykin @vankop | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const makeSerializable = require("../util/makeSerializable"); | ||||||
|  | const ModuleDependency = require("./ModuleDependency"); | ||||||
|  | const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); | ||||||
|  | 
 | ||||||
|  | class ImportMetaHotDeclineDependency extends ModuleDependency { | ||||||
|  | 	constructor(request, range) { | ||||||
|  | 		super(request); | ||||||
|  | 
 | ||||||
|  | 		this.range = range; | ||||||
|  | 		this.weak = true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	get type() { | ||||||
|  | 		return "import.meta.hot.decline"; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	get category() { | ||||||
|  | 		return "esm"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | makeSerializable( | ||||||
|  | 	ImportMetaHotDeclineDependency, | ||||||
|  | 	"webpack/lib/dependencies/ImportMetaHotDeclineDependency" | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | ImportMetaHotDeclineDependency.Template = ModuleDependencyTemplateAsId; | ||||||
|  | 
 | ||||||
|  | module.exports = ImportMetaHotDeclineDependency; | ||||||
|  | @ -30,6 +30,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression"); | ||||||
| /** @typedef {import("estree").Literal} LiteralNode */ | /** @typedef {import("estree").Literal} LiteralNode */ | ||||||
| /** @typedef {import("estree").LogicalExpression} LogicalExpressionNode */ | /** @typedef {import("estree").LogicalExpression} LogicalExpressionNode */ | ||||||
| /** @typedef {import("estree").MemberExpression} MemberExpressionNode */ | /** @typedef {import("estree").MemberExpression} MemberExpressionNode */ | ||||||
|  | /** @typedef {import("estree").MetaProperty} MetaPropertyNode */ | ||||||
| /** @typedef {import("estree").MethodDefinition} MethodDefinitionNode */ | /** @typedef {import("estree").MethodDefinition} MethodDefinitionNode */ | ||||||
| /** @typedef {import("estree").ModuleDeclaration} ModuleDeclarationNode */ | /** @typedef {import("estree").ModuleDeclaration} ModuleDeclarationNode */ | ||||||
| /** @typedef {import("estree").Node} AnyNode */ | /** @typedef {import("estree").Node} AnyNode */ | ||||||
|  | @ -105,6 +106,8 @@ const getRootName = expression => { | ||||||
| 			return expression.name; | 			return expression.name; | ||||||
| 		case "ThisExpression": | 		case "ThisExpression": | ||||||
| 			return "this"; | 			return "this"; | ||||||
|  | 		case "MetaProperty": | ||||||
|  | 			return "import.meta"; | ||||||
| 		default: | 		default: | ||||||
| 			return undefined; | 			return undefined; | ||||||
| 	} | 	} | ||||||
|  | @ -3157,6 +3160,7 @@ class JavascriptParser extends Parser { | ||||||
| 				}; | 				}; | ||||||
| 			} | 			} | ||||||
| 			case "Identifier": | 			case "Identifier": | ||||||
|  | 			case "MetaProperty": | ||||||
| 			case "ThisExpression": { | 			case "ThisExpression": { | ||||||
| 				if (!possibleTypes.has("expression")) return undefined; | 				if (!possibleTypes.has("expression")) return undefined; | ||||||
| 				const rootName = getRootName(object); | 				const rootName = getRootName(object); | ||||||
|  |  | ||||||
|  | @ -108,8 +108,12 @@ module.exports = { | ||||||
| 		require("../dependencies/ModuleHotAcceptDependency"), | 		require("../dependencies/ModuleHotAcceptDependency"), | ||||||
| 	"dependencies/ModuleHotDeclineDependency": () => | 	"dependencies/ModuleHotDeclineDependency": () => | ||||||
| 		require("../dependencies/ModuleHotDeclineDependency"), | 		require("../dependencies/ModuleHotDeclineDependency"), | ||||||
| 	"dependencies/ModuleHotDependency": () => | 	"dependencies/ImportMetaHotAcceptDependency": () => | ||||||
| 		require("../dependencies/ModuleHotDependency"), | 		require("../dependencies/ImportMetaHotAcceptDependency"), | ||||||
|  | 	"dependencies/ImportMetaHotDeclineDependency": () => | ||||||
|  | 		require("../dependencies/ImportMetaHotDeclineDependency"), | ||||||
|  | 	"dependencies/HMRApiDependency": () => | ||||||
|  | 		require("../dependencies/HMRApiDependency"), | ||||||
| 	"dependencies/ProvidedDependency": () => | 	"dependencies/ProvidedDependency": () => | ||||||
| 		require("../dependencies/ProvidedDependency"), | 		require("../dependencies/ProvidedDependency"), | ||||||
| 	"dependencies/PureExpressionDependency": () => | 	"dependencies/PureExpressionDependency": () => | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
| export var value = 1; | export var value = 1; | ||||||
| --- | --- | ||||||
| export var value = 2; | export var value = 2; | ||||||
|  | --- | ||||||
|  | export var value = 3; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| it("should import a changed chunk", (done) => { | it("should import a changed chunk using module.hot.accept API", (done) => { | ||||||
| 	import("./chunk").then((chunk) => { | 	import("./chunk").then((chunk) => { | ||||||
| 		expect(chunk.value).toBe(1); | 		expect(chunk.value).toBe(1); | ||||||
| 		import("./chunk2").then((chunk2) => { | 		import("./chunk2").then((chunk2) => { | ||||||
|  | @ -16,3 +16,22 @@ it("should import a changed chunk", (done) => { | ||||||
| 		}).catch(done); | 		}).catch(done); | ||||||
| 	}).catch(done); | 	}).catch(done); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | it("should import a changed chunk using import.meta.hot.accept API", (done) => { | ||||||
|  | 	import("./chunk").then((chunk) => { | ||||||
|  | 		expect(chunk.value).toBe(2); | ||||||
|  | 		import("./chunk2").then((chunk2) => { | ||||||
|  | 			expect(chunk2.value).toBe(2); | ||||||
|  | 			NEXT(require("../../update")(done)); | ||||||
|  | 			import.meta.hot.accept(["./chunk", "./chunk2"], () => { | ||||||
|  | 				import("./chunk").then((chunk) => { | ||||||
|  | 					expect(chunk.value).toBe(3); | ||||||
|  | 					import("./chunk2").then((chunk2) => { | ||||||
|  | 						expect(chunk2.value).toBe(3); | ||||||
|  | 						done(); | ||||||
|  | 					}).catch(done); | ||||||
|  | 				}).catch(done); | ||||||
|  | 			}); | ||||||
|  | 		}).catch(done); | ||||||
|  | 	}).catch(done); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import vendor from "vendor"; | import vendor from "vendor"; | ||||||
| module.hot.accept("vendor"); | import.meta.hot.accept("vendor"); | ||||||
| it("should hot update a splitted initial chunk", function (done) { | it("should hot update a splitted initial chunk using import.meta.hot.* API", function (done) { | ||||||
| 	expect(vendor).toBe("1"); | 	expect(vendor).toBe("1"); | ||||||
| 	NEXT( | 	NEXT( | ||||||
| 		require("../../update")(done, true, () => { | 		require("../../update")(done, true, () => { | ||||||
|  | @ -9,3 +9,14 @@ it("should hot update a splitted initial chunk", function (done) { | ||||||
| 		}) | 		}) | ||||||
| 	); | 	); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | it("should hot update a splitted initial chunk using module.hot.* API", function (done) { | ||||||
|  | 	expect(vendor).toBe("2"); | ||||||
|  | 	module.hot.accept("vendor"); | ||||||
|  | 	NEXT( | ||||||
|  | 		require("../../update")(done, true, () => { | ||||||
|  | 			expect(vendor).toBe("3"); | ||||||
|  | 			done(); | ||||||
|  | 		}) | ||||||
|  | 	); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
| module.exports = "1"; | module.exports = "1"; | ||||||
| --- | --- | ||||||
| module.exports = "2"; | module.exports = "2"; | ||||||
|  | --- | ||||||
|  | module.exports = "3"; | ||||||
|  |  | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| import x from "./module"; | import x from "./module"; | ||||||
| 
 | 
 | ||||||
| it("should have correct this context in accept handler", (done) => { | it("should have correct this context in module.hot.accept handler", (done) => { | ||||||
| 	expect(x).toEqual("ok1"); | 	expect(x).toEqual("ok1"); | ||||||
|      | 
 | ||||||
|     (function() { |     (function() { | ||||||
|         module.hot.accept("./module", () => { |         module.hot.accept("./module", () => { | ||||||
|             expect(x).toEqual("ok2"); |             expect(x).toEqual("ok2"); | ||||||
|  | @ -13,3 +13,17 @@ it("should have correct this context in accept handler", (done) => { | ||||||
| 
 | 
 | ||||||
| 	NEXT(require("../../update")(done)); | 	NEXT(require("../../update")(done)); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | it("should have correct this context in import.meta.hot.accept handler", (done) => { | ||||||
|  | 	expect(x).toEqual("ok2"); | ||||||
|  | 
 | ||||||
|  | 	(function() { | ||||||
|  | 		import.meta.hot.accept("./module", () => { | ||||||
|  | 			expect(x).toEqual("ok3"); | ||||||
|  | 			expect(this).toEqual({ ok: true }); | ||||||
|  | 			done(); | ||||||
|  | 		}); | ||||||
|  | 	}).call({ ok: true }); | ||||||
|  | 
 | ||||||
|  | 	NEXT(require("../../update")(done)); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
| export default "ok1"; | export default "ok1"; | ||||||
| --- | --- | ||||||
| export default "ok2"; | export default "ok2"; | ||||||
|  | --- | ||||||
|  | export default "ok3"; | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import b from "./b"; | ||||||
| 
 | 
 | ||||||
| export default b; | export default b; | ||||||
| 
 | 
 | ||||||
| if(module.hot) { | if(import.meta.hot) { | ||||||
| 	module.hot.decline("./b"); | 	import.meta.hot.decline("./b"); | ||||||
| 	module.hot.accept(); | 	import.meta.hot.accept(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | import {val} from "./module"; | ||||||
|  | 
 | ||||||
|  | it("should fail import a changed chunk using module.hot.accept API", (done) => { | ||||||
|  | 	expect(val).toBe(1); | ||||||
|  | 	NEXT(require("../../update")((err) => { | ||||||
|  | 		try { | ||||||
|  | 			expect(err.message).toMatch(/Aborted because \.\/node_modules\/dep1\/file.js is not accepted/); | ||||||
|  | 			expect(err.message).toMatch(/Update propagation: \.\/node_modules\/dep1\/file.js -> \.\/node_modules\/dep1\/exports\.js -> \.\/module\.js -> \.\/index.js/); | ||||||
|  | 			done(); | ||||||
|  | 		} catch(e) { | ||||||
|  | 			done(e); | ||||||
|  | 		} | ||||||
|  | 	})); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | import {value} from "dep1"; | ||||||
|  | 
 | ||||||
|  | export const val = value; | ||||||
|  | 
 | ||||||
|  | module.hot.accept("dep1"); | ||||||
							
								
								
									
										1
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/exports.js
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										1
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/exports.js
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1 @@ | ||||||
|  | export {value} from "./file"; | ||||||
							
								
								
									
										3
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/file.js
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										3
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/file.js
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | export var value = 1; | ||||||
|  | --- | ||||||
|  | export var value = 2; | ||||||
							
								
								
									
										5
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/main.js
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										5
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/main.js
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | (() => { | ||||||
|  | 	throw new Error("should not resolve"); | ||||||
|  | })(); | ||||||
|  | 
 | ||||||
|  | export default 1; | ||||||
							
								
								
									
										6
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/package.json
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										6
									
								
								test/hotCases/errors/esm-dependency-import/node_modules/dep1/package.json
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | { | ||||||
|  |   "exports": { | ||||||
|  |     "import": "./exports.js", | ||||||
|  |     "default": "./main.js" | ||||||
|  |   } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue