webpack 5.59.0 → 5.76.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (236) hide show
  1. package/README.md +22 -24
  2. package/bin/webpack.js +0 -0
  3. package/hot/dev-server.js +17 -4
  4. package/hot/lazy-compilation-node.js +3 -1
  5. package/hot/poll.js +1 -1
  6. package/hot/signal.js +1 -1
  7. package/lib/APIPlugin.js +33 -0
  8. package/lib/BannerPlugin.js +13 -5
  9. package/lib/Cache.js +1 -1
  10. package/lib/CacheFacade.js +4 -11
  11. package/lib/Chunk.js +6 -3
  12. package/lib/ChunkGraph.js +94 -8
  13. package/lib/ChunkGroup.js +1 -1
  14. package/lib/CleanPlugin.js +81 -20
  15. package/lib/Compilation.js +188 -93
  16. package/lib/Compiler.js +87 -18
  17. package/lib/ConstPlugin.js +2 -2
  18. package/lib/ContextModule.js +142 -51
  19. package/lib/ContextModuleFactory.js +65 -25
  20. package/lib/DelegatedModule.js +1 -1
  21. package/lib/DelegatedModuleFactoryPlugin.js +1 -1
  22. package/lib/Dependency.js +17 -0
  23. package/lib/DependencyTemplate.js +9 -0
  24. package/lib/DependencyTemplates.js +1 -1
  25. package/lib/DllModule.js +1 -1
  26. package/lib/DllReferencePlugin.js +1 -1
  27. package/lib/EntryOptionPlugin.js +2 -0
  28. package/lib/ErrorHelpers.js +2 -2
  29. package/lib/EvalDevToolModulePlugin.js +16 -1
  30. package/lib/EvalSourceMapDevToolPlugin.js +25 -4
  31. package/lib/ExportsInfo.js +5 -5
  32. package/lib/ExternalModule.js +94 -54
  33. package/lib/ExternalModuleFactoryPlugin.js +5 -5
  34. package/lib/FileSystemInfo.js +124 -58
  35. package/lib/Generator.js +3 -0
  36. package/lib/HookWebpackError.js +1 -1
  37. package/lib/HotModuleReplacementPlugin.js +3 -1
  38. package/lib/LoaderOptionsPlugin.js +1 -1
  39. package/lib/Module.js +28 -4
  40. package/lib/ModuleFilenameHelpers.js +8 -4
  41. package/lib/ModuleHashingError.js +29 -0
  42. package/lib/MultiCompiler.js +1 -1
  43. package/lib/MultiWatching.js +1 -1
  44. package/lib/NodeStuffPlugin.js +13 -3
  45. package/lib/NormalModule.js +51 -33
  46. package/lib/NormalModuleFactory.js +42 -37
  47. package/lib/ProgressPlugin.js +4 -5
  48. package/lib/RawModule.js +1 -1
  49. package/lib/RuntimeGlobals.js +29 -1
  50. package/lib/RuntimeModule.js +1 -1
  51. package/lib/RuntimePlugin.js +84 -1
  52. package/lib/RuntimeTemplate.js +114 -2
  53. package/lib/Template.js +3 -2
  54. package/lib/TemplatedPathPlugin.js +48 -23
  55. package/lib/WatchIgnorePlugin.js +19 -7
  56. package/lib/Watching.js +33 -19
  57. package/lib/WebpackOptionsApply.js +79 -11
  58. package/lib/asset/AssetGenerator.js +228 -71
  59. package/lib/asset/AssetModulesPlugin.js +3 -0
  60. package/lib/asset/AssetParser.js +1 -0
  61. package/lib/asset/AssetSourceGenerator.js +31 -6
  62. package/lib/asset/AssetSourceParser.js +1 -0
  63. package/lib/asset/RawDataUrlModule.js +148 -0
  64. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -4
  65. package/lib/buildChunkGraph.js +38 -7
  66. package/lib/cache/PackFileCacheStrategy.js +15 -8
  67. package/lib/cache/ResolverCachePlugin.js +90 -29
  68. package/lib/cli.js +44 -3
  69. package/lib/config/browserslistTargetHandler.js +41 -6
  70. package/lib/config/defaults.js +123 -19
  71. package/lib/config/normalization.js +10 -2
  72. package/lib/config/target.js +10 -0
  73. package/lib/container/ContainerEntryModule.js +8 -5
  74. package/lib/container/FallbackModule.js +4 -4
  75. package/lib/container/ModuleFederationPlugin.js +2 -0
  76. package/lib/container/RemoteModule.js +4 -2
  77. package/lib/container/RemoteRuntimeModule.js +8 -7
  78. package/lib/css/CssExportsGenerator.js +139 -0
  79. package/lib/css/CssGenerator.js +109 -0
  80. package/lib/css/CssLoadingRuntimeModule.js +442 -0
  81. package/lib/css/CssModulesPlugin.js +462 -0
  82. package/lib/css/CssParser.js +618 -0
  83. package/lib/css/walkCssTokens.js +659 -0
  84. package/lib/debug/ProfilingPlugin.js +24 -21
  85. package/lib/dependencies/AMDRequireDependency.js +6 -6
  86. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
  87. package/lib/dependencies/CommonJsFullRequireDependency.js +5 -1
  88. package/lib/dependencies/CommonJsImportsParserPlugin.js +344 -61
  89. package/lib/dependencies/CommonJsRequireContextDependency.js +6 -2
  90. package/lib/dependencies/CommonJsRequireDependency.js +2 -1
  91. package/lib/dependencies/ContextDependency.js +16 -2
  92. package/lib/dependencies/ContextDependencyHelpers.js +21 -8
  93. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +4 -1
  94. package/lib/dependencies/ContextElementDependency.js +25 -3
  95. package/lib/dependencies/CreateScriptUrlDependency.js +12 -0
  96. package/lib/dependencies/CssExportDependency.js +85 -0
  97. package/lib/dependencies/CssImportDependency.js +75 -0
  98. package/lib/dependencies/CssLocalIdentifierDependency.js +119 -0
  99. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +101 -0
  100. package/lib/dependencies/CssUrlDependency.js +132 -0
  101. package/lib/dependencies/ExportsInfoDependency.js +6 -0
  102. package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
  103. package/lib/dependencies/HarmonyCompatibilityDependency.js +5 -5
  104. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +127 -0
  105. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +12 -3
  106. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +25 -17
  107. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  108. package/lib/dependencies/HarmonyImportDependency.js +23 -0
  109. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +142 -45
  110. package/lib/dependencies/HarmonyImportSpecifierDependency.js +46 -22
  111. package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
  112. package/lib/dependencies/ImportContextDependency.js +0 -2
  113. package/lib/dependencies/ImportMetaContextDependency.js +35 -0
  114. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
  115. package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
  116. package/lib/dependencies/ImportMetaPlugin.js +22 -3
  117. package/lib/dependencies/ImportParserPlugin.js +35 -29
  118. package/lib/dependencies/JsonExportsDependency.js +17 -21
  119. package/lib/dependencies/LoaderDependency.js +13 -0
  120. package/lib/dependencies/LoaderImportDependency.js +13 -0
  121. package/lib/dependencies/LoaderPlugin.js +4 -2
  122. package/lib/dependencies/ModuleDependency.js +11 -1
  123. package/lib/dependencies/ProvidedDependency.js +31 -8
  124. package/lib/dependencies/RequireContextDependency.js +0 -16
  125. package/lib/dependencies/RequireEnsureDependency.js +2 -2
  126. package/lib/dependencies/RequireResolveContextDependency.js +2 -2
  127. package/lib/dependencies/RequireResolveDependency.js +2 -1
  128. package/lib/dependencies/URLDependency.js +3 -8
  129. package/lib/dependencies/URLPlugin.js +22 -1
  130. package/lib/dependencies/WorkerPlugin.js +2 -0
  131. package/lib/esm/ModuleChunkFormatPlugin.js +74 -49
  132. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  133. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +25 -9
  134. package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
  135. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
  136. package/lib/hmr/LazyCompilationPlugin.js +54 -26
  137. package/lib/hmr/lazyCompilationBackend.js +51 -12
  138. package/lib/ids/DeterministicModuleIdsPlugin.js +55 -35
  139. package/lib/ids/HashedModuleIdsPlugin.js +11 -14
  140. package/lib/ids/IdHelpers.js +26 -12
  141. package/lib/ids/NamedModuleIdsPlugin.js +6 -9
  142. package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
  143. package/lib/ids/OccurrenceModuleIdsPlugin.js +13 -10
  144. package/lib/ids/SyncModuleIdsPlugin.js +140 -0
  145. package/lib/index.js +20 -0
  146. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +2 -2
  147. package/lib/javascript/BasicEvaluatedExpression.js +5 -2
  148. package/lib/javascript/ChunkHelpers.js +33 -0
  149. package/lib/javascript/JavascriptGenerator.js +1 -0
  150. package/lib/javascript/JavascriptModulesPlugin.js +27 -2
  151. package/lib/javascript/JavascriptParser.js +143 -73
  152. package/lib/javascript/StartupHelpers.js +7 -30
  153. package/lib/json/JsonData.js +8 -0
  154. package/lib/json/JsonParser.js +4 -6
  155. package/lib/library/AssignLibraryPlugin.js +39 -15
  156. package/lib/library/EnableLibraryPlugin.js +11 -0
  157. package/lib/library/UmdLibraryPlugin.js +5 -3
  158. package/lib/node/NodeTargetPlugin.js +3 -0
  159. package/lib/node/NodeWatchFileSystem.js +85 -31
  160. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +23 -8
  161. package/lib/node/RequireChunkLoadingRuntimeModule.js +24 -9
  162. package/lib/optimize/ConcatenatedModule.js +62 -26
  163. package/lib/optimize/ModuleConcatenationPlugin.js +26 -4
  164. package/lib/optimize/RealContentHashPlugin.js +45 -15
  165. package/lib/optimize/SplitChunksPlugin.js +8 -1
  166. package/lib/runtime/AsyncModuleRuntimeModule.js +50 -66
  167. package/lib/runtime/BaseUriRuntimeModule.js +31 -0
  168. package/lib/runtime/CreateScriptRuntimeModule.js +36 -0
  169. package/lib/runtime/CreateScriptUrlRuntimeModule.js +9 -34
  170. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +76 -0
  171. package/lib/runtime/LoadScriptRuntimeModule.js +11 -9
  172. package/lib/runtime/NonceRuntimeModule.js +24 -0
  173. package/lib/schemes/HttpUriPlugin.js +77 -14
  174. package/lib/serialization/FileMiddleware.js +44 -9
  175. package/lib/sharing/ConsumeSharedModule.js +8 -2
  176. package/lib/sharing/ConsumeSharedRuntimeModule.js +26 -5
  177. package/lib/sharing/ProvideSharedModule.js +4 -2
  178. package/lib/sharing/ProvideSharedPlugin.js +1 -2
  179. package/lib/sharing/ShareRuntimeModule.js +1 -1
  180. package/lib/sharing/utils.js +1 -1
  181. package/lib/stats/DefaultStatsFactoryPlugin.js +113 -68
  182. package/lib/stats/DefaultStatsPrinterPlugin.js +90 -25
  183. package/lib/util/ArrayHelpers.js +30 -0
  184. package/lib/util/AsyncQueue.js +1 -1
  185. package/lib/util/compileBooleanMatcher.js +1 -1
  186. package/lib/util/create-schema-validation.js +9 -2
  187. package/lib/util/createHash.js +12 -0
  188. package/lib/util/deprecation.js +10 -2
  189. package/lib/util/deterministicGrouping.js +1 -1
  190. package/lib/util/extractUrlAndGlobal.js +3 -0
  191. package/lib/util/fs.js +11 -0
  192. package/lib/util/hash/BatchedHash.js +7 -4
  193. package/lib/util/hash/md4.js +20 -0
  194. package/lib/util/hash/wasm-hash.js +163 -0
  195. package/lib/util/hash/xxhash64.js +5 -139
  196. package/lib/util/identifier.js +65 -44
  197. package/lib/util/internalSerializables.js +15 -0
  198. package/lib/util/nonNumericOnlyHash.js +22 -0
  199. package/lib/util/semver.js +17 -10
  200. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +9 -3
  201. package/lib/wasm-sync/WebAssemblyParser.js +1 -1
  202. package/lib/web/JsonpChunkLoadingRuntimeModule.js +31 -18
  203. package/lib/webpack.js +10 -3
  204. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -11
  205. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +33 -22
  206. package/module.d.ts +215 -0
  207. package/package.json +28 -32
  208. package/schemas/WebpackOptions.check.js +1 -1
  209. package/schemas/WebpackOptions.json +321 -30
  210. package/schemas/plugins/BannerPlugin.check.js +1 -1
  211. package/schemas/plugins/BannerPlugin.json +4 -0
  212. package/schemas/plugins/DllReferencePlugin.check.js +1 -1
  213. package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
  214. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  215. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  216. package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
  217. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  218. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  219. package/schemas/plugins/container/ContainerPlugin.json +2 -1
  220. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  221. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  222. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  223. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  224. package/schemas/plugins/container/ModuleFederationPlugin.json +3 -1
  225. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
  226. package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
  227. package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
  228. package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
  229. package/schemas/plugins/css/CssParserOptions.check.js +6 -0
  230. package/schemas/plugins/css/CssParserOptions.json +3 -0
  231. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
  232. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
  233. package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
  234. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  235. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  236. package/types.d.ts +869 -296
@@ -5,18 +5,16 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { ConcatSource, RawSource } = require("webpack-sources");
8
+ const { ConcatSource } = require("webpack-sources");
9
9
  const { RuntimeGlobals } = require("..");
10
10
  const HotUpdateChunk = require("../HotUpdateChunk");
11
11
  const Template = require("../Template");
12
+ const { getAllChunks } = require("../javascript/ChunkHelpers");
12
13
  const {
13
14
  getCompilationHooks,
14
15
  getChunkFilenameTemplate
15
16
  } = require("../javascript/JavascriptModulesPlugin");
16
- const {
17
- generateEntryStartup,
18
- updateHashForEntryStartup
19
- } = require("../javascript/StartupHelpers");
17
+ const { updateHashForEntryStartup } = require("../javascript/StartupHelpers");
20
18
 
21
19
  /** @typedef {import("../Compiler")} Compiler */
22
20
 
@@ -84,63 +82,90 @@ class ModuleChunkFormatPlugin {
84
82
  }
85
83
  )
86
84
  .split("/");
87
- const runtimeOutputName = compilation
88
- .getPath(
89
- getChunkFilenameTemplate(
90
- runtimeChunk,
91
- compilation.outputOptions
92
- ),
93
- {
94
- chunk: runtimeChunk,
95
- contentHashType: "javascript"
96
- }
97
- )
98
- .split("/");
99
85
 
100
86
  // remove filename, we only need the directory
101
- const outputFilename = currentOutputName.pop();
87
+ currentOutputName.pop();
102
88
 
103
- // remove common parts
104
- while (
105
- currentOutputName.length > 0 &&
106
- runtimeOutputName.length > 0 &&
107
- currentOutputName[0] === runtimeOutputName[0]
108
- ) {
109
- currentOutputName.shift();
110
- runtimeOutputName.shift();
111
- }
89
+ const getRelativePath = chunk => {
90
+ const baseOutputName = currentOutputName.slice();
91
+ const chunkOutputName = compilation
92
+ .getPath(
93
+ getChunkFilenameTemplate(
94
+ chunk,
95
+ compilation.outputOptions
96
+ ),
97
+ {
98
+ chunk: chunk,
99
+ contentHashType: "javascript"
100
+ }
101
+ )
102
+ .split("/");
112
103
 
113
- // create final path
114
- const runtimePath =
115
- (currentOutputName.length > 0
116
- ? "../".repeat(currentOutputName.length)
117
- : "./") + runtimeOutputName.join("/");
104
+ // remove common parts
105
+ while (
106
+ baseOutputName.length > 0 &&
107
+ chunkOutputName.length > 0 &&
108
+ baseOutputName[0] === chunkOutputName[0]
109
+ ) {
110
+ baseOutputName.shift();
111
+ chunkOutputName.shift();
112
+ }
113
+ // create final path
114
+ return (
115
+ (baseOutputName.length > 0
116
+ ? "../".repeat(baseOutputName.length)
117
+ : "./") + chunkOutputName.join("/")
118
+ );
119
+ };
118
120
 
119
121
  const entrySource = new ConcatSource();
120
122
  entrySource.add(source);
121
123
  entrySource.add(";\n\n// load runtime\n");
122
124
  entrySource.add(
123
125
  `import __webpack_require__ from ${JSON.stringify(
124
- runtimePath
125
- )};\n`
126
- );
127
- entrySource.add(
128
- `import * as __webpack_self_exports__ from ${JSON.stringify(
129
- "./" + outputFilename
126
+ getRelativePath(runtimeChunk)
130
127
  )};\n`
131
128
  );
132
- entrySource.add(
133
- `${RuntimeGlobals.externalInstallChunk}(__webpack_self_exports__);\n`
134
- );
135
- const startupSource = new RawSource(
136
- generateEntryStartup(
137
- chunkGraph,
138
- runtimeTemplate,
139
- entries,
140
- chunk,
141
- false
142
- )
129
+
130
+ const startupSource = new ConcatSource();
131
+ startupSource.add(
132
+ `var __webpack_exec__ = ${runtimeTemplate.returningFunction(
133
+ `__webpack_require__(${RuntimeGlobals.entryModuleId} = moduleId)`,
134
+ "moduleId"
135
+ )}\n`
143
136
  );
137
+
138
+ const loadedChunks = new Set();
139
+ let index = 0;
140
+ for (let i = 0; i < entries.length; i++) {
141
+ const [module, entrypoint] = entries[i];
142
+ const final = i + 1 === entries.length;
143
+ const moduleId = chunkGraph.getModuleId(module);
144
+ const chunks = getAllChunks(
145
+ entrypoint,
146
+ runtimeChunk,
147
+ undefined
148
+ );
149
+ for (const chunk of chunks) {
150
+ if (loadedChunks.has(chunk)) continue;
151
+ loadedChunks.add(chunk);
152
+ startupSource.add(
153
+ `import * as __webpack_chunk_${index}__ from ${JSON.stringify(
154
+ getRelativePath(chunk)
155
+ )};\n`
156
+ );
157
+ startupSource.add(
158
+ `${RuntimeGlobals.externalInstallChunk}(__webpack_chunk_${index}__);\n`
159
+ );
160
+ index++;
161
+ }
162
+ startupSource.add(
163
+ `${
164
+ final ? "var __webpack_exports__ = " : ""
165
+ }__webpack_exec__(${JSON.stringify(moduleId)});\n`
166
+ );
167
+ }
168
+
144
169
  entrySource.add(
145
170
  hooks.renderStartup.call(
146
171
  startupSource,
@@ -25,7 +25,9 @@ class ModuleChunkLoadingPlugin {
25
25
  const isEnabledForChunk = chunk => {
26
26
  const options = chunk.getEntryOptions();
27
27
  const chunkLoading =
28
- (options && options.chunkLoading) || globalChunkLoading;
28
+ options && options.chunkLoading !== undefined
29
+ ? options.chunkLoading
30
+ : globalChunkLoading;
29
31
  return chunkLoading === "import";
30
32
  };
31
33
  const onceForChunkSet = new WeakSet();
@@ -55,15 +55,35 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
55
55
  this._runtimeRequirements = runtimeRequirements;
56
56
  }
57
57
 
58
+ /**
59
+ * @private
60
+ * @param {Chunk} chunk chunk
61
+ * @param {string} rootOutputDir root output directory
62
+ * @returns {string} generated code
63
+ */
64
+ _generateBaseUri(chunk, rootOutputDir) {
65
+ const options = chunk.getEntryOptions();
66
+ if (options && options.baseUri) {
67
+ return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
68
+ }
69
+ const {
70
+ compilation: {
71
+ outputOptions: { importMetaName }
72
+ }
73
+ } = this;
74
+ return `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
75
+ rootOutputDir
76
+ )}, ${importMetaName}.url);`;
77
+ }
78
+
58
79
  /**
59
80
  * @returns {string} runtime code
60
81
  */
61
82
  generate() {
62
- const { compilation, chunk } = this;
83
+ const { compilation, chunk, chunkGraph } = this;
63
84
  const {
64
85
  runtimeTemplate,
65
- chunkGraph,
66
- outputOptions: { importFunctionName, importMetaName }
86
+ outputOptions: { importFunctionName }
67
87
  } = compilation;
68
88
  const fn = RuntimeGlobals.ensureChunkHandlers;
69
89
  const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
@@ -81,7 +101,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
81
101
  );
82
102
  const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
83
103
  const hasJsMatcher = compileBooleanMatcher(conditionMap);
84
- const initialChunkIds = getInitialChunkIds(chunk, chunkGraph);
104
+ const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
85
105
 
86
106
  const outputName = this.compilation.getPath(
87
107
  getChunkFilenameTemplate(chunk, this.compilation.outputOptions),
@@ -102,11 +122,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
102
122
 
103
123
  return Template.asString([
104
124
  withBaseURI
105
- ? Template.asString([
106
- `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
107
- rootOutputDir
108
- )}, ${importMetaName}.url);`
109
- ])
125
+ ? this._generateBaseUri(chunk, rootOutputDir)
110
126
  : "// no baseURI",
111
127
  "",
112
128
  "// object to store loaded and loading chunks",
@@ -28,7 +28,8 @@ module.exports = function () {
28
28
  var currentStatus = "idle";
29
29
 
30
30
  // while downloading
31
- var blockingPromises;
31
+ var blockingPromises = 0;
32
+ var blockingPromisesWaiting = [];
32
33
 
33
34
  // The update info
34
35
  var currentUpdateApplyHandlers;
@@ -218,17 +219,28 @@ module.exports = function () {
218
219
  return Promise.all(results);
219
220
  }
220
221
 
222
+ function unblock() {
223
+ if (--blockingPromises === 0) {
224
+ setStatus("ready").then(function () {
225
+ if (blockingPromises === 0) {
226
+ var list = blockingPromisesWaiting;
227
+ blockingPromisesWaiting = [];
228
+ for (var i = 0; i < list.length; i++) {
229
+ list[i]();
230
+ }
231
+ }
232
+ });
233
+ }
234
+ }
235
+
221
236
  function trackBlockingPromise(promise) {
222
237
  switch (currentStatus) {
223
238
  case "ready":
224
239
  setStatus("prepare");
225
- blockingPromises.push(promise);
226
- waitForBlockingPromises(function () {
227
- return setStatus("ready");
228
- });
229
- return promise;
240
+ /* fallthrough */
230
241
  case "prepare":
231
- blockingPromises.push(promise);
242
+ blockingPromises++;
243
+ promise.then(unblock, unblock);
232
244
  return promise;
233
245
  default:
234
246
  return promise;
@@ -236,11 +248,11 @@ module.exports = function () {
236
248
  }
237
249
 
238
250
  function waitForBlockingPromises(fn) {
239
- if (blockingPromises.length === 0) return fn();
240
- var blocker = blockingPromises;
241
- blockingPromises = [];
242
- return Promise.all(blocker).then(function () {
243
- return waitForBlockingPromises(fn);
251
+ if (blockingPromises === 0) return fn();
252
+ return new Promise(function (resolve) {
253
+ blockingPromisesWaiting.push(function () {
254
+ resolve(fn());
255
+ });
244
256
  });
245
257
  }
246
258
 
@@ -261,7 +273,6 @@ module.exports = function () {
261
273
 
262
274
  return setStatus("prepare").then(function () {
263
275
  var updatedModules = [];
264
- blockingPromises = [];
265
276
  currentUpdateApplyHandlers = [];
266
277
 
267
278
  return Promise.all(
@@ -298,7 +309,11 @@ module.exports = function () {
298
309
  function hotApply(options) {
299
310
  if (currentStatus !== "ready") {
300
311
  return Promise.resolve().then(function () {
301
- throw new Error("apply() is only allowed in ready status");
312
+ throw new Error(
313
+ "apply() is only allowed in ready status (state: " +
314
+ currentStatus +
315
+ ")"
316
+ );
302
317
  });
303
318
  }
304
319
  return internalApply(options);
@@ -443,15 +443,16 @@ module.exports = function () {
443
443
  ) {
444
444
  promises.push($loadUpdateChunk$(chunkId, updatedModulesList));
445
445
  currentUpdateChunks[chunkId] = true;
446
+ } else {
447
+ currentUpdateChunks[chunkId] = false;
446
448
  }
447
449
  });
448
450
  if ($ensureChunkHandlers$) {
449
451
  $ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) {
450
452
  if (
451
453
  currentUpdateChunks &&
452
- !$hasOwnProperty$(currentUpdateChunks, chunkId) &&
453
- $hasOwnProperty$($installedChunks$, chunkId) &&
454
- $installedChunks$[chunkId] !== undefined
454
+ $hasOwnProperty$(currentUpdateChunks, chunkId) &&
455
+ !currentUpdateChunks[chunkId]
455
456
  ) {
456
457
  promises.push($loadUpdateChunk$(chunkId));
457
458
  currentUpdateChunks[chunkId] = true;
@@ -29,10 +29,17 @@ const { registerNotSerializable } = require("../util/serialization");
29
29
  /** @typedef {import("../RequestShortener")} RequestShortener */
30
30
  /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
31
31
  /** @typedef {import("../WebpackError")} WebpackError */
32
+ /** @typedef {import("../dependencies/HarmonyImportDependency")} HarmonyImportDependency */
32
33
  /** @typedef {import("../util/Hash")} Hash */
33
34
  /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
34
35
 
35
- const IGNORED_DEPENDENCY_TYPES = new Set([
36
+ /**
37
+ * @typedef {Object} BackendApi
38
+ * @property {function(Error=): void} dispose
39
+ * @property {function(Module): { client: string, data: string, active: boolean }} module
40
+ */
41
+
42
+ const HMR_DEPENDENCY_TYPES = new Set([
36
43
  "import.meta.webpackHot.accept",
37
44
  "import.meta.webpackHot.decline",
38
45
  "module.hot.accept",
@@ -140,7 +147,7 @@ class LazyCompilationProxyModule extends Module {
140
147
 
141
148
  /**
142
149
  * @param {NeedBuildContext} context context info
143
- * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
150
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
144
151
  * @returns {void}
145
152
  */
146
153
  needBuild(context, callback) {
@@ -303,15 +310,13 @@ class LazyCompilationDependencyFactory extends ModuleFactory {
303
310
  class LazyCompilationPlugin {
304
311
  /**
305
312
  * @param {Object} options options
306
- * @param {(function(Compiler, string, function(Error?, any?): void): void) | function(Compiler, string): Promise<any>} options.backend the backend
307
- * @param {string} options.client the client reference
313
+ * @param {(function(Compiler, function(Error?, BackendApi?): void): void) | function(Compiler): Promise<BackendApi>} options.backend the backend
308
314
  * @param {boolean} options.entries true, when entries are lazy compiled
309
315
  * @param {boolean} options.imports true, when import() modules are lazy compiled
310
316
  * @param {RegExp | string | (function(Module): boolean)} options.test additional filter for lazy compiled entrypoint modules
311
317
  */
312
- constructor({ backend, client, entries, imports, test }) {
318
+ constructor({ backend, entries, imports, test }) {
313
319
  this.backend = backend;
314
- this.client = client;
315
320
  this.entries = entries;
316
321
  this.imports = imports;
317
322
  this.test = test;
@@ -327,7 +332,7 @@ class LazyCompilationPlugin {
327
332
  "LazyCompilationPlugin",
328
333
  (params, callback) => {
329
334
  if (backend !== undefined) return callback();
330
- const promise = this.backend(compiler, this.client, (err, result) => {
335
+ const promise = this.backend(compiler, (err, result) => {
331
336
  if (err) return callback(err);
332
337
  backend = result;
333
338
  callback();
@@ -347,32 +352,55 @@ class LazyCompilationPlugin {
347
352
  "LazyCompilationPlugin",
348
353
  (originalModule, createData, resolveData) => {
349
354
  if (
350
- resolveData.dependencies.every(
355
+ resolveData.dependencies.every(dep =>
356
+ HMR_DEPENDENCY_TYPES.has(dep.type)
357
+ )
358
+ ) {
359
+ // for HMR only resolving, try to determine if the HMR accept/decline refers to
360
+ // an import() or not
361
+ const hmrDep = resolveData.dependencies[0];
362
+ const originModule =
363
+ compilation.moduleGraph.getParentModule(hmrDep);
364
+ const isReferringToDynamicImport = originModule.blocks.some(
365
+ block =>
366
+ block.dependencies.some(
367
+ dep =>
368
+ dep.type === "import()" &&
369
+ /** @type {HarmonyImportDependency} */ (dep).request ===
370
+ hmrDep.request
371
+ )
372
+ );
373
+ if (!isReferringToDynamicImport) return;
374
+ } else if (
375
+ !resolveData.dependencies.every(
351
376
  dep =>
352
- IGNORED_DEPENDENCY_TYPES.has(dep.type) ||
377
+ HMR_DEPENDENCY_TYPES.has(dep.type) ||
353
378
  (this.imports &&
354
379
  (dep.type === "import()" ||
355
380
  dep.type === "import() context element")) ||
356
381
  (this.entries && dep.type === "entry")
357
- ) &&
358
- !/webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client/.test(
382
+ )
383
+ )
384
+ return;
385
+ if (
386
+ /webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client|webpack-hot-middleware[/\\]client/.test(
359
387
  resolveData.request
360
- ) &&
361
- checkTest(this.test, originalModule)
362
- ) {
363
- const moduleInfo = backend.module(originalModule);
364
- if (!moduleInfo) return;
365
- const { client, data, active } = moduleInfo;
388
+ ) ||
389
+ !checkTest(this.test, originalModule)
390
+ )
391
+ return;
392
+ const moduleInfo = backend.module(originalModule);
393
+ if (!moduleInfo) return;
394
+ const { client, data, active } = moduleInfo;
366
395
 
367
- return new LazyCompilationProxyModule(
368
- compiler.context,
369
- originalModule,
370
- resolveData.request,
371
- client,
372
- data,
373
- active
374
- );
375
- }
396
+ return new LazyCompilationProxyModule(
397
+ compiler.context,
398
+ originalModule,
399
+ resolveData.request,
400
+ client,
401
+ data,
402
+ active
403
+ );
376
404
  }
377
405
  );
378
406
  compilation.dependencyFactories.set(
@@ -5,21 +5,51 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const http = require("http");
9
-
8
+ /** @typedef {import("http").ServerOptions} HttpServerOptions */
9
+ /** @typedef {import("https").ServerOptions} HttpsServerOptions */
10
+ /** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */
10
11
  /** @typedef {import("../Compiler")} Compiler */
11
12
 
12
13
  /**
14
+ * @callback BackendHandler
13
15
  * @param {Compiler} compiler compiler
14
- * @param {string} client client reference
15
- * @param {function(Error?, any?): void} callback callback
16
+ * @param {function((Error | null)=, any=): void} callback callback
16
17
  * @returns {void}
17
18
  */
18
- module.exports = (compiler, client, callback) => {
19
+
20
+ /**
21
+ * @param {Omit<LazyCompilationDefaultBackendOptions, "client"> & { client: NonNullable<LazyCompilationDefaultBackendOptions["client"]>}} options additional options for the backend
22
+ * @returns {BackendHandler} backend
23
+ */
24
+ module.exports = options => (compiler, callback) => {
19
25
  const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
20
26
  const activeModules = new Map();
21
27
  const prefix = "/lazy-compilation-using-";
22
28
 
29
+ const isHttps =
30
+ options.protocol === "https" ||
31
+ (typeof options.server === "object" &&
32
+ ("key" in options.server || "pfx" in options.server));
33
+
34
+ const createServer =
35
+ typeof options.server === "function"
36
+ ? options.server
37
+ : (() => {
38
+ const http = isHttps ? require("https") : require("http");
39
+ return http.createServer.bind(http, options.server);
40
+ })();
41
+ const listen =
42
+ typeof options.listen === "function"
43
+ ? options.listen
44
+ : server => {
45
+ let listen = options.listen;
46
+ if (typeof listen === "object" && !("port" in listen))
47
+ listen = { ...listen, port: undefined };
48
+ server.listen(listen);
49
+ };
50
+
51
+ const protocol = options.protocol || (isHttps ? "https" : "http");
52
+
23
53
  const requestListener = (req, res) => {
24
54
  const keys = req.url.slice(prefix.length).split("@");
25
55
  req.socket.on("close", () => {
@@ -38,7 +68,9 @@ module.exports = (compiler, client, callback) => {
38
68
  req.socket.setNoDelay(true);
39
69
  res.writeHead(200, {
40
70
  "content-type": "text/event-stream",
41
- "Access-Control-Allow-Origin": "*"
71
+ "Access-Control-Allow-Origin": "*",
72
+ "Access-Control-Allow-Methods": "*",
73
+ "Access-Control-Allow-Headers": "*"
42
74
  });
43
75
  res.write("\n");
44
76
  let moduleActivated = false;
@@ -52,7 +84,10 @@ module.exports = (compiler, client, callback) => {
52
84
  }
53
85
  if (moduleActivated && compiler.watching) compiler.watching.invalidate();
54
86
  };
55
- const server = http.createServer(requestListener);
87
+
88
+ const server = /** @type {import("net").Server} */ (createServer());
89
+ server.on("request", requestListener);
90
+
56
91
  let isClosing = false;
57
92
  /** @type {Set<import("net").Socket>} */
58
93
  const sockets = new Set();
@@ -63,16 +98,19 @@ module.exports = (compiler, client, callback) => {
63
98
  });
64
99
  if (isClosing) socket.destroy();
65
100
  });
66
- server.listen(err => {
101
+ server.on("clientError", e => {
102
+ if (e.message !== "Server is disposing") logger.warn(e);
103
+ });
104
+ server.on("listening", err => {
67
105
  if (err) return callback(err);
68
106
  const addr = server.address();
69
107
  if (typeof addr === "string") throw new Error("addr must not be a string");
70
108
  const urlBase =
71
109
  addr.address === "::" || addr.address === "0.0.0.0"
72
- ? `http://localhost:${addr.port}`
110
+ ? `${protocol}://localhost:${addr.port}`
73
111
  : addr.family === "IPv6"
74
- ? `http://[${addr.address}]:${addr.port}`
75
- : `http://${addr.address}:${addr.port}`;
112
+ ? `${protocol}://[${addr.address}]:${addr.port}`
113
+ : `${protocol}://${addr.address}:${addr.port}`;
76
114
  logger.log(
77
115
  `Server-Sent-Events server for lazy compilation open at ${urlBase}.`
78
116
  );
@@ -94,11 +132,12 @@ module.exports = (compiler, client, callback) => {
94
132
  ).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`;
95
133
  const active = activeModules.get(key) > 0;
96
134
  return {
97
- client: `${client}?${encodeURIComponent(urlBase + prefix)}`,
135
+ client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`,
98
136
  data: key,
99
137
  active
100
138
  };
101
139
  }
102
140
  });
103
141
  });
142
+ listen(server);
104
143
  };