webpack 5.108.3 → 5.109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/lib/APIPlugin.js +48 -29
  2. package/lib/CacheFacade.js +8 -0
  3. package/lib/ChunkGroup.js +1 -0
  4. package/lib/CompatibilityPlugin.js +31 -29
  5. package/lib/Compilation.js +50 -8
  6. package/lib/ConstPlugin.js +11 -11
  7. package/lib/ContextModule.js +239 -6
  8. package/lib/ContextModuleFactory.js +139 -14
  9. package/lib/DefinePlugin.js +396 -101
  10. package/lib/Entrypoint.js +1 -1
  11. package/lib/ExportsInfoApiPlugin.js +2 -2
  12. package/lib/ExternalModule.js +107 -5
  13. package/lib/ExternalModuleFactoryPlugin.js +20 -1
  14. package/lib/FileSystemInfo.js +130 -74
  15. package/lib/FlagDependencyExportsPlugin.js +55 -8
  16. package/lib/HotModuleReplacementPlugin.js +18 -15
  17. package/lib/LazyBarrel.js +30 -3
  18. package/lib/Module.js +3 -0
  19. package/lib/ModuleFilenameHelpers.js +2 -2
  20. package/lib/ModuleTypeConstants.js +8 -1
  21. package/lib/MultiCompiler.js +13 -2
  22. package/lib/MultiWatching.js +1 -0
  23. package/lib/NodeStuffPlugin.js +51 -33
  24. package/lib/NormalModule.js +169 -405
  25. package/lib/NormalModuleFactory.js +76 -2
  26. package/lib/ProgressPlugin.js +211 -119
  27. package/lib/ProvidePlugin.js +2 -2
  28. package/lib/RuntimeGlobals.js +47 -0
  29. package/lib/RuntimePlugin.js +33 -0
  30. package/lib/RuntimeTemplate.js +304 -16
  31. package/lib/UseStrictPlugin.js +1 -1
  32. package/lib/WebpackIsIncludedPlugin.js +1 -1
  33. package/lib/WebpackOptionsApply.js +24 -19
  34. package/lib/asset/AssetGenerator.js +110 -28
  35. package/lib/asset/AssetModulesPlugin.js +92 -2
  36. package/lib/asset/WebManifestGenerator.js +164 -0
  37. package/lib/asset/WebManifestParser.js +130 -0
  38. package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
  39. package/lib/async-modules/isGeneratorLowered.js +26 -0
  40. package/lib/cache/PackFileCacheStrategy.js +9 -3
  41. package/lib/config/browserslistTargetHandler.js +40 -0
  42. package/lib/config/defaults.js +222 -32
  43. package/lib/config/normalization.js +26 -0
  44. package/lib/config/target.js +9 -1
  45. package/lib/css/CssGenerator.js +73 -73
  46. package/lib/css/CssLoadingRuntimeModule.js +5 -1
  47. package/lib/css/CssModulesPlugin.js +92 -53
  48. package/lib/css/CssParser.js +843 -302
  49. package/lib/css/syntax.js +1219 -483
  50. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
  51. package/lib/dependencies/AMDPlugin.js +2 -2
  52. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
  53. package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
  54. package/lib/dependencies/CommonJsExportsDependency.js +47 -2
  55. package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
  56. package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
  57. package/lib/dependencies/CommonJsPlugin.js +2 -2
  58. package/lib/dependencies/CommonJsRequireDependency.js +26 -1
  59. package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
  60. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  61. package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
  62. package/lib/dependencies/CssIcssExportDependency.js +190 -87
  63. package/lib/dependencies/CssUrlDependency.js +35 -4
  64. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
  65. package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
  66. package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
  67. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
  68. package/lib/dependencies/HarmonyImportDependency.js +12 -1
  69. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +34 -107
  70. package/lib/dependencies/HarmonyImportGuard.js +192 -20
  71. package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
  72. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
  73. package/lib/dependencies/HtmlEntryDependency.js +797 -172
  74. package/lib/dependencies/HtmlSourceDependency.js +26 -0
  75. package/lib/dependencies/ImportDependency.js +43 -1
  76. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
  77. package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
  78. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  79. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  80. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  81. package/lib/dependencies/ImportMetaPlugin.js +532 -180
  82. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  83. package/lib/dependencies/ImportParserPlugin.js +87 -26
  84. package/lib/dependencies/ImportPhase.js +10 -8
  85. package/lib/dependencies/LoaderPlugin.js +5 -1
  86. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  87. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
  88. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
  89. package/lib/dependencies/SystemPlugin.js +2 -4
  90. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  91. package/lib/dependencies/URLDependency.js +141 -21
  92. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
  93. package/lib/dependencies/WorkerDependency.js +86 -18
  94. package/lib/dependencies/WorkletDependency.js +278 -0
  95. package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
  96. package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
  97. package/lib/errors/LoaderLoadingError.js +20 -0
  98. package/lib/errors/ModuleParseError.js +39 -22
  99. package/lib/errors/NodeStuffInWebError.js +1 -1
  100. package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
  101. package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
  102. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
  103. package/lib/hmr/lazyCompilationBackend.js +32 -8
  104. package/lib/html/HtmlGenerator.js +940 -91
  105. package/lib/html/HtmlModule.js +3 -2
  106. package/lib/html/HtmlModulesPlugin.js +625 -170
  107. package/lib/html/HtmlParser.js +812 -340
  108. package/lib/html/favicon.svg +1 -0
  109. package/lib/html/syntax.js +2116 -834
  110. package/lib/ids/IdHelpers.js +1 -1
  111. package/lib/index.js +6 -0
  112. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
  113. package/lib/javascript/BasicEvaluatedExpression.js +366 -48
  114. package/lib/javascript/JavascriptGenerator.js +197 -49
  115. package/lib/javascript/JavascriptModulesPlugin.js +178 -24
  116. package/lib/javascript/JavascriptParser.js +711 -355
  117. package/lib/javascript/JavascriptParserHelpers.js +3 -6
  118. package/lib/javascript/syntax.js +4380 -0
  119. package/lib/library/ModuleLibraryPlugin.js +38 -1
  120. package/lib/loaders/LoaderRunner.js +714 -0
  121. package/lib/loaders/loadLoader.js +100 -0
  122. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +19 -0
  123. package/lib/node/ReadFileCompileWasmPlugin.js +14 -0
  124. package/lib/optimize/ConcatenatedModule.js +120 -16
  125. package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
  126. package/lib/optimize/InnerGraphPlugin.js +50 -30
  127. package/lib/optimize/ModuleConcatenationPlugin.js +69 -3
  128. package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
  129. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
  130. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
  131. package/lib/prefetch/ResourceHintPlugin.js +663 -0
  132. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  133. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  134. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  135. package/lib/rules/RuleSetCompiler.js +114 -0
  136. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  137. package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
  138. package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
  139. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  140. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  141. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
  142. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
  143. package/lib/schemes/HttpUriPlugin.js +40 -1
  144. package/lib/schemes/VirtualUrlPlugin.js +1 -2
  145. package/lib/serialization/FileMiddleware.js +29 -3
  146. package/lib/stats/DefaultStatsFactoryPlugin.js +32 -3
  147. package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
  148. package/lib/stats/DefaultStatsPrinterPlugin.js +12 -2
  149. package/lib/stats/StatsFactory.js +15 -8
  150. package/lib/url/URLParserPlugin.js +98 -19
  151. package/lib/util/AsyncQueue.js +122 -72
  152. package/lib/util/LocConverter.js +9 -8
  153. package/lib/util/SetHelpers.js +1 -1
  154. package/lib/util/SourceProcessor.js +41 -28
  155. package/lib/util/StackedMap.js +122 -48
  156. package/lib/util/binarySearchBounds.js +2 -2
  157. package/lib/util/concatenate.js +40 -14
  158. package/lib/util/createHooksRegistry.js +13 -5
  159. package/lib/util/dataURL.js +2 -2
  160. package/lib/util/deterministicGrouping.js +7 -5
  161. package/lib/util/formatSize.js +6 -2
  162. package/lib/util/globUtils.js +710 -0
  163. package/lib/util/identifier.js +23 -6
  164. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  165. package/lib/util/internalSerializables.js +88 -71
  166. package/lib/util/magicComment.js +121 -25
  167. package/lib/util/numberHash.js +2 -2
  168. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
  169. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
  170. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
  171. package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
  172. package/lib/web/FetchCompileWasmPlugin.js +14 -0
  173. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
  174. package/lib/webpack.js +65 -0
  175. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
  176. package/module.d.ts +21 -0
  177. package/package.json +14 -13
  178. package/schemas/WebpackOptions.check.js +1 -1
  179. package/schemas/WebpackOptions.json +759 -36
  180. package/schemas/plugins/HtmlParserOptions.check.js +1 -1
  181. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  182. package/schemas/plugins/ProgressPlugin.json +17 -1
  183. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  184. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  185. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  186. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  187. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  188. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  189. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  190. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  191. package/types.d.ts +1300 -325
@@ -10,7 +10,15 @@ const { RawSource, ReplaceSource } = require("webpack-sources");
10
10
  const Generator = require("../Generator");
11
11
  const InitFragment = require("../InitFragment");
12
12
  const { JAVASCRIPT_TYPES } = require("../ModuleSourceTypeConstants");
13
+ const RuntimeGlobals = require("../RuntimeGlobals");
14
+ const CommonJsExportsDependency = require("../dependencies/CommonJsExportsDependency");
15
+ const CommonJsFullRequireDependency = require("../dependencies/CommonJsFullRequireDependency");
16
+ const CommonJsRequireDependency = require("../dependencies/CommonJsRequireDependency");
17
+ const CommonJsSelfReferenceDependency = require("../dependencies/CommonJsSelfReferenceDependency");
18
+ const ContextDependency = require("../dependencies/ContextDependency");
13
19
  const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
20
+ const ImportDependency = require("../dependencies/ImportDependency");
21
+ const RequireResolveDependency = require("../dependencies/RequireResolveDependency");
14
22
 
15
23
  /** @typedef {import("webpack-sources").Source} Source */
16
24
  /** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
@@ -42,6 +50,143 @@ const DEFAULT_SOURCE = {
42
50
  // TODO: clean up this file
43
51
  // replace with newer constructs
44
52
 
53
+ // Runtime requirements whose presence on a presentational dependency means the
54
+ // code references the module/exports objects, which do not exist for an inner
55
+ // concatenated module (e.g. `module.id`, `module.hot`, top-level `this`).
56
+ /** @type {ReadonlySet<string>} */
57
+ const CONCATENATION_INCOMPATIBLE_RUNTIME_REQUIREMENTS = new Set([
58
+ RuntimeGlobals.module,
59
+ RuntimeGlobals.moduleId,
60
+ RuntimeGlobals.moduleLoaded,
61
+ RuntimeGlobals.moduleCache,
62
+ RuntimeGlobals.exports,
63
+ RuntimeGlobals.thisAsExports,
64
+ RuntimeGlobals.harmonyModuleDecorator,
65
+ RuntimeGlobals.nodeModuleDecorator
66
+ ]);
67
+
68
+ // A wrapped CommonJS module keeps real `module`/`exports` objects and top-level
69
+ // `this`, so only requirements that need a module object webpack does not
70
+ // synthesize here (id, loaded state, cache, decorators) block wrapping.
71
+ /** @type {ReadonlySet<string>} */
72
+ const WRAPPING_INCOMPATIBLE_RUNTIME_REQUIREMENTS = new Set([
73
+ RuntimeGlobals.moduleId,
74
+ RuntimeGlobals.moduleLoaded,
75
+ RuntimeGlobals.moduleCache,
76
+ RuntimeGlobals.harmonyModuleDecorator,
77
+ RuntimeGlobals.nodeModuleDecorator
78
+ ]);
79
+
80
+ /**
81
+ * Returns the reason a CommonJS module cannot take part in concatenation at
82
+ * all — neither hoisted (as a "nice" module) nor wrapped. A module passing
83
+ * this check can be hoisted or wrapped; {@link isCommonJsHoistable} decides
84
+ * which.
85
+ * @param {NormalModule} module the module
86
+ * @returns {string | undefined} reason it can't be concatenated
87
+ */
88
+ const getCommonJsConcatenationBailoutReason = (module) => {
89
+ const buildMeta = module.buildMeta;
90
+ // "flagged"/"default" are hoistable; a dynamic (undefined) exports type is a
91
+ // reassigned/computed `module.exports`, only reachable by wrapping. Proper ESM
92
+ // modules ("namespace") never reach this path.
93
+ if (
94
+ !buildMeta ||
95
+ (buildMeta.exportsType !== "flagged" &&
96
+ buildMeta.exportsType !== "default" &&
97
+ buildMeta.exportsType !== undefined)
98
+ ) {
99
+ return "Module is not an ECMAScript module";
100
+ }
101
+ // Sloppy-mode modules bail out in ModuleConcatenationPlugin anyway,
102
+ // so skip the dependency scan for them (most of node_modules)
103
+ if (!(/** @type {JavascriptModuleBuildInfo} */ (module.buildInfo).strict)) {
104
+ return "Module is not in strict mode";
105
+ }
106
+ const wrapped = !isCommonJsHoistable(module);
107
+ // A dynamic exports type only makes sense when wrapping; a hoistable module
108
+ // with no static exports keeps its previous (bailed) behavior.
109
+ if (buildMeta.exportsType === undefined && !wrapped) {
110
+ return "Module is not an ECMAScript module";
111
+ }
112
+ for (const dep of module.dependencies) {
113
+ if (
114
+ dep instanceof CommonJsExportsDependency ||
115
+ dep instanceof CommonJsSelfReferenceDependency
116
+ ) {
117
+ // Any export shape is fine: hoisted modules restrict these below,
118
+ // wrapped modules keep them verbatim inside the wrapper.
119
+ continue;
120
+ } else if (
121
+ dep instanceof CommonJsRequireDependency ||
122
+ dep instanceof CommonJsFullRequireDependency ||
123
+ dep instanceof RequireResolveDependency ||
124
+ dep instanceof ContextDependency
125
+ ) {
126
+ // A wrapped module renders with its own module ids intact, so a
127
+ // require() target that is itself inlined (no id) would break. Only
128
+ // hoisted ("nice") modules — whose require targets always stay
129
+ // external — may keep these.
130
+ if (wrapped) {
131
+ return `Module uses ${dep.type} which is not supported when wrapping`;
132
+ }
133
+ } else if (!(dep instanceof ImportDependency)) {
134
+ return `Module uses an unsupported dependency (${dep.type})`;
135
+ }
136
+ }
137
+ if (module.presentationalDependencies !== undefined) {
138
+ const incompatible = wrapped
139
+ ? WRAPPING_INCOMPATIBLE_RUNTIME_REQUIREMENTS
140
+ : CONCATENATION_INCOMPATIBLE_RUNTIME_REQUIREMENTS;
141
+ for (const dep of module.presentationalDependencies) {
142
+ const runtimeRequirements =
143
+ /** @type {{ runtimeRequirements?: ReadonlySet<string> | null }} */
144
+ (dep).runtimeRequirements;
145
+ if (!runtimeRequirements) continue;
146
+ for (const requirement of runtimeRequirements) {
147
+ if (incompatible.has(requirement)) {
148
+ return `Module uses ${requirement}`;
149
+ }
150
+ }
151
+ }
152
+ }
153
+ return undefined;
154
+ };
155
+
156
+ /**
157
+ * A "nice" CommonJS module has a static list of exports, assigned only via
158
+ * plain `exports.x = …` / `module.exports.x = …`, and never uses the
159
+ * `module`/`exports` objects in any other way, so every reference can be
160
+ * rewritten to a hoisted module-scope variable. Modules eligible for
161
+ * concatenation but not hoistable are wrapped instead.
162
+ * @param {NormalModule} module the module
163
+ * @returns {boolean} true when the module can be hoisted rather than wrapped
164
+ */
165
+ const isCommonJsHoistable = (module) => {
166
+ for (const dep of module.dependencies) {
167
+ if (dep instanceof CommonJsExportsDependency) {
168
+ if (dep.base !== "exports" && dep.base !== "module.exports") return false;
169
+ if (dep.names.length === 0) return false;
170
+ } else if (dep instanceof CommonJsSelfReferenceDependency) {
171
+ if (dep.base !== "exports" && dep.base !== "module.exports") return false;
172
+ if (dep.names.length === 0) return false;
173
+ // `exports.f()` passes the exports object as `this`
174
+ if (dep.call && dep.names.length === 1) return false;
175
+ }
176
+ }
177
+ return true;
178
+ };
179
+
180
+ /**
181
+ * Whether a concatenation-eligible CommonJS module must be wrapped (rendered
182
+ * inside an IIFE with real `module`/`exports` objects) rather than hoisted.
183
+ * @param {NormalModule} module the module
184
+ * @returns {boolean} true when the module needs wrapping
185
+ */
186
+ const isCommonJsWrapped = (module) =>
187
+ getCommonJsConcatenationBailoutReason(module) === undefined &&
188
+ !isCommonJsHoistable(module);
189
+
45
190
  const deprecatedGetInitFragments = util.deprecate(
46
191
  /**
47
192
  * Handles the callback logic for this hook.
@@ -88,7 +233,8 @@ class JavascriptGenerator extends Generator {
88
233
  * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
89
234
  */
90
235
  getConcatenationBailoutReason(module, context) {
91
- // Only harmony modules are valid for optimization
236
+ // Harmony modules and CommonJS modules with statically rewritable
237
+ // exports are valid for optimization
92
238
  if (
93
239
  !module.buildMeta ||
94
240
  module.buildMeta.exportsType !== "namespace" ||
@@ -97,7 +243,11 @@ class JavascriptGenerator extends Generator {
97
243
  (d) => d instanceof HarmonyCompatibilityDependency
98
244
  )
99
245
  ) {
100
- return "Module is not an ECMAScript module";
246
+ // CommonJS concatenation is opt-in via optimization.concatenateCommonJsModules
247
+ const reason = context.concatenateCommonJsModules
248
+ ? getCommonJsConcatenationBailoutReason(module)
249
+ : "Module is not an ECMAScript module";
250
+ if (reason !== undefined) return reason;
101
251
  }
102
252
 
103
253
  // Some expressions are not compatible with module concatenation
@@ -113,14 +263,13 @@ class JavascriptGenerator extends Generator {
113
263
 
114
264
  /**
115
265
  * Processes the provided module.
116
- * @param {Module} module the current module
117
266
  * @param {Dependency} dependency the dependency to generate
118
- * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
119
267
  * @param {ReplaceSource} source the current replace source which can be modified
268
+ * @param {DependencyTemplateContext} templateContext the template context shared for the whole module
120
269
  * @param {GenerateContext} generateContext the render context
121
270
  * @returns {void}
122
271
  */
123
- sourceDependency(module, dependency, initFragments, source, generateContext) {
272
+ sourceDependency(dependency, source, templateContext, generateContext) {
124
273
  const constructor =
125
274
  /** @type {DependencyConstructor} */
126
275
  (dependency.constructor);
@@ -131,39 +280,6 @@ class JavascriptGenerator extends Generator {
131
280
  );
132
281
  }
133
282
 
134
- /** @type {InitFragment<GenerateContext>[] | undefined} */
135
- let chunkInitFragments;
136
-
137
- /** @type {DependencyTemplateContext} */
138
- const templateContext = {
139
- runtimeTemplate: generateContext.runtimeTemplate,
140
- dependencyTemplates: generateContext.dependencyTemplates,
141
- moduleGraph: generateContext.moduleGraph,
142
- chunkGraph: generateContext.chunkGraph,
143
- module,
144
- runtime: generateContext.runtime,
145
- runtimeRequirements: generateContext.runtimeRequirements,
146
- concatenationScope: generateContext.concatenationScope,
147
- codeGenerationResults:
148
- /** @type {NonNullable<GenerateContext["codeGenerationResults"]>} */
149
- (generateContext.codeGenerationResults),
150
- initFragments,
151
- get chunkInitFragments() {
152
- if (!chunkInitFragments) {
153
- const data =
154
- /** @type {NonNullable<GenerateContext["getData"]>} */
155
- (generateContext.getData)();
156
- chunkInitFragments = data.get("chunkInitFragments");
157
- if (!chunkInitFragments) {
158
- chunkInitFragments = [];
159
- data.set("chunkInitFragments", chunkInitFragments);
160
- }
161
- }
162
-
163
- return chunkInitFragments;
164
- }
165
- };
166
-
167
283
  template.apply(dependency, source, templateContext);
168
284
 
169
285
  // TODO remove in webpack 6
@@ -176,7 +292,7 @@ class JavascriptGenerator extends Generator {
176
292
 
177
293
  if (fragments) {
178
294
  for (const fragment of fragments) {
179
- initFragments.push(fragment);
295
+ templateContext.initFragments.push(fragment);
180
296
  }
181
297
  }
182
298
  }
@@ -186,18 +302,17 @@ class JavascriptGenerator extends Generator {
186
302
  * Processes the provided module.
187
303
  * @param {Module} module the module to generate
188
304
  * @param {DependenciesBlock} block the dependencies block which will be processed
189
- * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
305
+ * @param {DependencyTemplateContext} templateContext the template context shared for the whole module
190
306
  * @param {ReplaceSource} source the current replace source which can be modified
191
307
  * @param {GenerateContext} generateContext the generateContext
192
308
  * @returns {void}
193
309
  */
194
- sourceBlock(module, block, initFragments, source, generateContext) {
310
+ sourceBlock(module, block, templateContext, source, generateContext) {
195
311
  for (const dependency of block.dependencies) {
196
312
  this.sourceDependency(
197
- module,
198
313
  dependency,
199
- initFragments,
200
314
  source,
315
+ templateContext,
201
316
  generateContext
202
317
  );
203
318
  }
@@ -206,7 +321,7 @@ class JavascriptGenerator extends Generator {
206
321
  this.sourceBlock(
207
322
  module,
208
323
  childBlock,
209
- initFragments,
324
+ templateContext,
210
325
  source,
211
326
  generateContext
212
327
  );
@@ -222,12 +337,45 @@ class JavascriptGenerator extends Generator {
222
337
  * @returns {void}
223
338
  */
224
339
  sourceModule(module, initFragments, source, generateContext) {
340
+ /** @type {InitFragment<GenerateContext>[] | undefined} */
341
+ let chunkInitFragments;
342
+
343
+ // one template context for all dependencies of the module (hot path)
344
+ /** @type {DependencyTemplateContext} */
345
+ const templateContext = {
346
+ runtimeTemplate: generateContext.runtimeTemplate,
347
+ dependencyTemplates: generateContext.dependencyTemplates,
348
+ moduleGraph: generateContext.moduleGraph,
349
+ chunkGraph: generateContext.chunkGraph,
350
+ module,
351
+ runtime: generateContext.runtime,
352
+ runtimeRequirements: generateContext.runtimeRequirements,
353
+ concatenationScope: generateContext.concatenationScope,
354
+ codeGenerationResults:
355
+ /** @type {NonNullable<GenerateContext["codeGenerationResults"]>} */
356
+ (generateContext.codeGenerationResults),
357
+ initFragments,
358
+ get chunkInitFragments() {
359
+ if (!chunkInitFragments) {
360
+ const data =
361
+ /** @type {NonNullable<GenerateContext["getData"]>} */
362
+ (generateContext.getData)();
363
+ chunkInitFragments = data.get("chunkInitFragments");
364
+ if (!chunkInitFragments) {
365
+ chunkInitFragments = [];
366
+ data.set("chunkInitFragments", chunkInitFragments);
367
+ }
368
+ }
369
+
370
+ return chunkInitFragments;
371
+ }
372
+ };
373
+
225
374
  for (const dependency of module.dependencies) {
226
375
  this.sourceDependency(
227
- module,
228
376
  dependency,
229
- initFragments,
230
377
  source,
378
+ templateContext,
231
379
  generateContext
232
380
  );
233
381
  }
@@ -235,10 +383,9 @@ class JavascriptGenerator extends Generator {
235
383
  if (module.presentationalDependencies !== undefined) {
236
384
  for (const dependency of module.presentationalDependencies) {
237
385
  this.sourceDependency(
238
- module,
239
386
  dependency,
240
- initFragments,
241
387
  source,
388
+ templateContext,
242
389
  generateContext
243
390
  );
244
391
  }
@@ -248,7 +395,7 @@ class JavascriptGenerator extends Generator {
248
395
  this.sourceBlock(
249
396
  module,
250
397
  childBlock,
251
- initFragments,
398
+ templateContext,
252
399
  source,
253
400
  generateContext
254
401
  );
@@ -289,3 +436,4 @@ class JavascriptGenerator extends Generator {
289
436
  }
290
437
 
291
438
  module.exports = JavascriptGenerator;
439
+ module.exports.isCommonJsWrapped = isCommonJsWrapped;
@@ -46,6 +46,7 @@ const createHooksRegistry = require("../util/createHooksRegistry");
46
46
  const { digestNonNumericOnlyWithFull } = require("../util/nonNumericOnlyHash");
47
47
  const removeBOM = require("../util/removeBOM");
48
48
  const { intersectRuntime } = require("../util/runtime");
49
+ const { getAllChunks } = require("./ChunkHelpers");
49
50
  const JavascriptGenerator = require("./JavascriptGenerator");
50
51
  const JavascriptModule = require("./JavascriptModule");
51
52
  const JavascriptParser = require("./JavascriptParser");
@@ -283,6 +284,8 @@ const printGeneratedCodeForStack = (module, code) => {
283
284
  * @property {CodeGenerationResults} codeGenerationResults results of code generation
284
285
  * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
285
286
  * @property {boolean | undefined} strictMode rendering in strict context
287
+ * @property {Module=} inlinedEntryModule entry module inlined at the chunk top level instead of the registry
288
+ * @property {Source=} inlinedEntrySource rendered body of the inlined entry module
286
289
  */
287
290
 
288
291
  /**
@@ -455,19 +458,31 @@ class JavascriptModulesPlugin {
455
458
  case JAVASCRIPT_MODULE_TYPE_AUTO: {
456
459
  return new JavascriptParser("auto", {
457
460
  parse: options.parse,
458
- typescript: options.typescript
461
+ typescript: options.typescript,
462
+ importPhases: Boolean(
463
+ options.deferImport || options.sourceImport
464
+ ),
465
+ strictModeViolations: options.strictModeViolations
459
466
  });
460
467
  }
461
468
  case JAVASCRIPT_MODULE_TYPE_DYNAMIC: {
462
469
  return new JavascriptParser("script", {
463
470
  parse: options.parse,
464
- typescript: options.typescript
471
+ typescript: options.typescript,
472
+ importPhases: Boolean(
473
+ options.deferImport || options.sourceImport
474
+ ),
475
+ strictModeViolations: options.strictModeViolations
465
476
  });
466
477
  }
467
478
  case JAVASCRIPT_MODULE_TYPE_ESM: {
468
479
  return new JavascriptParser("module", {
469
480
  parse: options.parse,
470
- typescript: options.typescript
481
+ typescript: options.typescript,
482
+ importPhases: Boolean(
483
+ options.deferImport || options.sourceImport
484
+ ),
485
+ strictModeViolations: options.strictModeViolations
471
486
  });
472
487
  }
473
488
  }
@@ -945,10 +960,30 @@ class JavascriptModulesPlugin {
945
960
  chunkInitFragments: [],
946
961
  strictMode: allStrict
947
962
  };
963
+ // ESM entry chunk whose runtime lives in a separate chunk: inline the
964
+ // single entry module at the top level (instead of the module registry)
965
+ // so its own top-level declarations stay live ESM bindings for consumers.
966
+ const inlinedEntryModule = this._getEsmEntryModuleToInline(
967
+ renderContext,
968
+ allModules
969
+ );
970
+ let registryModules = allModules;
971
+ if (inlinedEntryModule) {
972
+ const inlinedEntrySource = this.renderModule(
973
+ inlinedEntryModule,
974
+ { ...chunkRenderContext, factory: false },
975
+ hooks
976
+ );
977
+ if (inlinedEntrySource) {
978
+ registryModules = allModules.filter((m) => m !== inlinedEntryModule);
979
+ chunkRenderContext.inlinedEntryModule = inlinedEntryModule;
980
+ chunkRenderContext.inlinedEntrySource = inlinedEntrySource;
981
+ }
982
+ }
948
983
  const moduleSources =
949
984
  Template.renderChunkModules(
950
985
  chunkRenderContext,
951
- allModules,
986
+ registryModules,
952
987
  (module, renderInObject) =>
953
988
  this.renderModule(
954
989
  module,
@@ -991,6 +1026,92 @@ class JavascriptModulesPlugin {
991
1026
  : new ConcatSource(source, ";");
992
1027
  }
993
1028
 
1029
+ /**
1030
+ * Returns the chunk's single entry module when it can be inlined at the top
1031
+ * level of an ESM output chunk (instead of the module registry), which keeps
1032
+ * its exports as live ESM bindings. Only a self-contained ESM entry whose
1033
+ * top-level declarations can be lifted into the chunk scope qualifies;
1034
+ * otherwise `undefined` is returned and the registry path is used.
1035
+ * @param {RenderContext} renderContext render context
1036
+ * @param {Module[]} allModules all javascript modules of the chunk
1037
+ * @returns {Module | undefined} the entry module to inline, if any
1038
+ */
1039
+ _getEsmEntryModuleToInline(renderContext, allModules) {
1040
+ const {
1041
+ chunk,
1042
+ chunkGraph,
1043
+ moduleGraph,
1044
+ runtimeTemplate,
1045
+ codeGenerationResults
1046
+ } = renderContext;
1047
+
1048
+ // Only a single ESM entry whose runtime lives in a separate chunk.
1049
+ if (
1050
+ !runtimeTemplate.isModule() ||
1051
+ chunk.hasRuntime() ||
1052
+ chunkGraph.getNumberOfEntryModules(chunk) !== 1
1053
+ ) {
1054
+ return undefined;
1055
+ }
1056
+ const [entryEntry] =
1057
+ chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk);
1058
+ const [entryModule, entrypoint] = /** @type {[Module, Entrypoint]} */ (
1059
+ entryEntry
1060
+ );
1061
+
1062
+ // Module-local safety: the body is lifted verbatim, so it must use the
1063
+ // standard exports binding (not `module`/`this`) and expose top-level
1064
+ // declarations whose names can't collide with runtime/startup identifiers.
1065
+ const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
1066
+ entryModule,
1067
+ chunk.runtime
1068
+ );
1069
+ if (
1070
+ entryModule.exportsArgument !== RuntimeGlobals.exports ||
1071
+ runtimeRequirements.has(RuntimeGlobals.module) ||
1072
+ runtimeRequirements.has(RuntimeGlobals.thisAsExports)
1073
+ ) {
1074
+ return undefined;
1075
+ }
1076
+ const topLevelDeclarations =
1077
+ codeGenerationResults.getData(
1078
+ entryModule,
1079
+ chunk.runtime,
1080
+ "topLevelDeclarations"
1081
+ ) ||
1082
+ (entryModule.buildInfo && entryModule.buildInfo.topLevelDeclarations);
1083
+ if (!topLevelDeclarations || topLevelDeclarations.size === 0) {
1084
+ return undefined;
1085
+ }
1086
+ for (const name of topLevelDeclarations) {
1087
+ if (RESERVED_NAMES.has(name) || name.startsWith("__webpack_")) {
1088
+ return undefined;
1089
+ }
1090
+ }
1091
+
1092
+ // Self-contained: the entry must not be imported by another module (which
1093
+ // needs it in the registry), and must not require other chunks or
1094
+ // `dependOn` parents to execute first.
1095
+ if (
1096
+ entrypoint.getParents().length > 0 ||
1097
+ getAllChunks(entrypoint, chunk, entrypoint.getRuntimeChunk()).size > 0
1098
+ ) {
1099
+ return undefined;
1100
+ }
1101
+ const referenced = someInIterable(
1102
+ moduleGraph.getIncomingConnectionsByOriginModule(entryModule),
1103
+ ([originModule, connections]) =>
1104
+ originModule &&
1105
+ originModule !== entryModule &&
1106
+ connections.some((c) => c.isTargetActive(chunk.runtime)) &&
1107
+ someInIterable(
1108
+ chunkGraph.getModuleRuntimes(originModule),
1109
+ (runtime) => intersectRuntime(runtime, chunk.runtime) !== undefined
1110
+ )
1111
+ );
1112
+ return referenced ? undefined : entryModule;
1113
+ }
1114
+
994
1115
  /**
995
1116
  * Renders the newly generated source from rendering.
996
1117
  * @param {MainRenderContext} renderContext options object
@@ -1044,9 +1165,7 @@ class JavascriptModulesPlugin {
1044
1165
  const strictBailout = hooks.strictRuntimeBailout.call(renderContext);
1045
1166
  if (strictBailout) {
1046
1167
  source.add(
1047
- `${
1048
- prefix
1049
- }// runtime can't be in strict mode because ${strictBailout}.\n`
1168
+ `${prefix}// runtime can't be in strict mode because ${strictBailout}.\n`
1050
1169
  );
1051
1170
  } else {
1052
1171
  allStrict = true;
@@ -1220,7 +1339,9 @@ class JavascriptModulesPlugin {
1220
1339
  );
1221
1340
  } else if (m.exportsArgument !== RuntimeGlobals.exports) {
1222
1341
  startupSource.add(
1223
- `${runtimeTemplate.renderLet()} ${m.exportsArgument} = ${RuntimeGlobals.exports};\n`
1342
+ `${runtimeTemplate.renderLet()} ${m.exportsArgument} = ${
1343
+ RuntimeGlobals.exports
1344
+ };\n`
1224
1345
  );
1225
1346
  }
1226
1347
  }
@@ -1660,9 +1781,13 @@ class JavascriptModulesPlugin {
1660
1781
  (() => {
1661
1782
  if (needThisAsExports) {
1662
1783
  const comma = args.length ? "," : "";
1663
- return `__webpack_modules__[${moduleIdExpr}].call(${RuntimeGlobals.exports}${comma}${args.join(",")});`;
1784
+ return `__webpack_modules__[${moduleIdExpr}].call(${
1785
+ RuntimeGlobals.exports
1786
+ }${comma}${args.join(",")});`;
1664
1787
  }
1665
- return `__webpack_modules__[${moduleIdExpr}](${args.join(",")});`;
1788
+ return `__webpack_modules__[${moduleIdExpr}](${args.join(
1789
+ ","
1790
+ )});`;
1666
1791
  })()
1667
1792
  )
1668
1793
  );
@@ -1802,6 +1927,18 @@ class JavascriptModulesPlugin {
1802
1927
  const needModuleDefer = runtimeRequirements.has(
1803
1928
  RuntimeGlobals.makeDeferredNamespaceObject
1804
1929
  );
1930
+ // Both deferred-namespace runtimes re-invoke `__webpack_require__` on
1931
+ // access, so a module's evaluation error must be retained and re-thrown
1932
+ // (a Cyclic Module Record's [[EvaluationError]]); the optimized variant
1933
+ // does not use `__webpack_module_deferred_exports__`, so it is tracked
1934
+ // separately from `needModuleDefer`.
1935
+ const needModuleDeferAny =
1936
+ needModuleDefer ||
1937
+ runtimeRequirements.has(
1938
+ RuntimeGlobals.makeOptimizedDeferredNamespaceObject
1939
+ );
1940
+ const needModuleErrorCaching =
1941
+ outputOptions.strictModuleErrorHandling || needModuleDeferAny;
1805
1942
  // `module` is reassigned by the interceptModuleExecution path; use `let`.
1806
1943
  const moduleDecl = runtimeRequirements.has(
1807
1944
  RuntimeGlobals.interceptModuleExecution
@@ -1812,7 +1949,7 @@ class JavascriptModulesPlugin {
1812
1949
  "// Check if module is in cache",
1813
1950
  `${cst} cachedModule = __webpack_module_cache__[moduleId];`,
1814
1951
  "if (cachedModule !== undefined) {",
1815
- outputOptions.strictModuleErrorHandling
1952
+ needModuleErrorCaching
1816
1953
  ? Template.indent([
1817
1954
  "if (cachedModule.error !== undefined) throw cachedModule.error;",
1818
1955
  "return cachedModule.exports;"
@@ -1830,7 +1967,7 @@ class JavascriptModulesPlugin {
1830
1967
  ]),
1831
1968
  "};",
1832
1969
  "",
1833
- outputOptions.strictModuleExceptionHandling
1970
+ outputOptions.strictModuleExceptionHandling && !needModuleErrorCaching
1834
1971
  ? Template.asString([
1835
1972
  "// Execute the module function",
1836
1973
  `${lt} threw = true;`,
@@ -1848,20 +1985,27 @@ class JavascriptModulesPlugin {
1848
1985
  ]),
1849
1986
  "}"
1850
1987
  ])
1851
- : outputOptions.strictModuleErrorHandling
1988
+ : needModuleErrorCaching
1852
1989
  ? Template.asString([
1853
1990
  "// Execute the module function",
1991
+ // Mark the module as evaluating so a deferred namespace that
1992
+ // forces evaluation of an already-evaluating module can throw
1993
+ // instead of exposing its partial exports.
1994
+ ...(needModuleDeferAny ? ["module.evaluating = true;"] : []),
1854
1995
  "try {",
1855
- Template.indent(
1856
- needModuleDefer
1857
- ? [
1858
- moduleExecution,
1859
- "delete __webpack_module_deferred_exports__[moduleId];"
1860
- ]
1861
- : moduleExecution
1862
- ),
1996
+ Template.indent([
1997
+ moduleExecution,
1998
+ ...(needModuleDefer
1999
+ ? ["delete __webpack_module_deferred_exports__[moduleId];"]
2000
+ : []),
2001
+ ...(needModuleDeferAny ? ["module.evaluating = false;"] : [])
2002
+ ]),
1863
2003
  "} catch(e) {",
1864
- Template.indent(["module.error = e;", "throw e;"]),
2004
+ Template.indent([
2005
+ ...(needModuleDeferAny ? ["module.evaluating = false;"] : []),
2006
+ "module.error = e;",
2007
+ "throw e;"
2008
+ ]),
1865
2009
  "}"
1866
2010
  ])
1867
2011
  : Template.asString([
@@ -1956,11 +2100,16 @@ class JavascriptModulesPlugin {
1956
2100
  }
1957
2101
  const code = /** @type {string} */ (moduleSource.source());
1958
2102
 
2103
+ const { experiments } = compilation.options;
1959
2104
  const { ast } = JavascriptParser._parse(
1960
2105
  code,
1961
2106
  {
1962
2107
  sourceType: "auto",
1963
- ranges: true
2108
+ ranges: true,
2109
+ // generated code contains phase imports when the experiments are on
2110
+ importPhases: Boolean(
2111
+ experiments.deferImport || experiments.sourceImport
2112
+ )
1964
2113
  },
1965
2114
  JavascriptParser._getModuleParseFunction(compilation, m)
1966
2115
  );
@@ -2028,11 +2177,16 @@ class JavascriptModulesPlugin {
2028
2177
  for (const [m, moduleSource] of inlinedModuleSources) {
2029
2178
  const code = /** @type {string} */ (moduleSource.source());
2030
2179
 
2180
+ const { experiments } = compilation.options;
2031
2181
  const { ast } = JavascriptParser._parse(
2032
2182
  code,
2033
2183
  {
2034
2184
  sourceType: "auto",
2035
- ranges: true
2185
+ ranges: true,
2186
+ // generated code contains phase imports when the experiments are on
2187
+ importPhases: Boolean(
2188
+ experiments.deferImport || experiments.sourceImport
2189
+ )
2036
2190
  },
2037
2191
  JavascriptParser._getModuleParseFunction(compilation, m)
2038
2192
  );