@@ -226,9 +226,10 @@ function getOptimizedDeferredModule(
226226 * Renders the setup a deferred namespace helper needs when a hot update delivers
227227 * it, since the running bootstrap may not mark modules as evaluating.
228228 * @param {RuntimeTemplate } runtimeTemplate the runtime template
229+ * @param {boolean } recordErrors the bootstrap may not keep evaluation errors
229230 * @returns {string } setup code, run once per runtime
230231 */
231- function renderHotDeferredSetup ( runtimeTemplate ) {
232+ function renderHotDeferredSetup ( runtimeTemplate , recordErrors ) {
232233 const cache = RuntimeGlobals . deferredModuleNamespaceCache ;
233234 return Template . asString ( [
234235 // The namespace cache doubles as the flag that the interceptor is installed.
@@ -242,7 +243,11 @@ function renderHotDeferredSetup(runtimeTemplate) {
242243 "if (factory) options.factory = function(module) {" ,
243244 Template . indent ( [
244245 "module.evaluating = true;" ,
245- "try { return factory.apply(this, arguments); } finally { module.evaluating = false; }"
246+ "try { return factory.apply(this, arguments); }" ,
247+ ...( recordErrors
248+ ? [ "catch (e) { module.error = e; throw e; }" ]
249+ : [ ] ) ,
250+ "finally { module.evaluating = false; }"
246251 ] ) ,
247252 "};"
248253 ]
@@ -287,8 +292,11 @@ class MakeOptimizedDeferredNamespaceObjectRuntimeModule extends HelperRuntimeMod
287292 const moduleCache = hot
288293 ? RuntimeGlobals . moduleCache
289294 : "__webpack_module_cache__" ;
295+ // Without strict error handling the running bootstrap keeps no error to rethrow.
296+ const recordErrors =
297+ hot && ! runtimeTemplate . outputOptions . strictModuleErrorHandling ;
290298 return Template . asString ( [
291- ...( hot ? [ renderHotDeferredSetup ( runtimeTemplate ) ] : [ ] ) ,
299+ ...( hot ? [ renderHotDeferredSetup ( runtimeTemplate , recordErrors ) ] : [ ] ) ,
292300 // Note: must be a function (not arrow), because this is used in body!
293301 // `asyncDeps` keeps a fixed positional slot even without async runtime
294302 // so the trailing `syncDeps` (defer-cycle closure) always lines up.
@@ -305,6 +313,11 @@ class MakeOptimizedDeferredNamespaceObjectRuntimeModule extends HelperRuntimeMod
305313 // exports. `syncDeps` carries the closure that catches it first.
306314 `${ cst } cachedModule = ${ moduleCache } [moduleId];` ,
307315 'if (cachedModule !== undefined && (cachedModule.evaluating || cachedModule.evaluatingAsync)) throw new TypeError("Cannot access a deferred module namespace while the module is being evaluated");' ,
316+ ...( recordErrors
317+ ? [
318+ "if (cachedModule !== undefined && cachedModule.error !== undefined) throw cachedModule.error;"
319+ ]
320+ : [ ] ) ,
308321 "if (syncDeps) for (var i = 0; i < syncDeps.length; i++) {" ,
309322 Template . indent ( [
310323 `${ cst } depModule = ${ moduleCache } [syncDeps[i]];` ,
@@ -393,7 +406,10 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
393406 const namespaceCache = hot
394407 ? RuntimeGlobals . deferredModuleNamespaceCache
395408 : "__webpack_module_deferred_namespace_cache__" ;
396- return `${ hot ? `${ renderHotDeferredSetup ( runtimeTemplate ) } \n` : "" } ${ fn } = ${ runtimeTemplate . basicFunction (
409+ // Without strict error handling the running bootstrap keeps no error to rethrow.
410+ const recordErrors =
411+ hot && ! runtimeTemplate . outputOptions . strictModuleErrorHandling ;
412+ return `${ hot ? `${ renderHotDeferredSetup ( runtimeTemplate , recordErrors ) } \n` : "" } ${ fn } = ${ runtimeTemplate . basicFunction (
397413 "moduleId, mode, exportNames" ,
398414 [
399415 // WHY: the TC39 import-defer spec makes a deferred namespace distinct
@@ -440,6 +456,11 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
440456 // partial exports.
441457 `${ cst } evaluatingModule = ${ moduleCache } [moduleId];` ,
442458 'if (evaluatingModule !== undefined && (evaluatingModule.evaluating || evaluatingModule.evaluatingAsync)) throw new TypeError("Cannot access a deferred module namespace while the module is being evaluated");' ,
459+ ...( recordErrors
460+ ? [
461+ "if (evaluatingModule !== undefined && evaluatingModule.error !== undefined) throw evaluatingModule.error;"
462+ ]
463+ : [ ] ) ,
443464 `ns = ${ RuntimeGlobals . require } (moduleId);` ,
444465 hasAsync
445466 ? `if (${ RuntimeGlobals . asyncModuleExportSymbol } in ns) ns = ns[${ RuntimeGlobals . asyncModuleExportSymbol } ];`
0 commit comments