diff --git a/packages/next/bundles/package.json b/packages/next/bundles/package.json index 3bddca517c73aee..b4a4318824a4559 100644 --- a/packages/next/bundles/package.json +++ b/packages/next/bundles/package.json @@ -2,7 +2,7 @@ "dependencies": { "schema-utils3": "npm:schema-utils@3.0.0", "webpack-sources3": "npm:webpack-sources@3.2.0", - "webpack5": "npm:webpack@5.50.0" + "webpack5": "npm:webpack@5.51.1" }, "resolutions": { "browserslist": "4.16.6", diff --git a/packages/next/bundles/yarn.lock b/packages/next/bundles/yarn.lock index a4ab5e03c870c3e..fd1b9e0e474c191 100644 --- a/packages/next/bundles/yarn.lock +++ b/packages/next/bundles/yarn.lock @@ -475,10 +475,10 @@ watchpack@^2.2.0: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d" integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw== -"webpack5@npm:webpack@5.50.0": - version "5.50.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.50.0.tgz#5562d75902a749eb4d75131f5627eac3a3192527" - integrity sha512-hqxI7t/KVygs0WRv/kTgUW8Kl3YC81uyWQSo/7WUs5LsuRw0htH/fCwbVBGCuiX/t4s7qzjXFcf41O8Reiypag== +"webpack5@npm:webpack@5.51.1": + version "5.51.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.51.1.tgz#41bebf38dccab9a89487b16dbe95c22e147aac57" + integrity sha512-xsn3lwqEKoFvqn4JQggPSRxE4dhsRcysWTqYABAZlmavcoTmwlOb9b1N36Inbt/eIispSkuHa80/FJkDTPos1A== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.50" diff --git a/packages/next/compiled/webpack/bundle5.js b/packages/next/compiled/webpack/bundle5.js index fb446e7b017e190..2b4076303df2124 100644 --- a/packages/next/compiled/webpack/bundle5.js +++ b/packages/next/compiled/webpack/bundle5.js @@ -54,7 +54,7 @@ module.exports = JSON.parse("{\"name\":\"terser\",\"description\":\"JavaScript p /***/ (function(module) { "use strict"; -module.exports = {"i8":"5.50.0"}; +module.exports = {"i8":"5.51.1"}; /***/ }), @@ -44555,13 +44555,15 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si contextInfo, context }, - err => { + (err, result) => { if (err && this.bail) { callback(err); this.buildQueue.stop(); this.rebuildQueue.stop(); this.processDependenciesQueue.stop(); this.factorizeQueue.stop(); + } else if (!err && result) { + callback(null, result); } else { callback(); } @@ -46977,7 +46979,7 @@ This prevents using hashes of each other and should be avoided.`); strictModuleErrorHandling, strictModuleExceptionHandling } = this.outputOptions; - const __nested_webpack_require_129732__ = id => { + const __nested_webpack_require_129804__ = id => { const cached = moduleCache[id]; if (cached !== undefined) { if (cached.error) throw cached.error; @@ -46986,20 +46988,20 @@ This prevents using hashes of each other and should be avoided.`); const moduleArgument = moduleArgumentsById.get(id); return __webpack_require_module__(moduleArgument, id); }; - const interceptModuleExecution = (__nested_webpack_require_129732__[ + const interceptModuleExecution = (__nested_webpack_require_129804__[ RuntimeGlobals.interceptModuleExecution.replace( "__webpack_require__.", "" ) ] = []); - const moduleCache = (__nested_webpack_require_129732__[ + const moduleCache = (__nested_webpack_require_129804__[ RuntimeGlobals.moduleCache.replace( "__webpack_require__.", "" ) ] = {}); - context.__webpack_require__ = __nested_webpack_require_129732__; + context.__webpack_require__ = __nested_webpack_require_129804__; /** * @param {ExecuteModuleArgument} moduleArgument the module argument @@ -47015,7 +47017,7 @@ This prevents using hashes of each other and should be avoided.`); loaded: false, error: undefined }, - require: __nested_webpack_require_129732__ + require: __nested_webpack_require_129804__ }; interceptModuleExecution.forEach(handler => handler(execOptions) @@ -47055,7 +47057,7 @@ This prevents using hashes of each other and should be avoided.`); moduleArgumentsMap.get(runtimeModule) ); } - exports = __nested_webpack_require_129732__(module.identifier()); + exports = __nested_webpack_require_129804__(module.identifier()); } catch (e) { const err = new WebpackError( `Execution of module code from module graph (${module.readableIdentifier( @@ -53634,7 +53636,7 @@ const NormalModule = __webpack_require__(88376); const SourceMapDevToolModuleOptionsPlugin = __webpack_require__(5426); const JavascriptModulesPlugin = __webpack_require__(80867); const ConcatenatedModule = __webpack_require__(74233); -const { absolutify } = __webpack_require__(47779); +const { makePathsAbsolute } = __webpack_require__(47779); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/WebpackOptions").DevTool} DevToolOptions */ @@ -53748,7 +53750,7 @@ class EvalSourceMapDevToolPlugin { const root = compiler.root; const modules = sourceMap.sources.map(source => { if (!source.startsWith("webpack://")) return source; - source = absolutify(context, source.slice(10), root); + source = makePathsAbsolute(context, source.slice(10), root); const module = compilation.findModule(source); return module || source; }); @@ -56448,12 +56450,13 @@ const asyncLib = __webpack_require__(36386); const AsyncQueue = __webpack_require__(51921); const StackedCacheMap = __webpack_require__(12725); const createHash = __webpack_require__(34627); -const { join, dirname, relative } = __webpack_require__(71593); +const { join, dirname, relative, lstatReadlinkAbsolute } = __webpack_require__(71593); const makeSerializable = __webpack_require__(55575); const processAsyncTree = __webpack_require__(71627); /** @typedef {import("./WebpackError")} WebpackError */ /** @typedef {import("./logging/Logger").Logger} Logger */ +/** @typedef {import("./util/fs").IStats} IStats */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ const supportsEsm = +process.versions.modules >= 83; @@ -56479,15 +56482,50 @@ const INVALID = Symbol("invalid"); * @typedef {Object} FileSystemInfoEntry * @property {number} safeTime * @property {number=} timestamp + */ + +/** + * @typedef {Object} ResolvedContextFileSystemInfoEntry + * @property {number} safeTime + * @property {string=} timestampHash + */ + +/** + * @typedef {Object} ContextFileSystemInfoEntry + * @property {number} safeTime * @property {string=} timestampHash + * @property {ResolvedContextFileSystemInfoEntry=} resolved + * @property {Set=} symlinks */ /** * @typedef {Object} TimestampAndHash * @property {number} safeTime * @property {number=} timestamp + * @property {string} hash + */ + +/** + * @typedef {Object} ResolvedContextTimestampAndHash + * @property {number} safeTime + * @property {string=} timestampHash + * @property {string} hash + */ + +/** + * @typedef {Object} ContextTimestampAndHash + * @property {number} safeTime * @property {string=} timestampHash * @property {string} hash + * @property {ResolvedContextTimestampAndHash=} resolved + * @property {Set=} symlinks + */ + +/** + * @typedef {Object} ContextHash + * @property {string} hash + * @property {string=} resolved + * @property {Set=} symlinks */ /** @@ -56613,11 +56651,11 @@ class Snapshot { this.fileHashes = undefined; /** @type {Map | undefined} */ this.fileTshs = undefined; - /** @type {Map | undefined} */ + /** @type {Map | undefined} */ this.contextTimestamps = undefined; /** @type {Map | undefined} */ this.contextHashes = undefined; - /** @type {Map | undefined} */ + /** @type {Map | undefined} */ this.contextTshs = undefined; /** @type {Map | undefined} */ this.missingExistence = undefined; @@ -57209,11 +57247,29 @@ const getManagedItem = (managedPath, path) => { }; /** - * @param {FileSystemInfoEntry} entry file system info entry - * @returns {boolean} existence flag + * @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T + * @param {T | "ignore"} entry entry + * @returns {T["resolved"] | undefined} the resolved entry */ -const toExistence = entry => { - return Boolean(entry); +const getResolvedTimestamp = entry => { + if (entry === "ignore") return undefined; + if (entry === null) return null; + if (entry.resolved !== undefined) return entry.resolved; + return entry.symlinks === undefined ? entry : undefined; +}; + +/** + * @param {ContextHash} entry entry + * @returns {string | undefined} the resolved entry + */ +const getResolvedHash = entry => { + if (entry === null) return null; + if (entry.resolved !== undefined) return entry.resolved; + return entry.symlinks === undefined ? entry.hash : undefined; +}; + +const addAll = (source, target) => { + for (const key of source) target.add(key); }; /** @@ -57298,11 +57354,11 @@ class FileSystemInfo { this._fileHashes = new Map(); /** @type {Map} */ this._fileTshs = new Map(); - /** @type {StackedCacheMap} */ + /** @type {StackedCacheMap} */ this._contextTimestamps = new StackedCacheMap(); - /** @type {Map} */ + /** @type {Map} */ this._contextHashes = new Map(); - /** @type {Map} */ + /** @type {Map} */ this._contextTshs = new Map(); /** @type {Map} */ this._managedItems = new Map(); @@ -57318,18 +57374,24 @@ class FileSystemInfo { parallelism: 10, processor: this._readFileHash.bind(this) }); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ this.contextTimestampQueue = new AsyncQueue({ name: "context timestamp", parallelism: 2, processor: this._readContextTimestamp.bind(this) }); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ this.contextHashQueue = new AsyncQueue({ name: "context hash", parallelism: 2, processor: this._readContextHash.bind(this) }); + /** @type {AsyncQueue} */ + this.contextTshQueue = new AsyncQueue({ + name: "context hash and timestamp", + parallelism: 2, + processor: this._readContextTimestampAndHash.bind(this) + }); /** @type {AsyncQueue} */ this.managedItemQueue = new AsyncQueue({ name: "managed item info", @@ -57531,13 +57593,34 @@ class FileSystemInfo { /** * @param {string} path context path - * @param {function(WebpackError=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function + * @param {function(WebpackError=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function * @returns {void} */ getContextTimestamp(path, callback) { + const cache = this._contextTimestamps.get(path); + if (cache !== undefined) { + const resolved = getResolvedTimestamp(cache); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextTimestamp(cache, callback); + } + this.contextTimestampQueue.add(path, (err, entry) => { + const resolved = getResolvedTimestamp(entry); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextTimestamp(entry, callback); + }); + } + + /** + * @param {string} path context path + * @param {function(WebpackError=, (ContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function + * @returns {void} + */ + _getUnresolvedContextTimestamp(path, callback) { const cache = this._contextTimestamps.get(path); if (cache !== undefined) return callback(null, cache); - this.contextTimestampQueue.add(path, callback); + this.contextTimestampQueue.add(path, (err, entry) => { + return callback(null, entry); + }); } /** @@ -57557,9 +57640,62 @@ class FileSystemInfo { * @returns {void} */ getContextHash(path, callback) { + const cache = this._contextHashes.get(path); + if (cache !== undefined) { + const resolved = getResolvedHash(cache); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextHash(cache, callback); + } + this.contextHashQueue.add(path, (err, entry) => { + const resolved = getResolvedHash(entry); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextHash(entry, callback); + }); + } + + /** + * @param {string} path context path + * @param {function(WebpackError=, ContextHash=): void} callback callback function + * @returns {void} + */ + _getUnresolvedContextHash(path, callback) { const cache = this._contextHashes.get(path); if (cache !== undefined) return callback(null, cache); - this.contextHashQueue.add(path, callback); + this.contextHashQueue.add(path, (err, entry) => { + return callback(null, entry); + }); + } + + /** + * @param {string} path context path + * @param {function(WebpackError=, ResolvedContextTimestampAndHash=): void} callback callback function + * @returns {void} + */ + getContextTsh(path, callback) { + const cache = this._contextTshs.get(path); + if (cache !== undefined) { + const resolved = getResolvedTimestamp(cache); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextTsh(cache, callback); + } + this.contextTshQueue.add(path, (err, entry) => { + const resolved = getResolvedTimestamp(entry); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextTsh(entry, callback); + }); + } + + /** + * @param {string} path context path + * @param {function(WebpackError=, ContextTimestampAndHash=): void} callback callback function + * @returns {void} + */ + _getUnresolvedContextTsh(path, callback) { + const cache = this._contextTshs.get(path); + if (cache !== undefined) return callback(null, cache); + this.contextTshQueue.add(path, (err, entry) => { + return callback(null, entry); + }); } _createBuildDependenciesResolvers() { @@ -58445,11 +58581,15 @@ class FileSystemInfo { ); for (const path of capturedDirectories) { const cache = this._contextTshs.get(path); - if (cache !== undefined) { - contextTshs.set(path, cache); + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + contextTshs.set(path, resolved); } else { jobs++; - this._getContextTimestampAndHash(path, (err, entry) => { + const callback = (err, entry) => { if (err) { if (this.logger) { this.logger.debug( @@ -58461,7 +58601,12 @@ class FileSystemInfo { contextTshs.set(path, entry); jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextTsh(cache, callback); + } else { + this.getContextTsh(path, callback); + } } } break; @@ -58473,11 +58618,15 @@ class FileSystemInfo { ); for (const path of capturedDirectories) { const cache = this._contextHashes.get(path); - if (cache !== undefined) { - contextHashes.set(path, cache); + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedHash(cache)) !== undefined + ) { + contextHashes.set(path, resolved); } else { jobs++; - this.contextHashQueue.add(path, (err, entry) => { + const callback = (err, entry) => { if (err) { if (this.logger) { this.logger.debug( @@ -58489,7 +58638,12 @@ class FileSystemInfo { contextHashes.set(path, entry); jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextHash(cache, callback); + } else { + this.getContextHash(path, callback); + } } } break; @@ -58502,13 +58656,15 @@ class FileSystemInfo { ); for (const path of capturedDirectories) { const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache !== "ignore") { - contextTimestamps.set(path, cache); - } - } else { + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + contextTimestamps.set(path, resolved); + } else if (cache !== "ignore") { jobs++; - this.contextTimestampQueue.add(path, (err, entry) => { + const callback = (err, entry) => { if (err) { if (this.logger) { this.logger.debug( @@ -58520,7 +58676,12 @@ class FileSystemInfo { contextTimestamps.set(path, entry); jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextTimestamp(cache, callback); + } else { + this.getContextTimestamp(path, callback); + } } } break; @@ -58537,7 +58698,7 @@ class FileSystemInfo { const cache = this._fileTimestamps.get(path); if (cache !== undefined) { if (cache !== "ignore") { - missingExistence.set(path, toExistence(cache)); + missingExistence.set(path, Boolean(cache)); } } else { jobs++; @@ -58550,7 +58711,7 @@ class FileSystemInfo { } jobError(); } else { - missingExistence.set(path, toExistence(entry)); + missingExistence.set(path, Boolean(entry)); jobDone(); } }); @@ -58759,17 +58920,7 @@ class FileSystemInfo { */ const checkFile = (path, current, snap, log = true) => { if (current === snap) return true; - if (!current !== !snap) { - // If existence of item differs - // it's invalid - if (log && this._remainingLogs > 0) { - this._log( - path, - current ? "it didn't exist before" : "it does no longer exist" - ); - } - return false; - } + if (!checkExistence(path, Boolean(current), Boolean(snap))) return false; if (current) { // For existing items only if (typeof startTime === "number" && current.safeTime > startTime) { @@ -58801,6 +58952,34 @@ class FileSystemInfo { } return false; } + } + return true; + }; + /** + * @param {string} path file path + * @param {ResolvedContextFileSystemInfoEntry} current current entry + * @param {ResolvedContextFileSystemInfoEntry} snap entry from snapshot + * @param {boolean} log log reason + * @returns {boolean} true, if ok + */ + const checkContext = (path, current, snap, log = true) => { + if (current === snap) return true; + if (!checkExistence(path, Boolean(current), Boolean(snap))) return false; + if (current) { + // For existing items only + if (typeof startTime === "number" && current.safeTime > startTime) { + // If a change happened after starting reading the item + // this may no longer be valid + if (log && this._remainingLogs > 0) { + this._log( + path, + `it may have changed (%d) after the start time of the snapshot (%d)`, + current.safeTime, + startTime + ); + } + return false; + } if ( snap.timestampHash !== undefined && current.timestampHash !== snap.timestampHash @@ -58925,41 +59104,59 @@ class FileSystemInfo { this._statTestedEntries += contextTimestamps.size; for (const [path, ts] of contextTimestamps) { const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache !== "ignore" && !checkFile(path, cache, ts)) { + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + if (!checkContext(path, resolved, ts)) { invalid(); return; } - } else { + } else if (cache !== "ignore") { jobs++; - this.contextTimestampQueue.add(path, (err, entry) => { + const callback = (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkFile(path, entry, ts)) { + if (!checkContext(path, entry, ts)) { invalid(); } else { jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextTimestamp(cache, callback); + } else { + this.getContextTimestamp(path, callback); + } } } } const processContextHashSnapshot = (path, hash) => { const cache = this._contextHashes.get(path); - if (cache !== undefined) { - if (cache !== "ignore" && !checkHash(path, cache, hash)) { + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedHash(cache)) !== undefined + ) { + if (!checkHash(path, resolved, hash)) { invalid(); return; } } else { jobs++; - this.contextHashQueue.add(path, (err, entry) => { + const callback = (err, entry) => { if (err) return invalidWithError(path, err); if (!checkHash(path, entry, hash)) { invalid(); } else { jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextHash(cache, callback); + } else { + this.getContextHash(path, callback); + } } }; if (snapshot.hasContextHashes()) { @@ -58977,19 +59174,28 @@ class FileSystemInfo { processContextHashSnapshot(path, tsh); } else { const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache === "ignore" || !checkFile(path, cache, tsh, false)) { + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + if (!checkContext(path, resolved, tsh, false)) { processContextHashSnapshot(path, tsh.hash); } - } else { + } else if (cache !== "ignore") { jobs++; - this.contextTimestampQueue.add(path, (err, entry) => { + const callback = (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkFile(path, entry, tsh, false)) { + if (!checkContext(path, entry, tsh, false)) { processContextHashSnapshot(path, tsh.hash); } jobDone(); - }); + }; + if (cache !== undefined) { + this._resolveContextTsh(cache, callback); + } else { + this.getContextTsh(path, callback); + } } } } @@ -59002,7 +59208,7 @@ class FileSystemInfo { if (cache !== undefined) { if ( cache !== "ignore" && - !checkExistence(path, toExistence(cache), existence) + !checkExistence(path, Boolean(cache), Boolean(existence)) ) { invalid(); return; @@ -59011,7 +59217,7 @@ class FileSystemInfo { jobs++; this.fileTimestampQueue.add(path, (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkExistence(path, toExistence(entry), existence)) { + if (!checkExistence(path, Boolean(entry), Boolean(existence))) { invalid(); } else { jobDone(); @@ -59165,12 +59371,34 @@ class FileSystemInfo { } } - _readContextTimestamp(path, callback) { + /** + * @template T + * @template ItemType + * @param {Object} options options + * @param {string} options.path path + * @param {function(string): ItemType} options.fromImmutablePath called when context item is an immutable path + * @param {function(string): ItemType} options.fromManagedItem called when context item is a managed path + * @param {function(string, string, function(Error=, ItemType=): void): void} options.fromSymlink called when context item is a symlink + * @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromFile called when context item is a file + * @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromDirectory called when context item is a directory + * @param {function(string[], ItemType[]): T} options.reduce called from all context items + * @param {function(Error=, (T)=): void} callback callback + */ + _readContext( + { + path, + fromImmutablePath, + fromManagedItem, + fromSymlink, + fromFile, + fromDirectory, + reduce + }, + callback + ) { this.fs.readdir(path, (err, _files) => { if (err) { if (err.code === "ENOENT") { - this._contextTimestamps.set(path, null); - this._cachedDeprecatedContextTimestamps = undefined; return callback(null, null); } return callback(err); @@ -59183,47 +59411,94 @@ class FileSystemInfo { files, (file, callback) => { const child = join(this.fs, path, file); - this.fs.stat(child, (err, stat) => { - if (err) return callback(err); - - for (const immutablePath of this.immutablePathsWithSlash) { - if (path.startsWith(immutablePath)) { - // ignore any immutable path for timestamping - return callback(null, null); + for (const immutablePath of this.immutablePathsWithSlash) { + if (path.startsWith(immutablePath)) { + // ignore any immutable path for timestamping + return callback(null, fromImmutablePath(immutablePath)); + } + } + for (const managedPath of this.managedPathsWithSlash) { + if (path.startsWith(managedPath)) { + const managedItem = getManagedItem(managedPath, child); + if (managedItem) { + // construct timestampHash from managed info + return this.managedItemQueue.add(managedItem, (err, info) => { + if (err) return callback(err); + return callback(null, fromManagedItem(info)); + }); } } - for (const managedPath of this.managedPathsWithSlash) { - if (path.startsWith(managedPath)) { - const managedItem = getManagedItem(managedPath, child); - if (managedItem) { - // construct timestampHash from managed info - return this.managedItemQueue.add(managedItem, (err, info) => { - if (err) return callback(err); - return callback(null, { - safeTime: 0, - timestampHash: info - }); - }); - } - } + } + + lstatReadlinkAbsolute(this.fs, child, (err, stat) => { + if (err) return callback(err); + + if (typeof stat === "string") { + return fromSymlink(child, stat, callback); } if (stat.isFile()) { - return this.getFileTimestamp(child, callback); + return fromFile(child, stat, callback); } if (stat.isDirectory()) { - this.contextTimestampQueue.increaseParallelism(); - this.getContextTimestamp(child, (err, tsEntry) => { - this.contextTimestampQueue.decreaseParallelism(); - callback(err, tsEntry); - }); - return; + return fromDirectory(child, stat, callback); } callback(null, null); }); }, - (err, tsEntries) => { + (err, results) => { if (err) return callback(err); + const result = reduce(files, results); + callback(null, result); + } + ); + }); + } + + _readContextTimestamp(path, callback) { + this._readContext( + { + path, + fromImmutablePath: () => null, + fromManagedItem: info => ({ + safeTime: 0, + timestampHash: info + }), + fromSymlink: (file, target, callback) => { + callback(null, { + timestampHash: target, + symlinks: new Set([target]) + }); + }, + fromFile: (file, stat, callback) => { + // Prefer the cached value over our new stat to report consistent results + const cache = this._fileTimestamps.get(file); + if (cache !== undefined) + return callback(null, cache === "ignore" ? null : cache); + + const mtime = +stat.mtime; + + if (mtime) applyMtime(mtime); + + const ts = { + safeTime: mtime ? mtime + FS_ACCURACY : Infinity, + timestamp: mtime + }; + + this._fileTimestamps.set(file, ts); + this._cachedDeprecatedFileTimestamps = undefined; + callback(null, ts); + }, + fromDirectory: (directory, stat, callback) => { + this.contextTimestampQueue.increaseParallelism(); + this._getUnresolvedContextTimestamp(directory, (err, tsEntry) => { + this.contextTimestampQueue.decreaseParallelism(); + callback(err, tsEntry); + }); + }, + reduce: (files, tsEntries) => { + let symlinks = undefined; + const hash = createHash("md4"); for (const file of files) hash.update(file); @@ -59240,6 +59515,10 @@ class FileSystemInfo { hash.update("d"); hash.update(`${entry.timestampHash}`); } + if (entry.symlinks !== undefined) { + if (symlinks === undefined) symlinks = new Set(); + addAll(entry.symlinks, symlinks); + } if (entry.safeTime) { safeTime = Math.max(safeTime, entry.safeTime); } @@ -59251,131 +59530,326 @@ class FileSystemInfo { safeTime, timestampHash: digest }; - - this._contextTimestamps.set(path, result); - this._cachedDeprecatedContextTimestamps = undefined; - - callback(null, result); + if (symlinks) result.symlinks = symlinks; + return result; } - ); - }); - } + }, + (err, result) => { + if (err) return callback(err); + this._contextTimestamps.set(path, result); + this._cachedDeprecatedContextTimestamps = undefined; - _readContextHash(path, callback) { - this.fs.readdir(path, (err, _files) => { - if (err) { - if (err.code === "ENOENT") { - this._contextHashes.set(path, null); - return callback(null, null); - } - return callback(err); + callback(null, result); } - const files = /** @type {string[]} */ (_files) - .map(file => file.normalize("NFC")) - .filter(file => !/^\./.test(file)) - .sort(); - asyncLib.map( - files, - (file, callback) => { - const child = join(this.fs, path, file); - this.fs.stat(child, (err, stat) => { - if (err) return callback(err); + ); + } - for (const immutablePath of this.immutablePathsWithSlash) { - if (path.startsWith(immutablePath)) { - // ignore any immutable path for hashing - return callback(null, ""); - } + _resolveContextTimestamp(entry, callback) { + const hashes = []; + let safeTime = 0; + processAsyncTree( + entry.symlinks, + 10, + (target, push, callback) => { + this._getUnresolvedContextTimestamp(target, (err, entry) => { + if (err) return callback(err); + if (entry && entry !== "ignore") { + hashes.push(entry.timestampHash); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); } - for (const managedPath of this.managedPathsWithSlash) { - if (path.startsWith(managedPath)) { - const managedItem = getManagedItem(managedPath, child); - if (managedItem) { - // construct hash from managed info - return this.managedItemQueue.add(managedItem, (err, info) => { - if (err) return callback(err); - callback(null, info || ""); - }); - } - } + if (entry.symlinks !== undefined) { + for (const target of entry.symlinks) push(target); } + } + callback(); + }); + }, + err => { + if (err) return callback(err); + const hash = createHash("md4"); + hash.update(entry.timestampHash); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + hashes.sort(); + for (const h of hashes) { + hash.update(h); + } + callback( + null, + (entry.resolved = { + safeTime, + timestampHash: /** @type {string} */ (hash.digest("hex")) + }) + ); + } + ); + } - if (stat.isFile()) { - return this.getFileHash(child, (err, hash) => { - callback(err, hash || ""); - }); - } - if (stat.isDirectory()) { - this.contextHashQueue.increaseParallelism(); - this.getContextHash(child, (err, hash) => { - this.contextHashQueue.decreaseParallelism(); - callback(err, hash || ""); - }); - return; - } - callback(null, ""); + _readContextHash(path, callback) { + this._readContext( + { + path, + fromImmutablePath: () => "", + fromManagedItem: info => info || "", + fromSymlink: (file, target, callback) => { + callback(null, { + hash: target, + symlinks: new Set([target]) }); }, - (err, fileHashes) => { - if (err) return callback(err); + fromFile: (file, stat, callback) => + this.getFileHash(file, (err, hash) => { + callback(err, hash || ""); + }), + fromDirectory: (directory, stat, callback) => { + this.contextHashQueue.increaseParallelism(); + this._getUnresolvedContextHash(directory, (err, hash) => { + this.contextHashQueue.decreaseParallelism(); + callback(err, hash || ""); + }); + }, + /** + * @param {string[]} files files + * @param {(string | ContextHash)[]} fileHashes hashes + * @returns {ContextHash} reduced hash + */ + reduce: (files, fileHashes) => { + let symlinks = undefined; const hash = createHash("md4"); for (const file of files) hash.update(file); - for (const h of fileHashes) hash.update(h); - - const digest = /** @type {string} */ (hash.digest("hex")); - - this._contextHashes.set(path, digest); + for (const entry of fileHashes) { + if (typeof entry === "string") { + hash.update(entry); + } else { + hash.update(entry.hash); + if (entry.symlinks) { + if (symlinks === undefined) symlinks = new Set(); + addAll(entry.symlinks, symlinks); + } + } + } - callback(null, digest); + const result = { + hash: /** @type {string} */ (hash.digest("hex")) + }; + if (symlinks) result.symlinks = symlinks; + return result; } - ); - }); + }, + (err, result) => { + if (err) return callback(err); + this._contextHashes.set(path, result); + return callback(null, result); + } + ); } - _getContextTimestampAndHash(path, callback) { - const continueWithHash = hash => { - const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache !== "ignore") { - const result = { - ...cache, - hash - }; - this._contextTshs.set(path, result); - return callback(null, result); - } else { - this._contextTshs.set(path, hash); - return callback(null, hash); + _resolveContextHash(entry, callback) { + const hashes = []; + processAsyncTree( + entry.symlinks, + 10, + (target, push, callback) => { + this._getUnresolvedContextHash(target, (err, hash) => { + if (err) return callback(err); + if (hash) { + hashes.push(hash.hash); + if (hash.symlinks !== undefined) { + for (const target of hash.symlinks) push(target); + } + } + callback(); + }); + }, + err => { + if (err) return callback(err); + const hash = createHash("md4"); + hash.update(entry.hash); + hashes.sort(); + for (const h of hashes) { + hash.update(h); } + callback( + null, + (entry.resolved = /** @type {string} */ (hash.digest("hex"))) + ); + } + ); + } + + _readContextTimestampAndHash(path, callback) { + const finalize = (timestamp, hash) => { + const result = + timestamp === "ignore" + ? hash + : { + ...timestamp, + ...hash + }; + this._contextTshs.set(path, result); + callback(null, result); + }; + const cachedHash = this._contextHashes.get(path); + const cachedTimestamp = this._contextTimestamps.get(path); + if (cachedHash !== undefined) { + if (cachedTimestamp !== undefined) { + finalize(cachedTimestamp, cachedHash); } else { this.contextTimestampQueue.add(path, (err, entry) => { - if (err) { - return callback(err); - } - const result = { - ...entry, - hash - }; - this._contextTshs.set(path, result); - return callback(null, result); + if (err) return callback(err); + finalize(entry, cachedHash); }); } - }; - - const cache = this._contextHashes.get(path); - if (cache !== undefined) { - continueWithHash(cache); } else { - this.contextHashQueue.add(path, (err, entry) => { - if (err) { - return callback(err); - } - continueWithHash(entry); - }); + if (cachedTimestamp !== undefined) { + this.contextHashQueue.add(path, (err, entry) => { + if (err) return callback(err); + finalize(cachedTimestamp, entry); + }); + } else { + this._readContext( + { + path, + fromImmutablePath: () => null, + fromManagedItem: info => ({ + safeTime: 0, + timestampHash: info, + hash: info || "" + }), + fromSymlink: (fle, target, callback) => { + callback(null, { + timestampHash: target, + hash: target, + symlinks: new Set([target]) + }); + }, + fromFile: (file, stat, callback) => { + this._getFileTimestampAndHash(file, callback); + }, + fromDirectory: (directory, stat, callback) => { + this.contextTshQueue.increaseParallelism(); + this.contextTshQueue.add(directory, (err, result) => { + this.contextTshQueue.decreaseParallelism(); + callback(err, result); + }); + }, + /** + * @param {string[]} files files + * @param {(Partial & Partial | string | null)[]} results results + * @returns {ContextTimestampAndHash} tsh + */ + reduce: (files, results) => { + let symlinks = undefined; + + const tsHash = createHash("md4"); + const hash = createHash("md4"); + + for (const file of files) { + tsHash.update(file); + hash.update(file); + } + let safeTime = 0; + for (const entry of results) { + if (!entry) { + tsHash.update("n"); + continue; + } + if (typeof entry === "string") { + tsHash.update("n"); + hash.update(entry); + continue; + } + if (entry.timestamp) { + tsHash.update("f"); + tsHash.update(`${entry.timestamp}`); + } else if (entry.timestampHash) { + tsHash.update("d"); + tsHash.update(`${entry.timestampHash}`); + } + if (entry.symlinks !== undefined) { + if (symlinks === undefined) symlinks = new Set(); + addAll(entry.symlinks, symlinks); + } + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + hash.update(entry.hash); + } + + const result = { + safeTime, + timestampHash: /** @type {string} */ (tsHash.digest("hex")), + hash: /** @type {string} */ (hash.digest("hex")) + }; + if (symlinks) result.symlinks = symlinks; + return result; + } + }, + (err, result) => { + if (err) return callback(err); + this._contextTshs.set(path, result); + return callback(null, result); + } + ); + } } } + _resolveContextTsh(entry, callback) { + const hashes = []; + const tsHashes = []; + let safeTime = 0; + processAsyncTree( + entry.symlinks, + 10, + (target, push, callback) => { + this._getUnresolvedContextTsh(target, (err, entry) => { + if (err) return callback(err); + if (entry) { + hashes.push(entry.hash); + if (entry.timestampHash) tsHashes.push(entry.timestampHash); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + if (entry.symlinks !== undefined) { + for (const target of entry.symlinks) push(target); + } + } + callback(); + }); + }, + err => { + if (err) return callback(err); + const hash = createHash("md4"); + const tsHash = createHash("md4"); + hash.update(entry.hash); + if (entry.timestampHash) tsHash.update(entry.timestampHash); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + hashes.sort(); + for (const h of hashes) { + hash.update(h); + } + tsHashes.sort(); + for (const h of tsHashes) { + tsHash.update(h); + } + callback( + null, + (entry.resolved = { + safeTime, + timestampHash: /** @type {string} */ (tsHash.digest("hex")), + hash: /** @type {string} */ (hash.digest("hex")) + }) + ); + } + ); + } + _getManagedItemDirectoryInfo(path, callback) { this.fs.readdir(path, (err, elements) => { if (err) { @@ -67144,7 +67618,11 @@ const { } = __webpack_require__(21699); const createHash = __webpack_require__(34627); const { join } = __webpack_require__(71593); -const { contextify, absolutify } = __webpack_require__(47779); +const { + contextify, + absolutify, + makePathsRelative +} = __webpack_require__(47779); const makeSerializable = __webpack_require__(55575); const memoize = __webpack_require__(18003); @@ -67208,7 +67686,11 @@ const ABSOLUTE_PATH_REGEX = /^([a-zA-Z]:\\|\\\\|\/)/; */ const contextifySourceUrl = (context, source, associatedObjectForCache) => { if (source.startsWith("webpack://")) return source; - return `webpack://${contextify(context, source, associatedObjectForCache)}`; + return `webpack://${makePathsRelative( + context, + source, + associatedObjectForCache + )}`; }; /** @@ -71534,6 +72016,11 @@ exports.hmrModuleData = "__webpack_require__.hmrD"; */ exports.hmrInvalidateModuleHandlers = "__webpack_require__.hmrI"; +/** + * the prefix for storing state of runtime modules when hmr is enabled + */ +exports.hmrRuntimeStatePrefix = "__webpack_require__.hmrS"; + /** * the AMD define function */ @@ -73287,7 +73774,7 @@ const SourceMapDevToolModuleOptionsPlugin = __webpack_require__(5426); const createSchemaValidation = __webpack_require__(32797); const createHash = __webpack_require__(34627); const { relative, dirname } = __webpack_require__(71593); -const { absolutify } = __webpack_require__(47779); +const { makePathsAbsolute } = __webpack_require__(47779); /** @typedef {import("webpack-sources").MapOptions} MapOptions */ /** @typedef {import("webpack-sources").Source} Source */ @@ -73364,7 +73851,7 @@ const getTaskForFile = ( if (!sourceMap || typeof source !== "string") return; const context = compilation.options.context; const root = compilation.compiler.root; - const cachedAbsolutify = absolutify.bindContextCache(context, root); + const cachedAbsolutify = makePathsAbsolute.bindContextCache(context, root); const modules = sourceMap.sources.map(source => { if (!source.startsWith("webpack://")) return source; source = cachedAbsolutify(source.slice(10)); @@ -99973,6 +100460,9 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule { const withOnChunkLoad = this._runtimeRequirements.has( RuntimeGlobals.onChunksLoaded ); + const withHmr = this._runtimeRequirements.has( + RuntimeGlobals.hmrDownloadUpdateHandlers + ); const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs); const hasJsMatcher = compileBooleanMatcher(conditionMap); const initialChunkIds = getInitialChunkIds(chunk, chunkGraph); @@ -99990,6 +100480,10 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule { true ); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_module` + : undefined; + return Template.asString([ withBaseURI ? Template.asString([ @@ -100002,7 +100496,9 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule { "// object to store loaded and loading chunks", "// undefined = chunk not loaded, null = chunk preloaded/prefetched", "// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded", - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join( ",\n" @@ -110939,6 +111435,10 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin { const result = new ConcatSource(source); const exportsInfo = moduleGraph.getExportsInfo(module); const exports = []; + const isAsync = moduleGraph.isAsync(module); + if (isAsync) { + result.add(`__webpack_exports__ = await __webpack_exports__;\n`); + } for (const exportInfo of exportsInfo.orderedExports) { if (!exportInfo.provided) continue; const varName = `__webpack_exports__${Template.toIdentifier( @@ -112580,6 +113080,10 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { false ); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_readFileVm` + : undefined; + return Template.asString([ withBaseURI ? Template.asString([ @@ -112593,7 +113097,9 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { "", "// object to store loaded chunks", '// "0" means "already loaded", Promise means loading', - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join( ",\n" @@ -112804,7 +113310,7 @@ module.exports = ReadFileChunkLoadingRuntimeModule; const RuntimeGlobals = __webpack_require__(48801); const Template = __webpack_require__(90751); -const AsyncWasmChunkLoadingRuntimeModule = __webpack_require__(38733); +const AsyncWasmLoadingRuntimeModule = __webpack_require__(36486); /** @typedef {import("../Compiler")} Compiler */ @@ -112890,7 +113396,7 @@ class ReadFileCompileAsyncWasmPlugin { set.add(RuntimeGlobals.publicPath); compilation.addRuntimeModule( chunk, - new AsyncWasmChunkLoadingRuntimeModule({ + new AsyncWasmLoadingRuntimeModule({ generateLoadBinaryCode, supportsStreaming: false }) @@ -112992,7 +113498,8 @@ class ReadFileCompileWasmPlugin { new WasmChunkLoadingRuntimeModule({ generateLoadBinaryCode, supportsStreaming: false, - mangleImports: this.options.mangleImports + mangleImports: this.options.mangleImports, + runtimeRequirements: set }) ); }); @@ -113073,6 +113580,10 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { true ); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_require` + : undefined; + return Template.asString([ withBaseURI ? Template.asString([ @@ -113086,7 +113597,9 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { "", "// object to store loaded chunks", '// "1" means "loaded", otherwise not loaded yet', - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 1`).join( ",\n" @@ -113848,7 +114361,7 @@ const { equals } = __webpack_require__(92459); const LazySet = __webpack_require__(60248); const { concatComparators, keepOriginalOrder } = __webpack_require__(21699); const createHash = __webpack_require__(34627); -const contextify = __webpack_require__(47779).contextify; +const { makePathsRelative } = __webpack_require__(47779); const makeSerializable = __webpack_require__(55575); const propertyAccess = __webpack_require__(44682); const { @@ -114836,13 +115349,13 @@ class ConcatenatedModule extends Module { } static _createIdentifier(rootModule, modules, associatedObjectForCache) { - const cachedContextify = contextify.bindContextCache( + const cachedMakePathsRelative = makePathsRelative.bindContextCache( rootModule.context, associatedObjectForCache ); let identifiers = []; for (const module of modules) { - identifiers.push(cachedContextify(module.identifier())); + identifiers.push(cachedMakePathsRelative(module.identifier())); } identifiers.sort(); const hash = createHash("md4"); @@ -139569,6 +140082,7 @@ const path = __webpack_require__(85622); /** @typedef {function((NodeJS.ErrnoException | null)=, number=): void} NumberCallback */ /** @typedef {function((NodeJS.ErrnoException | null)=, IStats=): void} StatsCallback */ /** @typedef {function((NodeJS.ErrnoException | Error | null)=, any=): void} ReadJsonCallback */ +/** @typedef {function((NodeJS.ErrnoException | Error | null)=, IStats|string=): void} LstatReadlinkAbsoluteCallback */ /** * @typedef {Object} Watcher @@ -139613,6 +140127,7 @@ const path = __webpack_require__(85622); * @property {function(string, BufferOrStringCallback): void} readlink * @property {function(string, DirentArrayCallback): void} readdir * @property {function(string, StatsCallback): void} stat + * @property {function(string, StatsCallback): void=} lstat * @property {(function(string, BufferOrStringCallback): void)=} realpath * @property {(function(string=): void)=} purge * @property {(function(string, string): string)=} join @@ -139793,6 +140308,44 @@ const readJson = (fs, p, callback) => { }; exports.readJson = readJson; +/** + * @param {InputFileSystem} fs a file system + * @param {string} p an absolute path + * @param {ReadJsonCallback} callback callback + * @returns {void} + */ +const lstatReadlinkAbsolute = (fs, p, callback) => { + let i = 3; + const doReadLink = () => { + fs.readlink(p, (err, target) => { + if (err && --i > 0) { + // It might was just changed from symlink to file + // we retry 2 times to catch this case before throwing the error + return doStat(); + } + if (err || !target) return doStat(); + const value = target.toString(); + callback(null, join(fs, dirname(fs, p), value)); + }); + }; + const doStat = () => { + if ("lstat" in fs) { + return fs.lstat(p, (err, stats) => { + if (err) return callback(err); + if (stats.isSymbolicLink()) { + return doReadLink(); + } + callback(null, stats); + }); + } else { + return fs.stat(p, callback); + } + }; + if ("lstat" in fs) return doStat(); + doReadLink(); +}; +exports.lstatReadlinkAbsolute = lstatReadlinkAbsolute; + /***/ }), @@ -139817,6 +140370,13 @@ const WINDOWS_PATH_SEPARATOR_REGEXP = /\\/g; * @property {Map>=} relativePaths */ +const relativePathToRequest = relativePath => { + if (relativePath === "") return "./."; + if (relativePath === "..") return "../."; + if (relativePath.startsWith("../")) return relativePath; + return `./${relativePath}`; +}; + /** * @param {string} context context for relative path * @param {string} maybeAbsolutePath path to make relative @@ -139838,10 +140398,7 @@ const absoluteToRequest = (context, maybeAbsolutePath) => { querySplitPos === -1 ? maybeAbsolutePath : maybeAbsolutePath.slice(0, querySplitPos); - resource = path.posix.relative(context, resource); - if (!resource.startsWith("../")) { - resource = "./" + resource; - } + resource = relativePathToRequest(path.posix.relative(context, resource)); return querySplitPos === -1 ? resource : resource + maybeAbsolutePath.slice(querySplitPos); @@ -139855,10 +140412,9 @@ const absoluteToRequest = (context, maybeAbsolutePath) => { : maybeAbsolutePath.slice(0, querySplitPos); resource = path.win32.relative(context, resource); if (!WINDOWS_ABS_PATH_REGEXP.test(resource)) { - resource = resource.replace(WINDOWS_PATH_SEPARATOR_REGEXP, "/"); - if (!resource.startsWith("../")) { - resource = "./" + resource; - } + resource = relativePathToRequest( + resource.replace(WINDOWS_PATH_SEPARATOR_REGEXP, "/") + ); } return querySplitPos === -1 ? resource @@ -140016,6 +140572,21 @@ const _makePathsRelative = (context, identifier) => { exports.makePathsRelative = makeCacheable(_makePathsRelative); +/** + * + * @param {string} context context for relative path + * @param {string} identifier identifier for path + * @returns {string} a converted relative path + */ +const _makePathsAbsolute = (context, identifier) => { + return identifier + .split(SEGMENTS_SPLIT_REGEXP) + .map(str => requestToAbsolute(context, str)) + .join(""); +}; + +exports.makePathsAbsolute = makeCacheable(_makePathsAbsolute); + /** * @param {string} context absolute context path * @param {string} request any request string may containing absolute paths, query string, etc. @@ -142639,7 +143210,7 @@ module.exports = validateSchema; /***/ }), -/***/ 38733: +/***/ 36486: /***/ (function(module, __unused_webpack_exports, __webpack_require__) { "use strict"; @@ -142654,9 +143225,9 @@ const RuntimeGlobals = __webpack_require__(48801); const RuntimeModule = __webpack_require__(54746); const Template = __webpack_require__(90751); -class AsyncWasmChunkLoadingRuntimeModule extends RuntimeModule { +class AsyncWasmLoadingRuntimeModule extends RuntimeModule { constructor({ generateLoadBinaryCode, supportsStreaming }) { - super("wasm chunk loading", RuntimeModule.STAGE_ATTACH); + super("wasm loading", RuntimeModule.STAGE_NORMAL); this.generateLoadBinaryCode = generateLoadBinaryCode; this.supportsStreaming = supportsStreaming; } @@ -142720,7 +143291,7 @@ class AsyncWasmChunkLoadingRuntimeModule extends RuntimeModule { } } -module.exports = AsyncWasmChunkLoadingRuntimeModule; +module.exports = AsyncWasmLoadingRuntimeModule; /***/ }), @@ -143490,11 +144061,17 @@ const generateImportObject = ( }; class WasmChunkLoadingRuntimeModule extends RuntimeModule { - constructor({ generateLoadBinaryCode, supportsStreaming, mangleImports }) { + constructor({ + generateLoadBinaryCode, + supportsStreaming, + mangleImports, + runtimeRequirements + }) { super("wasm chunk loading", RuntimeModule.STAGE_ATTACH); this.generateLoadBinaryCode = generateLoadBinaryCode; this.supportsStreaming = supportsStreaming; this.mangleImports = mangleImports; + this._runtimeRequirements = runtimeRequirements; } /** @@ -143504,6 +144081,9 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule { const { chunkGraph, compilation, chunk, mangleImports } = this; const { moduleGraph, outputOptions } = compilation; const fn = RuntimeGlobals.ensureChunkHandlers; + const withHmr = this._runtimeRequirements.has( + RuntimeGlobals.hmrDownloadUpdateHandlers + ); const wasmModules = getAllWasmModules(moduleGraph, chunkGraph, chunk); const declarations = []; const importObjects = wasmModules.map(module => { @@ -143548,9 +144128,16 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule { runtime: chunk.runtime } ); + + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_wasm` + : undefined; + return Template.asString([ "// object to store loaded and loading wasm modules", - "var installedWasmModules = {};", + `var installedWasmModules = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{};`, "", // This function is used to delay reading the installed wasm module promises // by a microtask. Sorting them doesn't help because there are edge cases where @@ -145157,7 +145744,7 @@ module.exports = EnableWasmLoadingPlugin; const RuntimeGlobals = __webpack_require__(48801); -const AsyncWasmChunkLoadingRuntimeModule = __webpack_require__(38733); +const AsyncWasmLoadingRuntimeModule = __webpack_require__(36486); /** @typedef {import("../Compiler")} Compiler */ @@ -145199,7 +145786,7 @@ class FetchCompileAsyncWasmPlugin { set.add(RuntimeGlobals.publicPath); compilation.addRuntimeModule( chunk, - new AsyncWasmChunkLoadingRuntimeModule({ + new AsyncWasmLoadingRuntimeModule({ generateLoadBinaryCode, supportsStreaming: true }) @@ -145279,7 +145866,8 @@ class FetchCompileWasmPlugin { new WasmChunkLoadingRuntimeModule({ generateLoadBinaryCode, supportsStreaming: true, - mangleImports: this.options.mangleImports + mangleImports: this.options.mangleImports, + runtimeRequirements: set }) ); }); @@ -145496,6 +146084,10 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { const hasJsMatcher = compileBooleanMatcher(conditionMap); const initialChunkIds = getInitialChunkIds(chunk, chunkGraph); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_jsonp` + : undefined; + return Template.asString([ withBaseURI ? Template.asString([ @@ -145506,7 +146098,9 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { "// object to store loaded and loading chunks", "// undefined = chunk not loaded, null = chunk preloaded/prefetched", "// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded", - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join( ",\n" @@ -145787,16 +146381,23 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { '// add "moreModules" to the modules object,', '// then flag all "chunkIds" as loaded and fire callback', "var moduleId, chunkId, i = 0;", - "for(moduleId in moreModules) {", + `if(chunkIds.some(${runtimeTemplate.returningFunction( + "installedChunks[id] !== 0", + "id" + )})) {`, Template.indent([ - `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, - Template.indent( - `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` - ), - "}" + "for(moduleId in moreModules) {", + Template.indent([ + `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, + Template.indent( + `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` + ), + "}" + ]), + "}", + "if(runtime) var result = runtime(__webpack_require__);" ]), "}", - "if(runtime) var result = runtime(__webpack_require__);", "if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);", "for(;i < chunkIds.length; i++) {", Template.indent([ @@ -146228,6 +146829,10 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { false ); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_importScripts` + : undefined; + return Template.asString([ withBaseURI ? Template.asString([ @@ -146239,7 +146844,9 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { "", "// object to store loaded chunks", '// "1" means "already loaded"', - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 1`).join( ",\n"