mirror of https://github.com/webpack/webpack.git
allow to merge multiple hmr updates which calling hot.check while previous update is ready
This commit is contained in:
parent
3dbbdcb28c
commit
1266d76956
|
@ -276,6 +276,7 @@ const { isSourceEqual } = require("./util/source");
|
|||
* @typedef {Object} PathData
|
||||
* @property {ChunkGraph=} chunkGraph
|
||||
* @property {string=} hash
|
||||
* @property {string=} index
|
||||
* @property {function(number): string=} hashWithLength
|
||||
* @property {(Chunk|ChunkPathData)=} chunk
|
||||
* @property {(Module|ModulePathData)=} module
|
||||
|
@ -831,7 +832,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
/** @type {SyncHook<[Chunk, string]>} */
|
||||
chunkAsset: new SyncHook(["chunk", "filename"]),
|
||||
|
||||
/** @type {SyncWaterfallHook<[string, object, AssetInfo]>} */
|
||||
/** @type {SyncWaterfallHook<[string, PathData, AssetInfo]>} */
|
||||
assetPath: new SyncWaterfallHook(["path", "options", "assetInfo"]),
|
||||
|
||||
/** @type {SyncBailHook<[], boolean>} */
|
||||
|
@ -996,6 +997,12 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
/** @private @type {Map<string, Module>} */
|
||||
this._modules = new Map();
|
||||
this.records = null;
|
||||
/** @type {string | undefined} */
|
||||
this.hash = undefined;
|
||||
/** @type {string | undefined} */
|
||||
this.fullHash = undefined;
|
||||
/** @type {number | undefined} */
|
||||
this.index = undefined;
|
||||
/** @type {string[]} */
|
||||
this.additionalChunkAssets = [];
|
||||
/** @type {CompilationAssets} */
|
||||
|
@ -2781,6 +2788,11 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
ChunkGraph.setChunkGraphForModule(module, chunkGraph);
|
||||
}
|
||||
|
||||
this.index =
|
||||
this.records && this.records.index !== undefined
|
||||
? this.records.index + 1
|
||||
: 0;
|
||||
|
||||
this.hooks.seal.call();
|
||||
|
||||
this.logger.time("optimize dependencies");
|
||||
|
@ -3056,6 +3068,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
|
||||
this.summarizeDependencies();
|
||||
if (shouldRecord) {
|
||||
this.records.index = this.index;
|
||||
this.hooks.record.call(this, this.records);
|
||||
}
|
||||
|
||||
|
@ -4442,6 +4455,7 @@ This prevents using hashes of each other and should be avoided.`);
|
|||
try {
|
||||
manifest = this.getRenderManifest({
|
||||
chunk,
|
||||
index: `${this.index}`,
|
||||
hash: this.hash,
|
||||
fullHash: this.fullHash,
|
||||
outputOptions,
|
||||
|
@ -4586,9 +4600,10 @@ This prevents using hashes of each other and should be avoided.`);
|
|||
* @returns {string} interpolated path
|
||||
*/
|
||||
getPath(filename, data = {}) {
|
||||
if (!data.hash) {
|
||||
if (!data.hash || !data.index) {
|
||||
data = {
|
||||
hash: this.hash,
|
||||
index: `${this.index}`,
|
||||
...data
|
||||
};
|
||||
}
|
||||
|
@ -4601,9 +4616,10 @@ This prevents using hashes of each other and should be avoided.`);
|
|||
* @returns {{ path: string, info: AssetInfo }} interpolated path and asset info
|
||||
*/
|
||||
getPathWithInfo(filename, data = {}) {
|
||||
if (!data.hash) {
|
||||
if (!data.hash || !data.index) {
|
||||
data = {
|
||||
hash: this.hash,
|
||||
index: `${this.index}`,
|
||||
...data
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ const JavascriptParser = require("./javascript/JavascriptParser");
|
|||
const {
|
||||
evaluateToIdentifier
|
||||
} = require("./javascript/JavascriptParserHelpers");
|
||||
const CompilationIndexRuntimeModule = require("./runtime/CompilationIndexRuntimeModule");
|
||||
const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule");
|
||||
const { find, isSubset } = require("./util/SetHelpers");
|
||||
const TupleSet = require("./util/TupleSet");
|
||||
const { compareModulesById } = require("./util/comparators");
|
||||
|
@ -48,6 +50,10 @@ const {
|
|||
* @property {SyncBailHook<[TODO, string[]], void>} hotAcceptWithoutCallback
|
||||
*/
|
||||
|
||||
const isOutOfBandModule = module =>
|
||||
module instanceof CompilationIndexRuntimeModule ||
|
||||
module instanceof GetFullHashRuntimeModule;
|
||||
|
||||
/** @type {WeakMap<JavascriptParser, HMRJavascriptParserHooks>} */
|
||||
const parserHooksMap = new WeakMap();
|
||||
|
||||
|
@ -342,6 +348,7 @@ class HotModuleReplacementPlugin {
|
|||
chunkGraph.getChunkFullHashModulesSet(chunk);
|
||||
if (fullHashModulesInThisChunk !== undefined) {
|
||||
for (const module of fullHashModulesInThisChunk) {
|
||||
if (isOutOfBandModule(module)) continue;
|
||||
fullHashModules.add(module, chunk);
|
||||
}
|
||||
}
|
||||
|
@ -350,6 +357,7 @@ class HotModuleReplacementPlugin {
|
|||
if (records.chunkModuleHashes) {
|
||||
if (fullHashModulesInThisChunk !== undefined) {
|
||||
for (const module of modules) {
|
||||
if (isOutOfBandModule(module)) continue;
|
||||
const key = `${chunk.id}|${module.identifier()}`;
|
||||
const hash = getModuleHash(module);
|
||||
if (
|
||||
|
@ -370,6 +378,7 @@ class HotModuleReplacementPlugin {
|
|||
}
|
||||
} else {
|
||||
for (const module of modules) {
|
||||
if (isOutOfBandModule(module)) continue;
|
||||
const key = `${chunk.id}|${module.identifier()}`;
|
||||
const hash = getModuleHash(module);
|
||||
if (records.chunkModuleHashes[key] !== hash) {
|
||||
|
@ -381,6 +390,7 @@ class HotModuleReplacementPlugin {
|
|||
} else {
|
||||
if (fullHashModulesInThisChunk !== undefined) {
|
||||
for (const module of modules) {
|
||||
if (isOutOfBandModule(module)) continue;
|
||||
const key = `${chunk.id}|${module.identifier()}`;
|
||||
const hash = getModuleHash(module);
|
||||
if (
|
||||
|
@ -452,6 +462,7 @@ class HotModuleReplacementPlugin {
|
|||
compilation.outputOptions.hotUpdateMainFilename,
|
||||
{
|
||||
hash: records.hash,
|
||||
index: `${records.index}`,
|
||||
runtime
|
||||
}
|
||||
);
|
||||
|
@ -625,6 +636,7 @@ class HotModuleReplacementPlugin {
|
|||
chunk: hotUpdateChunk,
|
||||
hash: records.hash,
|
||||
fullHash: records.hash,
|
||||
index: `${records.index}`,
|
||||
outputOptions: compilation.outputOptions,
|
||||
moduleTemplates: compilation.moduleTemplates,
|
||||
dependencyTemplates: compilation.dependencyTemplates,
|
||||
|
@ -710,6 +722,8 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename
|
|||
{ removedChunkIds, removedModules, updatedChunkIds, assetInfo }
|
||||
] of hotUpdateMainContentByFilename) {
|
||||
const hotUpdateMainJson = {
|
||||
n: compilation.index,
|
||||
h: compilation.hash,
|
||||
c: Array.from(updatedChunkIds),
|
||||
r: Array.from(removedChunkIds),
|
||||
m:
|
||||
|
|
|
@ -140,6 +140,11 @@ exports.nodeModuleDecorator = "__webpack_require__.nmd";
|
|||
*/
|
||||
exports.getFullHash = "__webpack_require__.h";
|
||||
|
||||
/**
|
||||
* the compilation index
|
||||
*/
|
||||
exports.compilationIndex = "__webpack_require__.N";
|
||||
|
||||
/**
|
||||
* an object containing all installed WebAssembly.Instance export objects keyed by module id
|
||||
*/
|
||||
|
|
|
@ -12,6 +12,7 @@ const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
|
|||
const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule");
|
||||
const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
|
||||
const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
|
||||
const CompilationIndexRuntimeModule = require("./runtime/CompilationIndexRuntimeModule");
|
||||
const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule");
|
||||
const CreateScriptUrlRuntimeModule = require("./runtime/CreateScriptUrlRuntimeModule");
|
||||
const DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule");
|
||||
|
@ -44,6 +45,7 @@ const GLOBALS_ON_REQUIRE = [
|
|||
RuntimeGlobals.ensureChunk,
|
||||
RuntimeGlobals.entryModuleId,
|
||||
RuntimeGlobals.getFullHash,
|
||||
RuntimeGlobals.compilationIndex,
|
||||
RuntimeGlobals.global,
|
||||
RuntimeGlobals.makeNamespaceObject,
|
||||
RuntimeGlobals.moduleCache,
|
||||
|
@ -84,6 +86,16 @@ const TREE_DEPENDENCIES = {
|
|||
[RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty]
|
||||
};
|
||||
|
||||
const handleRuntimeModuleAssetPath = (assetPath, runtimeRequirements) => {
|
||||
if (typeof assetPath !== "string") return;
|
||||
if (/\[(full)?hash(:\d+)?\]/.test(assetPath)) {
|
||||
runtimeRequirements.add(RuntimeGlobals.getFullHash);
|
||||
}
|
||||
if (/\[index\]/.test(assetPath)) {
|
||||
runtimeRequirements.add(RuntimeGlobals.compilationIndex);
|
||||
}
|
||||
};
|
||||
|
||||
class RuntimePlugin {
|
||||
/**
|
||||
* @param {Compiler} compiler the Compiler
|
||||
|
@ -203,6 +215,15 @@ class RuntimePlugin {
|
|||
}
|
||||
return true;
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.compilationIndex)
|
||||
.tap("RuntimePlugin", chunk => {
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new CompilationIndexRuntimeModule(compilation.index)
|
||||
);
|
||||
return true;
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.global)
|
||||
.tap("RuntimePlugin", chunk => {
|
||||
|
@ -229,14 +250,10 @@ class RuntimePlugin {
|
|||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.getChunkScriptFilename)
|
||||
.tap("RuntimePlugin", (chunk, set) => {
|
||||
if (
|
||||
typeof compilation.outputOptions.chunkFilename === "string" &&
|
||||
/\[(full)?hash(:\d+)?\]/.test(
|
||||
compilation.outputOptions.chunkFilename
|
||||
)
|
||||
) {
|
||||
set.add(RuntimeGlobals.getFullHash);
|
||||
}
|
||||
handleRuntimeModuleAssetPath(
|
||||
compilation.outputOptions.chunkFilename,
|
||||
set
|
||||
);
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new GetChunkFilenameRuntimeModule(
|
||||
|
@ -256,12 +273,10 @@ class RuntimePlugin {
|
|||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.getChunkUpdateScriptFilename)
|
||||
.tap("RuntimePlugin", (chunk, set) => {
|
||||
if (
|
||||
/\[(full)?hash(:\d+)?\]/.test(
|
||||
compilation.outputOptions.hotUpdateChunkFilename
|
||||
)
|
||||
)
|
||||
set.add(RuntimeGlobals.getFullHash);
|
||||
handleRuntimeModuleAssetPath(
|
||||
compilation.outputOptions.hotUpdateChunkFilename,
|
||||
set
|
||||
);
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new GetChunkFilenameRuntimeModule(
|
||||
|
@ -277,13 +292,10 @@ class RuntimePlugin {
|
|||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.getUpdateManifestFilename)
|
||||
.tap("RuntimePlugin", (chunk, set) => {
|
||||
if (
|
||||
/\[(full)?hash(:\d+)?\]/.test(
|
||||
compilation.outputOptions.hotUpdateMainFilename
|
||||
)
|
||||
) {
|
||||
set.add(RuntimeGlobals.getFullHash);
|
||||
}
|
||||
handleRuntimeModuleAssetPath(
|
||||
compilation.outputOptions.hotUpdateMainFilename,
|
||||
set
|
||||
);
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new GetMainFilenameRuntimeModule(
|
||||
|
|
|
@ -41,6 +41,7 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
|
|||
/**
|
||||
* @typedef {Object} RenderManifestOptions
|
||||
* @property {Chunk} chunk the chunk used to render
|
||||
* @property {string} index
|
||||
* @property {string} hash
|
||||
* @property {string} fullHash
|
||||
* @property {OutputOptions} outputOptions
|
||||
|
|
|
@ -147,6 +147,7 @@ const replacePathVariables = (path, data, assetInfo) => {
|
|||
// Placeholders
|
||||
//
|
||||
// [fullhash] - data.hash (3a4b5c6e7f)
|
||||
// [index] - data.index (14)
|
||||
//
|
||||
// Legacy Placeholders
|
||||
//
|
||||
|
@ -171,6 +172,9 @@ const replacePathVariables = (path, data, assetInfo) => {
|
|||
)
|
||||
);
|
||||
}
|
||||
if (data.index) {
|
||||
replacements.set("index", replacer(data.index));
|
||||
}
|
||||
|
||||
// Chunk Context
|
||||
//
|
||||
|
|
|
@ -808,9 +808,17 @@ const applyOutputDefaults = (
|
|||
D(
|
||||
output,
|
||||
"hotUpdateChunkFilename",
|
||||
`[id].[fullhash].hot-update.${output.module ? "mjs" : "js"}`
|
||||
futureDefaults
|
||||
? `[id].[index].hot-update.${output.module ? "mjs" : "js"}`
|
||||
: `[id].[fullhash].hot-update.${output.module ? "mjs" : "js"}`
|
||||
);
|
||||
D(
|
||||
output,
|
||||
"hotUpdateMainFilename",
|
||||
futureDefaults
|
||||
? "[runtime].[index].hot-update.json"
|
||||
: "[runtime].[fullhash].hot-update.json"
|
||||
);
|
||||
D(output, "hotUpdateMainFilename", "[runtime].[fullhash].hot-update.json");
|
||||
D(output, "crossOriginLoading", false);
|
||||
F(output, "scriptType", () => (output.module ? "module" : false));
|
||||
D(
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
var $interceptModuleExecution$ = undefined;
|
||||
var $moduleCache$ = undefined;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var $getFullHash$ = undefined;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var $compilationIndex$ = undefined;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var $hmrModuleData$ = undefined;
|
||||
/** @type {() => Promise} */
|
||||
var $hmrDownloadManifest$ = undefined;
|
||||
|
@ -26,12 +30,15 @@ module.exports = function () {
|
|||
// status
|
||||
var registeredStatusHandlers = [];
|
||||
var currentStatus = "idle";
|
||||
var additionalUpdate = false;
|
||||
|
||||
// while downloading
|
||||
var blockingPromises;
|
||||
|
||||
// The update info
|
||||
var currentUpdateApplyHandlers;
|
||||
var currentUpdateCompilationIndex;
|
||||
var currentUpdateCompilationHash;
|
||||
var queuedInvalidatedModules;
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
@ -200,6 +207,12 @@ module.exports = function () {
|
|||
var idx = registeredStatusHandlers.indexOf(l);
|
||||
if (idx >= 0) registeredStatusHandlers.splice(idx, 1);
|
||||
},
|
||||
getUpdateIndex: function () {
|
||||
return currentUpdateCompilationIndex;
|
||||
},
|
||||
getUpdateHash: function () {
|
||||
return currentUpdateCompilationHash;
|
||||
},
|
||||
|
||||
//inherit from previous dispose call
|
||||
data: currentModuleData[moduleId]
|
||||
|
@ -230,6 +243,9 @@ module.exports = function () {
|
|||
case "prepare":
|
||||
blockingPromises.push(promise);
|
||||
return promise;
|
||||
case "check":
|
||||
if (additionalUpdate) blockingPromises.push(promise);
|
||||
return promise;
|
||||
default:
|
||||
return promise;
|
||||
}
|
||||
|
@ -244,25 +260,51 @@ module.exports = function () {
|
|||
});
|
||||
}
|
||||
|
||||
function hotCheck(applyOnUpdate) {
|
||||
if (currentStatus !== "idle") {
|
||||
throw new Error("check() is only allowed in idle status");
|
||||
function applyOutOfBandInfo() {
|
||||
if (currentUpdateCompilationIndex !== undefined) {
|
||||
$compilationIndex$ = currentUpdateCompilationIndex;
|
||||
currentUpdateCompilationIndex = undefined;
|
||||
}
|
||||
if (currentUpdateCompilationHash !== undefined) {
|
||||
var value = currentUpdateCompilationHash;
|
||||
$getFullHash$ = function () {
|
||||
return value;
|
||||
};
|
||||
currentUpdateCompilationHash = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function hotCheck(applyOnUpdate) {
|
||||
if (currentStatus !== "idle" && currentStatus !== "ready") {
|
||||
throw new Error("check() is only allowed in idle or ready status");
|
||||
}
|
||||
additionalUpdate = currentStatus === "ready";
|
||||
// apply outstanding compilation index update to get the new hot update files
|
||||
applyOutOfBandInfo();
|
||||
return setStatus("check")
|
||||
.then($hmrDownloadManifest$)
|
||||
.then(function (update) {
|
||||
if (!update) {
|
||||
return setStatus(applyInvalidatedModules() ? "ready" : "idle").then(
|
||||
return waitForBlockingPromises(function () {
|
||||
additionalUpdate = applyInvalidatedModules() || additionalUpdate;
|
||||
if (additionalUpdate && applyOnUpdate) {
|
||||
return internalApply(applyOnUpdate);
|
||||
} else {
|
||||
return setStatus(additionalUpdate ? "ready" : "idle").then(
|
||||
function () {
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return setStatus("prepare").then(function () {
|
||||
var updatedModules = [];
|
||||
blockingPromises = [];
|
||||
currentUpdateApplyHandlers = [];
|
||||
if (!currentUpdateApplyHandlers) currentUpdateApplyHandlers = [];
|
||||
currentUpdateCompilationIndex = update.n;
|
||||
currentUpdateCompilationHash = update.h;
|
||||
|
||||
return Promise.all(
|
||||
Object.keys($hmrDownloadUpdateHandlers$).reduce(function (
|
||||
|
@ -308,6 +350,7 @@ module.exports = function () {
|
|||
options = options || {};
|
||||
|
||||
applyInvalidatedModules();
|
||||
applyOutOfBandInfo();
|
||||
|
||||
var results = currentUpdateApplyHandlers.map(function (handler) {
|
||||
return handler(options);
|
||||
|
|
|
@ -21,6 +21,7 @@ class HotModuleReplacementRuntimeModule extends RuntimeModule {
|
|||
require("./HotModuleReplacement.runtime.js")
|
||||
)
|
||||
.replace(/\$getFullHash\$/g, RuntimeGlobals.getFullHash)
|
||||
.replace(/\$compilationIndex\$/g, RuntimeGlobals.compilationIndex)
|
||||
.replace(
|
||||
/\$interceptModuleExecution\$/g,
|
||||
RuntimeGlobals.interceptModuleExecution
|
||||
|
|
|
@ -295,6 +295,7 @@ module.exports = function () {
|
|||
for (var i = 0; i < currentUpdateRuntime.length; i++) {
|
||||
currentUpdateRuntime[i](__webpack_require__);
|
||||
}
|
||||
currentUpdateRuntime = undefined;
|
||||
|
||||
// call accept handlers
|
||||
for (var outdatedModuleId in outdatedDependencies) {
|
||||
|
@ -428,14 +429,20 @@ module.exports = function () {
|
|||
applyHandlers,
|
||||
updatedModulesList
|
||||
) {
|
||||
applyHandlers.push(applyHandler);
|
||||
currentUpdateChunks = {};
|
||||
currentUpdateRemovedChunks = removedChunks;
|
||||
currentUpdate = removedModules.reduce(function (obj, key) {
|
||||
obj[key] = false;
|
||||
return obj;
|
||||
}, {});
|
||||
if (!currentUpdate) {
|
||||
currentUpdate = {};
|
||||
currentUpdateRuntime = [];
|
||||
currentUpdateRemovedChunks = [];
|
||||
applyHandlers.push(applyHandler);
|
||||
}
|
||||
currentUpdateChunks = {};
|
||||
currentUpdateRemovedChunks.push.apply(
|
||||
currentUpdateRemovedChunks,
|
||||
removedChunks
|
||||
);
|
||||
removedModules.forEach(function (key) {
|
||||
currentUpdate[key] = false;
|
||||
});
|
||||
chunkIds.forEach(function (chunkId) {
|
||||
if (
|
||||
$hasOwnProperty$($installedChunks$, chunkId) &&
|
||||
|
|
|
@ -231,6 +231,7 @@ class JavascriptModulesPlugin {
|
|||
"JavascriptModulesPlugin",
|
||||
(result, options) => {
|
||||
const {
|
||||
index,
|
||||
hash,
|
||||
chunk,
|
||||
chunkGraph,
|
||||
|
@ -305,6 +306,7 @@ class JavascriptModulesPlugin {
|
|||
filenameTemplate,
|
||||
pathOptions: {
|
||||
hash,
|
||||
index,
|
||||
runtime: chunk.runtime,
|
||||
chunk,
|
||||
contentHashType: "javascript"
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const RuntimeModule = require("../RuntimeModule");
|
||||
|
||||
class CompilationIndexRuntimeModule extends RuntimeModule {
|
||||
/**
|
||||
* @param {number} compilationIndex the compilation index
|
||||
*/
|
||||
constructor(compilationIndex) {
|
||||
super("compilation index");
|
||||
this.compilationIndex = compilationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
return `${RuntimeGlobals.compilationIndex} = ${this.compilationIndex};`;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CompilationIndexRuntimeModule;
|
|
@ -144,6 +144,7 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
|
|||
)
|
||||
: JSON.stringify(chunkFilename);
|
||||
const staticChunkFilename = compilation.getPath(chunkFilenameValue, {
|
||||
index: `" + ${RuntimeGlobals.compilationIndex} + "`,
|
||||
hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
|
||||
hashWithLength: length =>
|
||||
`" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`,
|
||||
|
@ -229,6 +230,7 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
|
|||
const url =
|
||||
dynamicFilename &&
|
||||
compilation.getPath(JSON.stringify(dynamicFilename), {
|
||||
index: `" + ${RuntimeGlobals.compilationIndex} + "`,
|
||||
hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
|
||||
hashWithLength: length =>
|
||||
`" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`,
|
||||
|
|
|
@ -29,6 +29,7 @@ class GetMainFilenameRuntimeModule extends RuntimeModule {
|
|||
const { global, filename, compilation, chunk } = this;
|
||||
const { runtimeTemplate } = compilation;
|
||||
const url = compilation.getPath(JSON.stringify(filename), {
|
||||
index: `" + ${RuntimeGlobals.compilationIndex} + "`,
|
||||
hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
|
||||
hashWithLength: length =>
|
||||
`" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`,
|
||||
|
|
|
@ -26,6 +26,7 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
|
|||
const wasmModuleSrcPath = compilation.getPath(
|
||||
JSON.stringify(outputOptions.webassemblyModuleFilename),
|
||||
{
|
||||
index: `" + ${RuntimeGlobals.compilationIndex} + "`,
|
||||
hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
|
||||
hashWithLength: length =>
|
||||
`" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
|
||||
|
|
|
@ -233,6 +233,7 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
const wasmModuleSrcPath = compilation.getPath(
|
||||
JSON.stringify(outputOptions.webassemblyModuleFilename),
|
||||
{
|
||||
index: `" + ${RuntimeGlobals.compilationIndex} + "`,
|
||||
hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
|
||||
hashWithLength: length =>
|
||||
`" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
|
||||
|
|
|
@ -274,9 +274,8 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
"",
|
||||
withHmr
|
||||
? Template.asString([
|
||||
"var currentUpdatedModulesList;",
|
||||
"var waitingUpdateResolves = {};",
|
||||
"function loadUpdateChunk(chunkId) {",
|
||||
"function loadUpdateChunk(chunkId, updatedModulesList) {",
|
||||
Template.indent([
|
||||
`return new Promise(${runtimeTemplate.basicFunction(
|
||||
"resolve, reject",
|
||||
|
@ -302,6 +301,9 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
])};`,
|
||||
`${RuntimeGlobals.loadScript}(url, loadingEnded);`
|
||||
]
|
||||
)}).then(${runtimeTemplate.basicFunction(
|
||||
"updatedModules",
|
||||
"if(updatedModulesList) updatedModulesList.push.apply(updatedModulesList, updatedModules);"
|
||||
)});`
|
||||
]),
|
||||
"}",
|
||||
|
@ -311,12 +313,13 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
)}] = ${runtimeTemplate.basicFunction(
|
||||
"chunkId, moreModules, runtime",
|
||||
[
|
||||
"var updatedModules = [];",
|
||||
"for(var moduleId in moreModules) {",
|
||||
Template.indent([
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
|
||||
Template.indent([
|
||||
"currentUpdate[moduleId] = moreModules[moduleId];",
|
||||
"if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);"
|
||||
"updatedModules.push(moduleId);"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
|
@ -324,7 +327,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
"if(runtime) currentUpdateRuntime.push(runtime);",
|
||||
"if(waitingUpdateResolves[chunkId]) {",
|
||||
Template.indent([
|
||||
"waitingUpdateResolves[chunkId]();",
|
||||
"waitingUpdateResolves[chunkId](updatedModules);",
|
||||
"waitingUpdateResolves[chunkId] = undefined;"
|
||||
]),
|
||||
"}"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
module.exports = [[/Module parse failed/]];
|
|
@ -0,0 +1,34 @@
|
|||
import value from "./module";
|
||||
import value2 from "./module2";
|
||||
|
||||
import.meta.webpackHot.accept("./module");
|
||||
import.meta.webpackHot.accept("./module2");
|
||||
|
||||
it("should merge multiple updates when not using apply", done => {
|
||||
expect(value).toBe(42);
|
||||
expect(value2).toBe(42);
|
||||
NEXT(err => {
|
||||
if (err) return done(err);
|
||||
NEXT(err => {
|
||||
if (err) return done(err);
|
||||
module.hot
|
||||
.check()
|
||||
.then(updatedModules => {
|
||||
expect(updatedModules).toEqual(["./module.js", "./module2.js"]);
|
||||
return module.hot.check(true).then(updatedModules => {
|
||||
expect(updatedModules).toEqual(["./module.js", "./module2.js"]);
|
||||
try {
|
||||
expect(value).toBe(43);
|
||||
expect(value2).toBe(43);
|
||||
} catch (e) {
|
||||
return done(e);
|
||||
}
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,6 @@
|
|||
export default 42;
|
||||
---
|
||||
throw new Error("Invalid")
|
||||
export default 0;
|
||||
---
|
||||
export default 43
|
|
@ -0,0 +1,6 @@
|
|||
export default 42;
|
||||
---
|
||||
}}}
|
||||
export default 0;
|
||||
---
|
||||
export default 43
|
|
@ -1424,7 +1424,7 @@ declare class Compilation {
|
|||
chunkHash: SyncHook<[Chunk, Hash, ChunkHashContext]>;
|
||||
moduleAsset: SyncHook<[Module, string]>;
|
||||
chunkAsset: SyncHook<[Chunk, string]>;
|
||||
assetPath: SyncWaterfallHook<[string, object, AssetInfo]>;
|
||||
assetPath: SyncWaterfallHook<[string, PathData, AssetInfo]>;
|
||||
needAdditionalPass: SyncBailHook<[], boolean>;
|
||||
childCompiler: SyncHook<[Compiler, string, number]>;
|
||||
log: SyncBailHook<[string, LogEntry], true>;
|
||||
|
@ -1491,6 +1491,9 @@ declare class Compilation {
|
|||
namedChunks: Map<string, Chunk>;
|
||||
modules: Set<Module>;
|
||||
records: any;
|
||||
hash?: string;
|
||||
fullHash?: string;
|
||||
index?: number;
|
||||
additionalChunkAssets: string[];
|
||||
assets: CompilationAssets;
|
||||
assetsInfo: Map<string, AssetInfo>;
|
||||
|
@ -1667,8 +1670,6 @@ declare class Compilation {
|
|||
runtime: RuntimeSpec;
|
||||
runtimes: RuntimeSpec[];
|
||||
}[];
|
||||
fullHash?: string;
|
||||
hash?: string;
|
||||
emitAsset(file: string, source: Source, assetInfo?: AssetInfo): void;
|
||||
updateAsset(
|
||||
file: string,
|
||||
|
@ -8611,6 +8612,7 @@ declare interface ParserStateBase {
|
|||
declare interface PathData {
|
||||
chunkGraph?: ChunkGraph;
|
||||
hash?: string;
|
||||
index?: string;
|
||||
hashWithLength?: (arg0: number) => string;
|
||||
chunk?: Chunk | ChunkPathData;
|
||||
module?: Module | ModulePathData;
|
||||
|
@ -9056,6 +9058,7 @@ declare interface RenderManifestOptions {
|
|||
* the chunk used to render
|
||||
*/
|
||||
chunk: Chunk;
|
||||
index: string;
|
||||
hash: string;
|
||||
fullHash: string;
|
||||
outputOptions: Output;
|
||||
|
@ -11419,7 +11422,7 @@ declare interface UpdateHashContextGenerator {
|
|||
chunkGraph: ChunkGraph;
|
||||
runtime: RuntimeSpec;
|
||||
}
|
||||
type UsageStateType = 0 | 1 | 2 | 3 | 4;
|
||||
type UsageStateType = 0 | 2 | 3 | 1 | 4;
|
||||
declare interface UserResolveOptions {
|
||||
/**
|
||||
* A list of module alias configurations or an object which maps key to value
|
||||
|
@ -12179,6 +12182,7 @@ declare namespace exports {
|
|||
export let harmonyModuleDecorator: string;
|
||||
export let nodeModuleDecorator: string;
|
||||
export let getFullHash: string;
|
||||
export let compilationIndex: string;
|
||||
export let wasmInstances: string;
|
||||
export let instantiateWasm: string;
|
||||
export let uncaughtErrorHandler: string;
|
||||
|
|
Loading…
Reference in New Issue