diff options
Diffstat (limited to 'node_modules/webpack/lib/HotModuleReplacementPlugin.js')
| -rw-r--r-- | node_modules/webpack/lib/HotModuleReplacementPlugin.js | 869 |
1 files changed, 0 insertions, 869 deletions
diff --git a/node_modules/webpack/lib/HotModuleReplacementPlugin.js b/node_modules/webpack/lib/HotModuleReplacementPlugin.js deleted file mode 100644 index d3392981..00000000 --- a/node_modules/webpack/lib/HotModuleReplacementPlugin.js +++ /dev/null @@ -1,869 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -const { SyncBailHook } = require("tapable"); -const { RawSource } = require("webpack-sources"); -const ChunkGraph = require("./ChunkGraph"); -const Compilation = require("./Compilation"); -const HotUpdateChunk = require("./HotUpdateChunk"); -const NormalModule = require("./NormalModule"); -const RuntimeGlobals = require("./RuntimeGlobals"); -const WebpackError = require("./WebpackError"); -const ConstDependency = require("./dependencies/ConstDependency"); -const ImportMetaHotAcceptDependency = require("./dependencies/ImportMetaHotAcceptDependency"); -const ImportMetaHotDeclineDependency = require("./dependencies/ImportMetaHotDeclineDependency"); -const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency"); -const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency"); -const HotModuleReplacementRuntimeModule = require("./hmr/HotModuleReplacementRuntimeModule"); -const JavascriptParser = require("./javascript/JavascriptParser"); -const { - evaluateToIdentifier -} = require("./javascript/JavascriptParserHelpers"); -const { find, isSubset } = require("./util/SetHelpers"); -const TupleSet = require("./util/TupleSet"); -const { compareModulesById } = require("./util/comparators"); -const { - getRuntimeKey, - keyToRuntime, - forEachRuntime, - mergeRuntimeOwned, - subtractRuntime, - intersectRuntime -} = require("./util/runtime"); - -const { - JAVASCRIPT_MODULE_TYPE_AUTO, - JAVASCRIPT_MODULE_TYPE_DYNAMIC, - JAVASCRIPT_MODULE_TYPE_ESM, - WEBPACK_MODULE_TYPE_RUNTIME -} = require("./ModuleTypeConstants"); - -/** @typedef {import("estree").CallExpression} CallExpression */ -/** @typedef {import("estree").Expression} Expression */ -/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputNormalized */ -/** @typedef {import("./Chunk")} Chunk */ -/** @typedef {import("./Chunk").ChunkId} ChunkId */ -/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ -/** @typedef {import("./Compilation").AssetInfo} AssetInfo */ -/** @typedef {import("./Compiler")} Compiler */ -/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ -/** @typedef {import("./Module")} Module */ -/** @typedef {import("./Module").BuildInfo} BuildInfo */ -/** @typedef {import("./RuntimeModule")} RuntimeModule */ -/** @typedef {import("./javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ -/** @typedef {import("./javascript/JavascriptParserHelpers").Range} Range */ -/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ - -/** - * @typedef {object} HMRJavascriptParserHooks - * @property {SyncBailHook<[TODO, string[]], void>} hotAcceptCallback - * @property {SyncBailHook<[TODO, string[]], void>} hotAcceptWithoutCallback - */ - -/** @typedef {{ updatedChunkIds: Set<ChunkId>, removedChunkIds: Set<ChunkId>, removedModules: Set<Module>, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */ -/** @typedef {Map<string, HotUpdateMainContentByRuntimeItem>} HotUpdateMainContentByRuntime */ - -/** @type {WeakMap<JavascriptParser, HMRJavascriptParserHooks>} */ -const parserHooksMap = new WeakMap(); - -const PLUGIN_NAME = "HotModuleReplacementPlugin"; - -class HotModuleReplacementPlugin { - /** - * @param {JavascriptParser} parser the parser - * @returns {HMRJavascriptParserHooks} the attached hooks - */ - static getParserHooks(parser) { - if (!(parser instanceof JavascriptParser)) { - throw new TypeError( - "The 'parser' argument must be an instance of JavascriptParser" - ); - } - let hooks = parserHooksMap.get(parser); - if (hooks === undefined) { - hooks = { - hotAcceptCallback: new SyncBailHook(["expression", "requests"]), - hotAcceptWithoutCallback: new SyncBailHook(["expression", "requests"]) - }; - parserHooksMap.set(parser, hooks); - } - return hooks; - } - - /** - * @param {object=} options options - */ - constructor(options) { - this.options = options || {}; - } - - /** - * Apply the plugin - * @param {Compiler} compiler the compiler instance - * @returns {void} - */ - apply(compiler) { - const { _backCompat: backCompat } = compiler; - if (compiler.options.output.strictModuleErrorHandling === undefined) - compiler.options.output.strictModuleErrorHandling = true; - const runtimeRequirements = [RuntimeGlobals.module]; - - /** - * @param {JavascriptParser} parser the parser - * @param {typeof ModuleHotAcceptDependency} ParamDependency dependency - * @returns {(expr: CallExpression) => boolean | undefined} callback - */ - const createAcceptHandler = (parser, ParamDependency) => { - const { hotAcceptCallback, hotAcceptWithoutCallback } = - HotModuleReplacementPlugin.getParserHooks(parser); - - return expr => { - const module = parser.state.module; - const dep = new ConstDependency( - `${module.moduleArgument}.hot.accept`, - /** @type {Range} */ (expr.callee.range), - runtimeRequirements - ); - dep.loc = /** @type {DependencyLocation} */ (expr.loc); - module.addPresentationalDependency(dep); - /** @type {BuildInfo} */ - (module.buildInfo).moduleConcatenationBailout = - "Hot Module Replacement"; - if (expr.arguments.length >= 1) { - const arg = parser.evaluateExpression( - /** @type {Expression} */ (expr.arguments[0]) - ); - /** @type {BasicEvaluatedExpression[]} */ - let params = []; - if (arg.isString()) { - params = [arg]; - } else if (arg.isArray()) { - params = - /** @type {BasicEvaluatedExpression[]} */ - (arg.items).filter(param => param.isString()); - } - /** @type {string[]} */ - const requests = []; - if (params.length > 0) { - for (const [idx, param] of params.entries()) { - const request = /** @type {string} */ (param.string); - const dep = new ParamDependency( - request, - /** @type {Range} */ (param.range) - ); - dep.optional = true; - dep.loc = Object.create( - /** @type {DependencyLocation} */ (expr.loc) - ); - dep.loc.index = idx; - module.addDependency(dep); - requests.push(request); - } - if (expr.arguments.length > 1) { - hotAcceptCallback.call(expr.arguments[1], requests); - for (let i = 1; i < expr.arguments.length; i++) { - parser.walkExpression(expr.arguments[i]); - } - return true; - } - hotAcceptWithoutCallback.call(expr, requests); - return true; - } - } - parser.walkExpressions(expr.arguments); - return true; - }; - }; - - /** - * @param {JavascriptParser} parser the parser - * @param {typeof ModuleHotDeclineDependency} ParamDependency dependency - * @returns {(expr: CallExpression) => boolean | undefined} callback - */ - const createDeclineHandler = (parser, ParamDependency) => expr => { - const module = parser.state.module; - const dep = new ConstDependency( - `${module.moduleArgument}.hot.decline`, - /** @type {Range} */ (expr.callee.range), - runtimeRequirements - ); - dep.loc = /** @type {DependencyLocation} */ (expr.loc); - module.addPresentationalDependency(dep); - /** @type {BuildInfo} */ - (module.buildInfo).moduleConcatenationBailout = "Hot Module Replacement"; - if (expr.arguments.length === 1) { - const arg = parser.evaluateExpression(expr.arguments[0]); - /** @type {BasicEvaluatedExpression[]} */ - let params = []; - if (arg.isString()) { - params = [arg]; - } else if (arg.isArray()) { - params = - /** @type {BasicEvaluatedExpression[]} */ - (arg.items).filter(param => param.isString()); - } - for (const [idx, param] of params.entries()) { - const dep = new ParamDependency( - /** @type {string} */ (param.string), - /** @type {Range} */ (param.range) - ); - dep.optional = true; - dep.loc = Object.create(/** @type {DependencyLocation} */ (expr.loc)); - dep.loc.index = idx; - module.addDependency(dep); - } - } - return true; - }; - - /** - * @param {JavascriptParser} parser the parser - * @returns {(expr: Expression) => boolean | undefined} callback - */ - const createHMRExpressionHandler = parser => expr => { - const module = parser.state.module; - const dep = new ConstDependency( - `${module.moduleArgument}.hot`, - /** @type {Range} */ (expr.range), - runtimeRequirements - ); - dep.loc = /** @type {DependencyLocation} */ (expr.loc); - module.addPresentationalDependency(dep); - /** @type {BuildInfo} */ - (module.buildInfo).moduleConcatenationBailout = "Hot Module Replacement"; - return true; - }; - - /** - * @param {JavascriptParser} parser the parser - * @returns {void} - */ - const applyModuleHot = parser => { - parser.hooks.evaluateIdentifier.for("module.hot").tap( - { - name: PLUGIN_NAME, - before: "NodeStuffPlugin" - }, - expr => - evaluateToIdentifier( - "module.hot", - "module", - () => ["hot"], - true - )(expr) - ); - parser.hooks.call - .for("module.hot.accept") - .tap( - PLUGIN_NAME, - createAcceptHandler(parser, ModuleHotAcceptDependency) - ); - parser.hooks.call - .for("module.hot.decline") - .tap( - PLUGIN_NAME, - createDeclineHandler(parser, ModuleHotDeclineDependency) - ); - parser.hooks.expression - .for("module.hot") - .tap(PLUGIN_NAME, createHMRExpressionHandler(parser)); - }; - - /** - * @param {JavascriptParser} parser the parser - * @returns {void} - */ - const applyImportMetaHot = parser => { - parser.hooks.evaluateIdentifier - .for("import.meta.webpackHot") - .tap(PLUGIN_NAME, expr => - evaluateToIdentifier( - "import.meta.webpackHot", - "import.meta", - () => ["webpackHot"], - true - )(expr) - ); - parser.hooks.call - .for("import.meta.webpackHot.accept") - .tap( - PLUGIN_NAME, - createAcceptHandler(parser, ImportMetaHotAcceptDependency) - ); - parser.hooks.call - .for("import.meta.webpackHot.decline") - .tap( - PLUGIN_NAME, - createDeclineHandler(parser, ImportMetaHotDeclineDependency) - ); - parser.hooks.expression - .for("import.meta.webpackHot") - .tap(PLUGIN_NAME, createHMRExpressionHandler(parser)); - }; - - compiler.hooks.compilation.tap( - PLUGIN_NAME, - (compilation, { normalModuleFactory }) => { - // This applies the HMR plugin only to the targeted compiler - // It should not affect child compilations - if (compilation.compiler !== compiler) return; - - // #region module.hot.* API - compilation.dependencyFactories.set( - ModuleHotAcceptDependency, - normalModuleFactory - ); - compilation.dependencyTemplates.set( - ModuleHotAcceptDependency, - new ModuleHotAcceptDependency.Template() - ); - compilation.dependencyFactories.set( - ModuleHotDeclineDependency, - normalModuleFactory - ); - compilation.dependencyTemplates.set( - ModuleHotDeclineDependency, - new ModuleHotDeclineDependency.Template() - ); - // #endregion - - // #region import.meta.webpackHot.* 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 - - let hotIndex = 0; - /** @type {Record<string, string>} */ - const fullHashChunkModuleHashes = {}; - /** @type {Record<string, string>} */ - const chunkModuleHashes = {}; - - compilation.hooks.record.tap(PLUGIN_NAME, (compilation, records) => { - if (records.hash === compilation.hash) return; - const chunkGraph = compilation.chunkGraph; - records.hash = compilation.hash; - records.hotIndex = hotIndex; - records.fullHashChunkModuleHashes = fullHashChunkModuleHashes; - records.chunkModuleHashes = chunkModuleHashes; - records.chunkHashes = {}; - records.chunkRuntime = {}; - for (const chunk of compilation.chunks) { - const chunkId = /** @type {ChunkId} */ (chunk.id); - records.chunkHashes[chunkId] = chunk.hash; - records.chunkRuntime[chunkId] = getRuntimeKey(chunk.runtime); - } - records.chunkModuleIds = {}; - for (const chunk of compilation.chunks) { - records.chunkModuleIds[/** @type {ChunkId} */ (chunk.id)] = - Array.from( - chunkGraph.getOrderedChunkModulesIterable( - chunk, - compareModulesById(chunkGraph) - ), - m => chunkGraph.getModuleId(m) - ); - } - }); - /** @type {TupleSet<[Module, Chunk]>} */ - const updatedModules = new TupleSet(); - /** @type {TupleSet<[Module, Chunk]>} */ - const fullHashModules = new TupleSet(); - /** @type {TupleSet<[Module, RuntimeSpec]>} */ - const nonCodeGeneratedModules = new TupleSet(); - compilation.hooks.fullHash.tap(PLUGIN_NAME, hash => { - const chunkGraph = compilation.chunkGraph; - const records = compilation.records; - for (const chunk of compilation.chunks) { - /** - * @param {Module} module module - * @returns {string} module hash - */ - const getModuleHash = module => { - if ( - compilation.codeGenerationResults.has(module, chunk.runtime) - ) { - return compilation.codeGenerationResults.getHash( - module, - chunk.runtime - ); - } - nonCodeGeneratedModules.add(module, chunk.runtime); - return chunkGraph.getModuleHash(module, chunk.runtime); - }; - const fullHashModulesInThisChunk = - chunkGraph.getChunkFullHashModulesSet(chunk); - if (fullHashModulesInThisChunk !== undefined) { - for (const module of fullHashModulesInThisChunk) { - fullHashModules.add(module, chunk); - } - } - const modules = chunkGraph.getChunkModulesIterable(chunk); - if (modules !== undefined) { - if (records.chunkModuleHashes) { - if (fullHashModulesInThisChunk !== undefined) { - for (const module of modules) { - const key = `${chunk.id}|${module.identifier()}`; - const hash = getModuleHash(module); - if ( - fullHashModulesInThisChunk.has( - /** @type {RuntimeModule} */ (module) - ) - ) { - if (records.fullHashChunkModuleHashes[key] !== hash) { - updatedModules.add(module, chunk); - } - fullHashChunkModuleHashes[key] = hash; - } else { - if (records.chunkModuleHashes[key] !== hash) { - updatedModules.add(module, chunk); - } - chunkModuleHashes[key] = hash; - } - } - } else { - for (const module of modules) { - const key = `${chunk.id}|${module.identifier()}`; - const hash = getModuleHash(module); - if (records.chunkModuleHashes[key] !== hash) { - updatedModules.add(module, chunk); - } - chunkModuleHashes[key] = hash; - } - } - } else if (fullHashModulesInThisChunk !== undefined) { - for (const module of modules) { - const key = `${chunk.id}|${module.identifier()}`; - const hash = getModuleHash(module); - if ( - fullHashModulesInThisChunk.has( - /** @type {RuntimeModule} */ (module) - ) - ) { - fullHashChunkModuleHashes[key] = hash; - } else { - chunkModuleHashes[key] = hash; - } - } - } else { - for (const module of modules) { - const key = `${chunk.id}|${module.identifier()}`; - const hash = getModuleHash(module); - chunkModuleHashes[key] = hash; - } - } - } - } - - hotIndex = records.hotIndex || 0; - if (updatedModules.size > 0) hotIndex++; - - hash.update(`${hotIndex}`); - }); - compilation.hooks.processAssets.tap( - { - name: PLUGIN_NAME, - stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL - }, - () => { - const chunkGraph = compilation.chunkGraph; - const records = compilation.records; - if (records.hash === compilation.hash) return; - if ( - !records.chunkModuleHashes || - !records.chunkHashes || - !records.chunkModuleIds - ) { - return; - } - for (const [module, chunk] of fullHashModules) { - const key = `${chunk.id}|${module.identifier()}`; - const hash = nonCodeGeneratedModules.has(module, chunk.runtime) - ? chunkGraph.getModuleHash(module, chunk.runtime) - : compilation.codeGenerationResults.getHash( - module, - chunk.runtime - ); - if (records.chunkModuleHashes[key] !== hash) { - updatedModules.add(module, chunk); - } - chunkModuleHashes[key] = hash; - } - - /** @type {HotUpdateMainContentByRuntime} */ - const hotUpdateMainContentByRuntime = new Map(); - let allOldRuntime; - for (const key of Object.keys(records.chunkRuntime)) { - const runtime = keyToRuntime(records.chunkRuntime[key]); - allOldRuntime = mergeRuntimeOwned(allOldRuntime, runtime); - } - forEachRuntime(allOldRuntime, runtime => { - const { path: filename, info: assetInfo } = - compilation.getPathWithInfo( - /** @type {NonNullable<OutputNormalized["hotUpdateMainFilename"]>} */ - (compilation.outputOptions.hotUpdateMainFilename), - { - hash: records.hash, - runtime - } - ); - hotUpdateMainContentByRuntime.set( - /** @type {string} */ (runtime), - { - updatedChunkIds: new Set(), - removedChunkIds: new Set(), - removedModules: new Set(), - filename, - assetInfo - } - ); - }); - if (hotUpdateMainContentByRuntime.size === 0) return; - - // Create a list of all active modules to verify which modules are removed completely - /** @type {Map<number|string, Module>} */ - const allModules = new Map(); - for (const module of compilation.modules) { - const id = - /** @type {ModuleId} */ - (chunkGraph.getModuleId(module)); - allModules.set(id, module); - } - - // List of completely removed modules - /** @type {Set<string | number>} */ - const completelyRemovedModules = new Set(); - - for (const key of Object.keys(records.chunkHashes)) { - const oldRuntime = keyToRuntime(records.chunkRuntime[key]); - /** @type {Module[]} */ - const remainingModules = []; - // Check which modules are removed - for (const id of records.chunkModuleIds[key]) { - const module = allModules.get(id); - if (module === undefined) { - completelyRemovedModules.add(id); - } else { - remainingModules.push(module); - } - } - - /** @type {ChunkId | null} */ - let chunkId; - let newModules; - let newRuntimeModules; - let newFullHashModules; - let newDependentHashModules; - let newRuntime; - let removedFromRuntime; - const currentChunk = find( - compilation.chunks, - chunk => `${chunk.id}` === key - ); - if (currentChunk) { - chunkId = currentChunk.id; - newRuntime = intersectRuntime( - currentChunk.runtime, - allOldRuntime - ); - if (newRuntime === undefined) continue; - newModules = chunkGraph - .getChunkModules(currentChunk) - .filter(module => updatedModules.has(module, currentChunk)); - newRuntimeModules = Array.from( - chunkGraph.getChunkRuntimeModulesIterable(currentChunk) - ).filter(module => updatedModules.has(module, currentChunk)); - const fullHashModules = - chunkGraph.getChunkFullHashModulesIterable(currentChunk); - newFullHashModules = - fullHashModules && - Array.from(fullHashModules).filter(module => - updatedModules.has(module, currentChunk) - ); - const dependentHashModules = - chunkGraph.getChunkDependentHashModulesIterable(currentChunk); - newDependentHashModules = - dependentHashModules && - Array.from(dependentHashModules).filter(module => - updatedModules.has(module, currentChunk) - ); - removedFromRuntime = subtractRuntime(oldRuntime, newRuntime); - } else { - // chunk has completely removed - chunkId = `${Number(key)}` === key ? Number(key) : key; - removedFromRuntime = oldRuntime; - newRuntime = oldRuntime; - } - if (removedFromRuntime) { - // chunk was removed from some runtimes - forEachRuntime(removedFromRuntime, runtime => { - const item = - /** @type {HotUpdateMainContentByRuntimeItem} */ - ( - hotUpdateMainContentByRuntime.get( - /** @type {string} */ (runtime) - ) - ); - item.removedChunkIds.add(/** @type {ChunkId} */ (chunkId)); - }); - // dispose modules from the chunk in these runtimes - // where they are no longer in this runtime - for (const module of remainingModules) { - const moduleKey = `${key}|${module.identifier()}`; - const oldHash = records.chunkModuleHashes[moduleKey]; - const runtimes = chunkGraph.getModuleRuntimes(module); - if (oldRuntime === newRuntime && runtimes.has(newRuntime)) { - // Module is still in the same runtime combination - const hash = nonCodeGeneratedModules.has(module, newRuntime) - ? chunkGraph.getModuleHash(module, newRuntime) - : compilation.codeGenerationResults.getHash( - module, - newRuntime - ); - if (hash !== oldHash) { - if (module.type === WEBPACK_MODULE_TYPE_RUNTIME) { - newRuntimeModules = newRuntimeModules || []; - newRuntimeModules.push( - /** @type {RuntimeModule} */ (module) - ); - } else { - newModules = newModules || []; - newModules.push(module); - } - } - } else { - // module is no longer in this runtime combination - // We (incorrectly) assume that it's not in an overlapping runtime combination - // and dispose it from the main runtimes the chunk was removed from - forEachRuntime(removedFromRuntime, runtime => { - // If the module is still used in this runtime, do not dispose it - // This could create a bad runtime state where the module is still loaded, - // but no chunk which contains it. This means we don't receive further HMR updates - // to this module and that's bad. - // TODO force load one of the chunks which contains the module - for (const moduleRuntime of runtimes) { - if (typeof moduleRuntime === "string") { - if (moduleRuntime === runtime) return; - } else if ( - moduleRuntime !== undefined && - moduleRuntime.has(/** @type {string} */ (runtime)) - ) - return; - } - const item = - /** @type {HotUpdateMainContentByRuntimeItem} */ ( - hotUpdateMainContentByRuntime.get( - /** @type {string} */ (runtime) - ) - ); - item.removedModules.add(module); - }); - } - } - } - if ( - (newModules && newModules.length > 0) || - (newRuntimeModules && newRuntimeModules.length > 0) - ) { - const hotUpdateChunk = new HotUpdateChunk(); - if (backCompat) - ChunkGraph.setChunkGraphForChunk(hotUpdateChunk, chunkGraph); - hotUpdateChunk.id = chunkId; - hotUpdateChunk.runtime = newRuntime; - if (currentChunk) { - for (const group of currentChunk.groupsIterable) - hotUpdateChunk.addGroup(group); - } - chunkGraph.attachModules(hotUpdateChunk, newModules || []); - chunkGraph.attachRuntimeModules( - hotUpdateChunk, - newRuntimeModules || [] - ); - if (newFullHashModules) { - chunkGraph.attachFullHashModules( - hotUpdateChunk, - newFullHashModules - ); - } - if (newDependentHashModules) { - chunkGraph.attachDependentHashModules( - hotUpdateChunk, - newDependentHashModules - ); - } - const renderManifest = compilation.getRenderManifest({ - chunk: hotUpdateChunk, - hash: records.hash, - fullHash: records.hash, - outputOptions: compilation.outputOptions, - moduleTemplates: compilation.moduleTemplates, - dependencyTemplates: compilation.dependencyTemplates, - codeGenerationResults: compilation.codeGenerationResults, - runtimeTemplate: compilation.runtimeTemplate, - moduleGraph: compilation.moduleGraph, - chunkGraph - }); - for (const entry of renderManifest) { - /** @type {string} */ - let filename; - /** @type {AssetInfo} */ - let assetInfo; - if ("filename" in entry) { - filename = entry.filename; - assetInfo = entry.info; - } else { - ({ path: filename, info: assetInfo } = - compilation.getPathWithInfo( - entry.filenameTemplate, - entry.pathOptions - )); - } - const source = entry.render(); - compilation.additionalChunkAssets.push(filename); - compilation.emitAsset(filename, source, { - hotModuleReplacement: true, - ...assetInfo - }); - if (currentChunk) { - currentChunk.files.add(filename); - compilation.hooks.chunkAsset.call(currentChunk, filename); - } - } - forEachRuntime(newRuntime, runtime => { - const item = - /** @type {HotUpdateMainContentByRuntimeItem} */ ( - hotUpdateMainContentByRuntime.get( - /** @type {string} */ (runtime) - ) - ); - item.updatedChunkIds.add(/** @type {ChunkId} */ (chunkId)); - }); - } - } - const completelyRemovedModulesArray = Array.from( - completelyRemovedModules - ); - const hotUpdateMainContentByFilename = new Map(); - for (const { - removedChunkIds, - removedModules, - updatedChunkIds, - filename, - assetInfo - } of hotUpdateMainContentByRuntime.values()) { - const old = hotUpdateMainContentByFilename.get(filename); - if ( - old && - (!isSubset(old.removedChunkIds, removedChunkIds) || - !isSubset(old.removedModules, removedModules) || - !isSubset(old.updatedChunkIds, updatedChunkIds)) - ) { - compilation.warnings.push( - new WebpackError(`HotModuleReplacementPlugin -The configured output.hotUpdateMainFilename doesn't lead to unique filenames per runtime and HMR update differs between runtimes. -This might lead to incorrect runtime behavior of the applied update. -To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename option, or use the default config.`) - ); - for (const chunkId of removedChunkIds) - old.removedChunkIds.add(chunkId); - for (const chunkId of removedModules) - old.removedModules.add(chunkId); - for (const chunkId of updatedChunkIds) - old.updatedChunkIds.add(chunkId); - continue; - } - hotUpdateMainContentByFilename.set(filename, { - removedChunkIds, - removedModules, - updatedChunkIds, - assetInfo - }); - } - for (const [ - filename, - { removedChunkIds, removedModules, updatedChunkIds, assetInfo } - ] of hotUpdateMainContentByFilename) { - const hotUpdateMainJson = { - c: Array.from(updatedChunkIds), - r: Array.from(removedChunkIds), - m: - removedModules.size === 0 - ? completelyRemovedModulesArray - : completelyRemovedModulesArray.concat( - Array.from( - removedModules, - m => - /** @type {ModuleId} */ (chunkGraph.getModuleId(m)) - ) - ) - }; - - const source = new RawSource(JSON.stringify(hotUpdateMainJson)); - compilation.emitAsset(filename, source, { - hotModuleReplacement: true, - ...assetInfo - }); - } - } - ); - - compilation.hooks.additionalTreeRuntimeRequirements.tap( - PLUGIN_NAME, - (chunk, runtimeRequirements) => { - runtimeRequirements.add(RuntimeGlobals.hmrDownloadManifest); - runtimeRequirements.add(RuntimeGlobals.hmrDownloadUpdateHandlers); - runtimeRequirements.add(RuntimeGlobals.interceptModuleExecution); - runtimeRequirements.add(RuntimeGlobals.moduleCache); - compilation.addRuntimeModule( - chunk, - new HotModuleReplacementRuntimeModule() - ); - } - ); - - normalModuleFactory.hooks.parser - .for(JAVASCRIPT_MODULE_TYPE_AUTO) - .tap(PLUGIN_NAME, parser => { - applyModuleHot(parser); - applyImportMetaHot(parser); - }); - normalModuleFactory.hooks.parser - .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) - .tap(PLUGIN_NAME, parser => { - applyModuleHot(parser); - }); - normalModuleFactory.hooks.parser - .for(JAVASCRIPT_MODULE_TYPE_ESM) - .tap(PLUGIN_NAME, parser => { - applyImportMetaHot(parser); - }); - - NormalModule.getCompilationHooks(compilation).loader.tap( - PLUGIN_NAME, - context => { - context.hot = true; - } - ); - } - ); - } -} - -module.exports = HotModuleReplacementPlugin; |
