webpack 5.97.1 → 5.104.1

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 (610) hide show
  1. package/README.md +368 -434
  2. package/bin/webpack.js +15 -9
  3. package/hot/dev-server.js +18 -3
  4. package/hot/emitter-event-target.js +7 -0
  5. package/hot/lazy-compilation-node.js +45 -29
  6. package/hot/lazy-compilation-universal.js +18 -0
  7. package/hot/lazy-compilation-web.js +15 -5
  8. package/hot/load-http.js +7 -0
  9. package/hot/log.js +15 -15
  10. package/hot/only-dev-server.js +19 -4
  11. package/hot/poll.js +1 -0
  12. package/lib/APIPlugin.js +48 -50
  13. package/lib/AbstractMethodError.js +1 -0
  14. package/lib/AsyncDependenciesBlock.js +4 -5
  15. package/lib/AutomaticPrefetchPlugin.js +22 -22
  16. package/lib/BannerPlugin.js +35 -40
  17. package/lib/Cache.js +12 -9
  18. package/lib/CacheFacade.js +13 -13
  19. package/lib/CaseSensitiveModulesWarning.js +6 -6
  20. package/lib/Chunk.js +68 -47
  21. package/lib/ChunkGraph.js +174 -95
  22. package/lib/ChunkGroup.js +32 -24
  23. package/lib/ChunkTemplate.js +8 -8
  24. package/lib/CleanPlugin.js +90 -42
  25. package/lib/CodeGenerationResults.js +12 -9
  26. package/lib/CompatibilityPlugin.js +70 -21
  27. package/lib/Compilation.js +827 -550
  28. package/lib/Compiler.js +137 -109
  29. package/lib/ConcatenationScope.js +45 -8
  30. package/lib/ConditionalInitFragment.js +1 -1
  31. package/lib/ConstPlugin.js +89 -59
  32. package/lib/ContextExclusionPlugin.js +5 -4
  33. package/lib/ContextModule.js +66 -51
  34. package/lib/ContextModuleFactory.js +51 -30
  35. package/lib/ContextReplacementPlugin.js +89 -34
  36. package/lib/CssModule.js +8 -4
  37. package/lib/DefinePlugin.js +209 -57
  38. package/lib/DelegatedModule.js +34 -23
  39. package/lib/DelegatedModuleFactoryPlugin.js +27 -24
  40. package/lib/DelegatedPlugin.js +4 -2
  41. package/lib/DependenciesBlock.js +0 -2
  42. package/lib/Dependency.js +37 -19
  43. package/lib/DependencyTemplate.js +2 -0
  44. package/lib/DependencyTemplates.js +5 -6
  45. package/lib/DllEntryPlugin.js +8 -4
  46. package/lib/DllModule.js +11 -12
  47. package/lib/DllModuleFactory.js +2 -2
  48. package/lib/DllPlugin.js +9 -6
  49. package/lib/DllReferencePlugin.js +60 -65
  50. package/lib/DotenvPlugin.js +462 -0
  51. package/lib/DynamicEntryPlugin.js +8 -8
  52. package/lib/EntryOptionPlugin.js +8 -6
  53. package/lib/EntryPlugin.js +5 -3
  54. package/lib/Entrypoint.js +19 -0
  55. package/lib/EnvironmentNotSupportAsyncWarning.js +0 -3
  56. package/lib/EnvironmentPlugin.js +26 -19
  57. package/lib/ErrorHelpers.js +6 -6
  58. package/lib/EvalDevToolModulePlugin.js +17 -14
  59. package/lib/EvalSourceMapDevToolPlugin.js +156 -142
  60. package/lib/ExportsInfo.js +180 -115
  61. package/lib/ExportsInfoApiPlugin.js +2 -2
  62. package/lib/ExternalModule.js +256 -102
  63. package/lib/ExternalModuleFactoryPlugin.js +66 -29
  64. package/lib/ExternalsPlugin.js +57 -2
  65. package/lib/FileSystemInfo.js +313 -247
  66. package/lib/FlagAllModulesAsUsedPlugin.js +2 -2
  67. package/lib/FlagDependencyExportsPlugin.js +29 -19
  68. package/lib/FlagDependencyUsagePlugin.js +9 -10
  69. package/lib/FlagEntryExportAsUsedPlugin.js +1 -1
  70. package/lib/Generator.js +43 -10
  71. package/lib/GraphHelpers.js +11 -3
  72. package/lib/HookWebpackError.js +35 -7
  73. package/lib/HotModuleReplacementPlugin.js +149 -108
  74. package/lib/HotUpdateChunk.js +0 -3
  75. package/lib/IgnoreErrorModuleFactory.js +2 -2
  76. package/lib/IgnorePlugin.js +16 -13
  77. package/lib/IgnoreWarningsPlugin.js +6 -4
  78. package/lib/InitFragment.js +41 -23
  79. package/lib/InvalidDependenciesModuleWarning.js +2 -3
  80. package/lib/JavascriptMetaInfoPlugin.js +2 -4
  81. package/lib/LibManifestPlugin.js +12 -13
  82. package/lib/LoaderOptionsPlugin.js +12 -14
  83. package/lib/LoaderTargetPlugin.js +5 -3
  84. package/lib/MainTemplate.js +18 -29
  85. package/lib/ManifestPlugin.js +235 -0
  86. package/lib/Module.js +138 -60
  87. package/lib/ModuleBuildError.js +4 -2
  88. package/lib/ModuleDependencyError.js +4 -3
  89. package/lib/ModuleDependencyWarning.js +4 -3
  90. package/lib/ModuleError.js +1 -1
  91. package/lib/ModuleFactory.js +10 -3
  92. package/lib/ModuleFilenameHelpers.js +63 -60
  93. package/lib/ModuleGraph.js +195 -70
  94. package/lib/ModuleGraphConnection.js +14 -20
  95. package/lib/ModuleInfoHeaderPlugin.js +15 -16
  96. package/lib/ModuleNotFoundError.js +1 -1
  97. package/lib/ModuleParseError.js +8 -4
  98. package/lib/ModuleSourceTypeConstants.js +189 -0
  99. package/lib/ModuleTemplate.js +7 -8
  100. package/lib/ModuleTypeConstants.js +37 -15
  101. package/lib/ModuleWarning.js +1 -1
  102. package/lib/MultiCompiler.js +64 -49
  103. package/lib/MultiStats.js +19 -14
  104. package/lib/MultiWatching.js +7 -11
  105. package/lib/NoEmitOnErrorsPlugin.js +5 -3
  106. package/lib/NodeStuffPlugin.js +438 -126
  107. package/lib/NormalModule.js +322 -201
  108. package/lib/NormalModuleFactory.js +230 -117
  109. package/lib/NormalModuleReplacementPlugin.js +37 -39
  110. package/lib/NullFactory.js +3 -2
  111. package/lib/OptimizationStages.js +1 -1
  112. package/lib/OptionsApply.js +1 -1
  113. package/lib/Parser.js +5 -3
  114. package/lib/PlatformPlugin.js +3 -1
  115. package/lib/PrefetchPlugin.js +6 -4
  116. package/lib/ProgressPlugin.js +48 -49
  117. package/lib/ProvidePlugin.js +7 -5
  118. package/lib/RawModule.js +26 -12
  119. package/lib/RecordIdsPlugin.js +88 -110
  120. package/lib/RequestShortener.js +3 -1
  121. package/lib/ResolverFactory.js +15 -14
  122. package/lib/RuntimeGlobals.js +216 -153
  123. package/lib/RuntimeModule.js +7 -6
  124. package/lib/RuntimePlugin.js +115 -62
  125. package/lib/RuntimeTemplate.js +248 -76
  126. package/lib/SelfModuleFactory.js +2 -2
  127. package/lib/SizeFormatHelpers.js +2 -2
  128. package/lib/SourceMapDevToolModuleOptionsPlugin.js +17 -27
  129. package/lib/SourceMapDevToolPlugin.js +72 -59
  130. package/lib/Stats.js +2 -3
  131. package/lib/Template.js +31 -24
  132. package/lib/TemplatedPathPlugin.js +24 -21
  133. package/lib/UseStrictPlugin.js +1 -1
  134. package/lib/WarnCaseSensitiveModulesPlugin.js +36 -37
  135. package/lib/WarnDeprecatedOptionPlugin.js +7 -8
  136. package/lib/WarnNoModeSetPlugin.js +3 -1
  137. package/lib/WatchIgnorePlugin.js +11 -9
  138. package/lib/Watching.js +27 -29
  139. package/lib/WebpackError.js +10 -3
  140. package/lib/WebpackIsIncludedPlugin.js +4 -5
  141. package/lib/WebpackOptionsApply.js +263 -135
  142. package/lib/asset/AssetBytesGenerator.js +171 -0
  143. package/lib/asset/AssetBytesParser.js +37 -0
  144. package/lib/asset/AssetGenerator.js +285 -223
  145. package/lib/asset/AssetModulesPlugin.js +103 -41
  146. package/lib/asset/AssetParser.js +7 -3
  147. package/lib/asset/AssetSourceGenerator.js +41 -17
  148. package/lib/asset/RawDataUrlModule.js +17 -9
  149. package/lib/async-modules/AsyncModuleHelpers.js +52 -0
  150. package/lib/async-modules/AwaitDependenciesInitFragment.js +39 -24
  151. package/lib/async-modules/InferAsyncModulesPlugin.js +25 -26
  152. package/lib/buildChunkGraph.js +36 -17
  153. package/lib/cache/AddBuildDependenciesPlugin.js +5 -6
  154. package/lib/cache/IdleFileCachePlugin.js +22 -20
  155. package/lib/cache/MemoryCachePlugin.js +3 -3
  156. package/lib/cache/MemoryWithGcCachePlugin.js +17 -11
  157. package/lib/cache/PackFileCacheStrategy.js +198 -170
  158. package/lib/cache/ResolverCachePlugin.js +58 -48
  159. package/lib/cache/getLazyHashedEtag.js +5 -4
  160. package/lib/cli.js +197 -39
  161. package/lib/config/browserslistTargetHandler.js +110 -85
  162. package/lib/config/defaults.js +514 -113
  163. package/lib/config/normalization.js +91 -64
  164. package/lib/config/target.js +30 -18
  165. package/lib/container/ContainerEntryDependency.js +0 -1
  166. package/lib/container/ContainerEntryModule.js +16 -15
  167. package/lib/container/ContainerEntryModuleFactory.js +2 -2
  168. package/lib/container/ContainerPlugin.js +5 -6
  169. package/lib/container/ContainerReferencePlugin.js +27 -30
  170. package/lib/container/FallbackDependency.js +2 -1
  171. package/lib/container/FallbackModule.js +19 -14
  172. package/lib/container/FallbackModuleFactory.js +2 -2
  173. package/lib/container/HoistContainerReferencesPlugin.js +7 -7
  174. package/lib/container/ModuleFederationPlugin.js +4 -4
  175. package/lib/container/RemoteModule.js +14 -14
  176. package/lib/container/RemoteRuntimeModule.js +2 -2
  177. package/lib/container/options.js +9 -9
  178. package/lib/css/CssGenerator.js +366 -74
  179. package/lib/css/CssLoadingRuntimeModule.js +26 -16
  180. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  181. package/lib/css/CssModulesPlugin.js +191 -142
  182. package/lib/css/CssParser.js +1756 -740
  183. package/lib/css/walkCssTokens.js +180 -67
  184. package/lib/debug/ProfilingPlugin.js +135 -51
  185. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +29 -28
  186. package/lib/dependencies/AMDPlugin.js +18 -11
  187. package/lib/dependencies/AMDRequireArrayDependency.js +5 -4
  188. package/lib/dependencies/AMDRequireContextDependency.js +2 -1
  189. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +35 -26
  190. package/lib/dependencies/AMDRuntimeModules.js +3 -1
  191. package/lib/dependencies/CachedConstDependency.js +24 -18
  192. package/lib/dependencies/CommonJsExportRequireDependency.js +31 -24
  193. package/lib/dependencies/CommonJsExportsDependency.js +2 -1
  194. package/lib/dependencies/CommonJsExportsParserPlugin.js +50 -36
  195. package/lib/dependencies/CommonJsFullRequireDependency.js +7 -13
  196. package/lib/dependencies/CommonJsImportsParserPlugin.js +146 -127
  197. package/lib/dependencies/CommonJsPlugin.js +29 -18
  198. package/lib/dependencies/CommonJsRequireContextDependency.js +4 -3
  199. package/lib/dependencies/CommonJsSelfReferenceDependency.js +4 -4
  200. package/lib/dependencies/ConstDependency.js +2 -2
  201. package/lib/dependencies/ContextDependency.js +10 -5
  202. package/lib/dependencies/ContextDependencyHelpers.js +21 -13
  203. package/lib/dependencies/ContextDependencyTemplateAsId.js +10 -9
  204. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +13 -10
  205. package/lib/dependencies/ContextElementDependency.js +23 -12
  206. package/lib/dependencies/CssIcssExportDependency.js +402 -22
  207. package/lib/dependencies/CssIcssImportDependency.js +116 -51
  208. package/lib/dependencies/CssIcssSymbolDependency.js +33 -35
  209. package/lib/dependencies/CssImportDependency.js +17 -14
  210. package/lib/dependencies/CssUrlDependency.js +8 -13
  211. package/lib/dependencies/DynamicExports.js +19 -19
  212. package/lib/dependencies/ExportsInfoDependency.js +13 -10
  213. package/lib/dependencies/ExternalModuleDependency.js +7 -7
  214. package/lib/dependencies/ExternalModuleInitFragment.js +3 -2
  215. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +96 -0
  216. package/lib/dependencies/HarmonyAcceptDependency.js +96 -5
  217. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -5
  218. package/lib/dependencies/HarmonyCompatibilityDependency.js +0 -1
  219. package/lib/dependencies/HarmonyDetectionParserPlugin.js +10 -30
  220. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +19 -8
  221. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +136 -99
  222. package/lib/dependencies/HarmonyExportExpressionDependency.js +1 -1
  223. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +152 -61
  224. package/lib/dependencies/HarmonyExportInitFragment.js +2 -2
  225. package/lib/dependencies/HarmonyExportSpecifierDependency.js +2 -2
  226. package/lib/dependencies/HarmonyExports.js +5 -5
  227. package/lib/dependencies/HarmonyImportDependency.js +92 -45
  228. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +201 -163
  229. package/lib/dependencies/HarmonyImportSideEffectDependency.js +5 -6
  230. package/lib/dependencies/HarmonyImportSpecifierDependency.js +69 -42
  231. package/lib/dependencies/HarmonyModulesPlugin.js +16 -11
  232. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +15 -15
  233. package/lib/dependencies/ImportContextDependency.js +15 -1
  234. package/lib/dependencies/ImportDependency.js +25 -7
  235. package/lib/dependencies/ImportEagerDependency.js +7 -5
  236. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +23 -13
  237. package/lib/dependencies/ImportMetaContextPlugin.js +2 -2
  238. package/lib/dependencies/ImportMetaPlugin.js +172 -20
  239. package/lib/dependencies/ImportParserPlugin.js +327 -49
  240. package/lib/dependencies/ImportPhase.js +121 -0
  241. package/lib/dependencies/ImportPlugin.js +3 -1
  242. package/lib/dependencies/ImportWeakDependency.js +7 -5
  243. package/lib/dependencies/JsonExportsDependency.js +54 -28
  244. package/lib/dependencies/LoaderDependency.js +0 -3
  245. package/lib/dependencies/LoaderImportDependency.js +0 -3
  246. package/lib/dependencies/LoaderPlugin.js +24 -25
  247. package/lib/dependencies/LocalModulesHelpers.js +4 -4
  248. package/lib/dependencies/ModuleDecoratorDependency.js +2 -4
  249. package/lib/dependencies/ModuleDependency.js +14 -13
  250. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +1 -0
  251. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  252. package/lib/dependencies/NullDependency.js +2 -0
  253. package/lib/dependencies/ProvidedDependency.js +8 -10
  254. package/lib/dependencies/PureExpressionDependency.js +1 -2
  255. package/lib/dependencies/RequireContextDependency.js +2 -1
  256. package/lib/dependencies/RequireContextDependencyParserPlugin.js +47 -44
  257. package/lib/dependencies/RequireContextPlugin.js +5 -2
  258. package/lib/dependencies/RequireEnsureDependenciesBlock.js +3 -3
  259. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +101 -99
  260. package/lib/dependencies/RequireEnsurePlugin.js +6 -6
  261. package/lib/dependencies/RequireIncludeDependency.js +2 -2
  262. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +33 -34
  263. package/lib/dependencies/RequireIncludePlugin.js +1 -0
  264. package/lib/dependencies/RequireResolveContextDependency.js +1 -1
  265. package/lib/dependencies/RequireResolveDependency.js +3 -3
  266. package/lib/dependencies/RuntimeRequirementsDependency.js +3 -4
  267. package/lib/dependencies/StaticExportsDependency.js +3 -5
  268. package/lib/dependencies/SystemPlugin.js +4 -4
  269. package/lib/dependencies/URLContextDependency.js +65 -0
  270. package/lib/dependencies/URLDependency.js +3 -8
  271. package/lib/dependencies/URLPlugin.js +18 -159
  272. package/lib/dependencies/WebAssemblyExportImportedDependency.js +3 -3
  273. package/lib/dependencies/WebAssemblyImportDependency.js +2 -2
  274. package/lib/dependencies/WebpackIsIncludedDependency.js +2 -3
  275. package/lib/dependencies/WorkerDependency.js +8 -6
  276. package/lib/dependencies/WorkerPlugin.js +131 -67
  277. package/lib/dependencies/getFunctionExpression.js +2 -2
  278. package/lib/dependencies/processExportInfo.js +4 -4
  279. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -1
  280. package/lib/esm/ModuleChunkFormatPlugin.js +232 -179
  281. package/lib/esm/ModuleChunkLoadingPlugin.js +112 -57
  282. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +102 -28
  283. package/lib/formatLocation.js +2 -2
  284. package/lib/hmr/HotModuleReplacement.runtime.js +41 -29
  285. package/lib/hmr/HotModuleReplacementRuntimeModule.js +1 -1
  286. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +43 -33
  287. package/lib/hmr/JavascriptHotModuleReplacementHelper.js +37 -0
  288. package/lib/hmr/LazyCompilationPlugin.js +67 -54
  289. package/lib/hmr/lazyCompilationBackend.js +23 -18
  290. package/lib/ids/ChunkModuleIdRangePlugin.js +14 -11
  291. package/lib/ids/DeterministicChunkIdsPlugin.js +32 -37
  292. package/lib/ids/DeterministicModuleIdsPlugin.js +52 -52
  293. package/lib/ids/HashedModuleIdsPlugin.js +15 -13
  294. package/lib/ids/IdHelpers.js +66 -49
  295. package/lib/ids/NamedChunkIdsPlugin.js +14 -17
  296. package/lib/ids/NamedModuleIdsPlugin.js +12 -14
  297. package/lib/ids/NaturalChunkIdsPlugin.js +6 -4
  298. package/lib/ids/NaturalModuleIdsPlugin.js +4 -3
  299. package/lib/ids/OccurrenceChunkIdsPlugin.js +7 -5
  300. package/lib/ids/OccurrenceModuleIdsPlugin.js +8 -7
  301. package/lib/ids/SyncModuleIdsPlugin.js +18 -13
  302. package/lib/index.js +54 -14
  303. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +116 -119
  304. package/lib/javascript/BasicEvaluatedExpression.js +26 -18
  305. package/lib/javascript/ChunkFormatHelpers.js +70 -0
  306. package/lib/javascript/ChunkHelpers.js +17 -5
  307. package/lib/javascript/CommonJsChunkFormatPlugin.js +114 -141
  308. package/lib/javascript/EnableChunkLoadingPlugin.js +7 -4
  309. package/lib/javascript/JavascriptGenerator.js +122 -100
  310. package/lib/javascript/JavascriptModulesPlugin.js +332 -152
  311. package/lib/javascript/JavascriptParser.js +1488 -1052
  312. package/lib/javascript/JavascriptParserHelpers.js +48 -47
  313. package/lib/javascript/StartupHelpers.js +23 -22
  314. package/lib/json/JsonData.js +4 -4
  315. package/lib/json/JsonGenerator.js +66 -32
  316. package/lib/json/JsonModulesPlugin.js +16 -6
  317. package/lib/json/JsonParser.js +23 -8
  318. package/lib/library/AbstractLibraryPlugin.js +45 -10
  319. package/lib/library/AmdLibraryPlugin.js +7 -5
  320. package/lib/library/AssignLibraryPlugin.js +71 -17
  321. package/lib/library/EnableLibraryPlugin.js +51 -25
  322. package/lib/library/ExportPropertyLibraryPlugin.js +12 -18
  323. package/lib/library/JsonpLibraryPlugin.js +5 -2
  324. package/lib/library/ModuleLibraryPlugin.js +230 -18
  325. package/lib/library/SystemLibraryPlugin.js +29 -11
  326. package/lib/library/UmdLibraryPlugin.js +35 -32
  327. package/lib/logging/Logger.js +18 -15
  328. package/lib/logging/createConsoleLogger.js +27 -27
  329. package/lib/logging/runtime.js +11 -11
  330. package/lib/logging/truncateArgs.js +5 -5
  331. package/lib/node/CommonJsChunkLoadingPlugin.js +72 -75
  332. package/lib/node/NodeEnvironmentPlugin.js +9 -3
  333. package/lib/node/NodeTargetPlugin.js +9 -1
  334. package/lib/node/NodeTemplatePlugin.js +2 -2
  335. package/lib/node/NodeWatchFileSystem.js +4 -4
  336. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -38
  337. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +10 -11
  338. package/lib/node/ReadFileCompileWasmPlugin.js +11 -14
  339. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -30
  340. package/lib/node/nodeConsole.js +12 -7
  341. package/lib/optimize/AggressiveMergingPlugin.js +46 -47
  342. package/lib/optimize/AggressiveSplittingPlugin.js +233 -238
  343. package/lib/optimize/ConcatenatedModule.js +620 -251
  344. package/lib/optimize/EnsureChunkConditionsPlugin.js +58 -58
  345. package/lib/optimize/FlagIncludedChunksPlugin.js +93 -96
  346. package/lib/optimize/InnerGraph.js +139 -124
  347. package/lib/optimize/InnerGraphPlugin.js +29 -24
  348. package/lib/optimize/LimitChunkCountPlugin.js +32 -8
  349. package/lib/optimize/MangleExportsPlugin.js +22 -22
  350. package/lib/optimize/MergeDuplicateChunksPlugin.js +80 -81
  351. package/lib/optimize/MinChunkSizePlugin.js +12 -7
  352. package/lib/optimize/ModuleConcatenationPlugin.js +92 -71
  353. package/lib/optimize/RealContentHashPlugin.js +58 -44
  354. package/lib/optimize/RemoveEmptyChunksPlugin.js +8 -5
  355. package/lib/optimize/RemoveParentModulesPlugin.js +7 -4
  356. package/lib/optimize/RuntimeChunkPlugin.js +22 -25
  357. package/lib/optimize/SideEffectsFlagPlugin.js +44 -26
  358. package/lib/optimize/SplitChunksPlugin.js +209 -158
  359. package/lib/performance/AssetsOverSizeLimitWarning.js +1 -1
  360. package/lib/performance/EntrypointsOverSizeLimitWarning.js +2 -2
  361. package/lib/performance/SizeLimitsPlugin.js +8 -5
  362. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +5 -7
  363. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +61 -64
  364. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +3 -4
  365. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +2 -2
  366. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +2 -2
  367. package/lib/rules/BasicEffectRulePlugin.js +14 -5
  368. package/lib/rules/BasicMatcherRulePlugin.js +18 -7
  369. package/lib/rules/ObjectMatcherRulePlugin.js +17 -6
  370. package/lib/rules/RuleSetCompiler.js +73 -32
  371. package/lib/rules/UseEffectRulePlugin.js +61 -25
  372. package/lib/runtime/AsyncModuleRuntimeModule.js +74 -9
  373. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -4
  374. package/lib/runtime/BaseUriRuntimeModule.js +2 -2
  375. package/lib/runtime/CompatRuntimeModule.js +0 -1
  376. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +1 -1
  377. package/lib/runtime/GetChunkFilenameRuntimeModule.js +34 -35
  378. package/lib/runtime/GetMainFilenameRuntimeModule.js +1 -1
  379. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +1 -1
  380. package/lib/runtime/LoadScriptRuntimeModule.js +0 -2
  381. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +248 -0
  382. package/lib/runtime/PublicPathRuntimeModule.js +2 -2
  383. package/lib/runtime/RuntimeIdRuntimeModule.js +2 -1
  384. package/lib/runtime/StartupChunkDependenciesPlugin.js +39 -42
  385. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +10 -9
  386. package/lib/runtime/StartupEntrypointRuntimeModule.js +0 -1
  387. package/lib/runtime/SystemContextRuntimeModule.js +0 -2
  388. package/lib/runtime/ToBinaryRuntimeModule.js +64 -0
  389. package/lib/schemes/DataUriPlugin.js +9 -31
  390. package/lib/schemes/FileUriPlugin.js +11 -6
  391. package/lib/schemes/HttpUriPlugin.js +381 -261
  392. package/lib/schemes/VirtualUrlPlugin.js +222 -0
  393. package/lib/serialization/AggregateErrorSerializer.js +41 -0
  394. package/lib/serialization/BinaryMiddleware.js +51 -33
  395. package/lib/serialization/ErrorObjectSerializer.js +7 -2
  396. package/lib/serialization/FileMiddleware.js +101 -71
  397. package/lib/serialization/NullPrototypeObjectSerializer.js +5 -3
  398. package/lib/serialization/ObjectMiddleware.js +130 -54
  399. package/lib/serialization/PlainObjectSerializer.js +1 -1
  400. package/lib/serialization/Serializer.js +38 -20
  401. package/lib/serialization/SerializerMiddleware.js +121 -49
  402. package/lib/serialization/SingleItemMiddleware.js +9 -7
  403. package/lib/serialization/types.js +1 -1
  404. package/lib/sharing/ConsumeSharedModule.js +9 -9
  405. package/lib/sharing/ConsumeSharedPlugin.js +14 -14
  406. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -8
  407. package/lib/sharing/ProvideSharedModule.js +9 -11
  408. package/lib/sharing/ProvideSharedModuleFactory.js +5 -3
  409. package/lib/sharing/ProvideSharedPlugin.js +15 -10
  410. package/lib/sharing/SharePlugin.js +3 -4
  411. package/lib/sharing/ShareRuntimeModule.js +7 -6
  412. package/lib/sharing/resolveMatchedConfigs.js +27 -13
  413. package/lib/sharing/utils.js +37 -43
  414. package/lib/stats/DefaultStatsFactoryPlugin.js +455 -286
  415. package/lib/stats/DefaultStatsPresetPlugin.js +77 -46
  416. package/lib/stats/DefaultStatsPrinterPlugin.js +583 -419
  417. package/lib/stats/StatsFactory.js +75 -32
  418. package/lib/stats/StatsPrinter.js +71 -51
  419. package/lib/url/URLParserPlugin.js +264 -0
  420. package/lib/util/ArrayHelpers.js +6 -8
  421. package/lib/util/ArrayQueue.js +1 -1
  422. package/lib/util/AsyncQueue.js +11 -10
  423. package/lib/util/Hash.js +37 -5
  424. package/lib/util/IterableHelpers.js +4 -4
  425. package/lib/util/LazyBucketSortedSet.js +46 -27
  426. package/lib/util/LazySet.js +16 -10
  427. package/lib/util/MapHelpers.js +1 -1
  428. package/lib/util/ParallelismFactorCalculator.js +2 -2
  429. package/lib/util/Semaphore.js +3 -3
  430. package/lib/util/SetHelpers.js +6 -6
  431. package/lib/util/SortableSet.js +11 -9
  432. package/lib/util/StackedCacheMap.js +2 -2
  433. package/lib/util/StackedMap.js +3 -3
  434. package/lib/util/StringXor.js +2 -1
  435. package/lib/util/TupleQueue.js +11 -8
  436. package/lib/util/TupleSet.js +44 -19
  437. package/lib/util/URLAbsoluteSpecifier.js +3 -4
  438. package/lib/util/WeakTupleMap.js +56 -42
  439. package/lib/util/binarySearchBounds.js +4 -3
  440. package/lib/util/chainedImports.js +3 -1
  441. package/lib/util/cleverMerge.js +171 -107
  442. package/lib/util/comparators.js +265 -162
  443. package/lib/util/compileBooleanMatcher.js +120 -41
  444. package/lib/util/concatenate.js +20 -16
  445. package/lib/util/conventions.js +73 -74
  446. package/lib/util/create-schema-validation.js +8 -8
  447. package/lib/util/createHash.js +32 -135
  448. package/lib/util/dataURL.js +39 -0
  449. package/lib/util/deprecation.js +119 -116
  450. package/lib/util/deterministicGrouping.js +56 -47
  451. package/lib/util/extractSourceMap.js +319 -0
  452. package/lib/util/extractUrlAndGlobal.js +1 -1
  453. package/lib/util/findGraphRoots.js +19 -9
  454. package/lib/util/fs.js +169 -141
  455. package/lib/util/hash/BatchedHash.js +50 -10
  456. package/lib/util/hash/BulkUpdateHash.js +138 -0
  457. package/lib/util/hash/DebugHash.js +75 -0
  458. package/lib/util/hash/hash-digest.js +216 -0
  459. package/lib/util/hash/md4.js +2 -2
  460. package/lib/util/hash/wasm-hash.js +59 -17
  461. package/lib/util/identifier.js +124 -61
  462. package/lib/util/internalSerializables.js +4 -6
  463. package/lib/util/magicComment.js +9 -5
  464. package/lib/util/makeSerializable.js +2 -2
  465. package/lib/util/memoize.js +5 -2
  466. package/lib/util/objectToMap.js +3 -2
  467. package/lib/util/processAsyncTree.js +5 -5
  468. package/lib/util/propertyAccess.js +1 -1
  469. package/lib/util/propertyName.js +2 -3
  470. package/lib/util/registerExternalSerializer.js +16 -20
  471. package/lib/util/removeBOM.js +25 -0
  472. package/lib/util/runtime.js +72 -56
  473. package/lib/util/semver.js +44 -33
  474. package/lib/util/serialization.js +56 -56
  475. package/lib/util/smartGrouping.js +42 -27
  476. package/lib/util/source.js +5 -4
  477. package/lib/util/traverseDestructuringAssignmentProperties.js +45 -0
  478. package/lib/validateSchema.js +7 -9
  479. package/lib/wasm/EnableWasmLoadingPlugin.js +22 -12
  480. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -5
  481. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +15 -3
  482. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +28 -22
  483. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +47 -57
  484. package/lib/wasm-async/AsyncWebAssemblyParser.js +2 -10
  485. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +8 -4
  486. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +23 -17
  487. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +55 -57
  488. package/lib/wasm-sync/WebAssemblyGenerator.js +56 -41
  489. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +6 -3
  490. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +25 -10
  491. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +11 -12
  492. package/lib/wasm-sync/WebAssemblyParser.js +10 -17
  493. package/lib/wasm-sync/WebAssemblyUtils.js +1 -1
  494. package/lib/web/FetchCompileAsyncWasmPlugin.js +4 -4
  495. package/lib/web/FetchCompileWasmPlugin.js +6 -8
  496. package/lib/web/JsonpChunkLoadingPlugin.js +74 -74
  497. package/lib/web/JsonpChunkLoadingRuntimeModule.js +10 -26
  498. package/lib/web/JsonpTemplatePlugin.js +0 -1
  499. package/lib/webpack.js +107 -87
  500. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +79 -75
  501. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +38 -51
  502. package/lib/webworker/WebWorkerTemplatePlugin.js +1 -0
  503. package/module.d.ts +5 -0
  504. package/package.json +149 -129
  505. package/schemas/WebpackOptions.check.d.ts +1 -1
  506. package/schemas/WebpackOptions.check.js +2 -2
  507. package/schemas/WebpackOptions.json +543 -190
  508. package/schemas/plugins/BannerPlugin.check.d.ts +1 -1
  509. package/schemas/plugins/BannerPlugin.check.js +2 -2
  510. package/schemas/plugins/BannerPlugin.json +4 -0
  511. package/schemas/plugins/DllPlugin.check.d.ts +1 -1
  512. package/schemas/plugins/DllPlugin.check.js +1 -1
  513. package/schemas/plugins/DllReferencePlugin.check.d.ts +1 -1
  514. package/schemas/plugins/DllReferencePlugin.check.js +1 -1
  515. package/schemas/plugins/IgnorePlugin.check.d.ts +1 -1
  516. package/schemas/plugins/IgnorePlugin.check.js +1 -1
  517. package/schemas/plugins/IgnorePlugin.json +1 -1
  518. package/schemas/plugins/LoaderOptionsPlugin.check.d.ts +1 -1
  519. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  520. package/schemas/plugins/{HashedModuleIdsPlugin.check.d.ts → ManifestPlugin.check.d.ts} +2 -2
  521. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  522. package/schemas/plugins/ManifestPlugin.json +98 -0
  523. package/schemas/plugins/ProgressPlugin.check.d.ts +1 -1
  524. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  525. package/schemas/plugins/ProgressPlugin.json +1 -1
  526. package/schemas/plugins/SourceMapDevToolPlugin.check.d.ts +1 -1
  527. package/schemas/plugins/SourceMapDevToolPlugin.check.js +2 -2
  528. package/schemas/plugins/SourceMapDevToolPlugin.json +23 -6
  529. package/schemas/plugins/WatchIgnorePlugin.check.d.ts +1 -1
  530. package/schemas/plugins/WatchIgnorePlugin.check.js +1 -1
  531. package/schemas/plugins/asset/AssetGeneratorOptions.check.d.ts +1 -1
  532. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  533. package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.d.ts +1 -1
  534. package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js +1 -1
  535. package/schemas/plugins/asset/AssetParserOptions.check.d.ts +1 -1
  536. package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
  537. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.d.ts +1 -1
  538. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  539. package/schemas/plugins/container/ContainerPlugin.check.d.ts +1 -1
  540. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  541. package/schemas/plugins/container/ContainerReferencePlugin.check.d.ts +1 -1
  542. package/schemas/plugins/container/ContainerReferencePlugin.check.js +2 -2
  543. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  544. package/schemas/plugins/container/ExternalsType.check.d.ts +1 -1
  545. package/schemas/plugins/container/ExternalsType.check.js +2 -2
  546. package/schemas/plugins/container/ModuleFederationPlugin.check.d.ts +1 -1
  547. package/schemas/plugins/container/ModuleFederationPlugin.check.js +2 -2
  548. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  549. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +1 -1
  550. package/schemas/plugins/css/CssGeneratorOptions.check.js +1 -1
  551. package/schemas/plugins/css/CssModuleGeneratorOptions.check.d.ts +1 -1
  552. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +2 -2
  553. package/schemas/plugins/css/CssModuleParserOptions.check.d.ts +1 -1
  554. package/schemas/plugins/css/CssModuleParserOptions.check.js +2 -2
  555. package/schemas/plugins/css/CssParserOptions.check.d.ts +1 -1
  556. package/schemas/plugins/css/CssParserOptions.check.js +2 -2
  557. package/schemas/plugins/debug/ProfilingPlugin.check.d.ts +1 -1
  558. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  559. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.d.ts +7 -0
  560. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +6 -0
  561. package/schemas/plugins/{HashedModuleIdsPlugin.json → ids/HashedModuleIdsPlugin.json} +15 -2
  562. package/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.d.ts +1 -1
  563. package/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.js +1 -1
  564. package/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.d.ts +1 -1
  565. package/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.js +1 -1
  566. package/schemas/plugins/{css/CssGlobalParserOptions.check.d.ts → json/JsonModulesPluginGenerator.check.d.ts} +1 -1
  567. package/schemas/plugins/json/JsonModulesPluginGenerator.check.js +6 -0
  568. package/schemas/plugins/json/JsonModulesPluginGenerator.json +3 -0
  569. package/schemas/plugins/{css/CssGlobalGeneratorOptions.check.d.ts → json/JsonModulesPluginParser.check.d.ts} +1 -1
  570. package/schemas/plugins/json/JsonModulesPluginParser.check.js +6 -0
  571. package/schemas/plugins/json/JsonModulesPluginParser.json +3 -0
  572. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.d.ts +1 -1
  573. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
  574. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.d.ts +1 -1
  575. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
  576. package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.d.ts +1 -1
  577. package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js +1 -1
  578. package/schemas/plugins/optimize/MinChunkSizePlugin.check.d.ts +1 -1
  579. package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
  580. package/schemas/plugins/schemes/HttpUriPlugin.check.d.ts +1 -1
  581. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  582. package/schemas/plugins/schemes/VirtualUrlPlugin.check.d.ts +7 -0
  583. package/schemas/plugins/schemes/VirtualUrlPlugin.check.js +6 -0
  584. package/schemas/plugins/schemes/VirtualUrlPlugin.json +77 -0
  585. package/schemas/plugins/sharing/ConsumeSharedPlugin.check.d.ts +1 -1
  586. package/schemas/plugins/sharing/ConsumeSharedPlugin.check.js +1 -1
  587. package/schemas/plugins/sharing/ProvideSharedPlugin.check.d.ts +1 -1
  588. package/schemas/plugins/sharing/ProvideSharedPlugin.check.js +1 -1
  589. package/schemas/plugins/sharing/SharePlugin.check.d.ts +1 -1
  590. package/schemas/plugins/sharing/SharePlugin.check.js +1 -1
  591. package/types.d.ts +5115 -1863
  592. package/SECURITY.md +0 -9
  593. package/lib/ModuleSourceTypesConstants.js +0 -112
  594. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -250
  595. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +0 -111
  596. package/lib/library/ModernModuleLibraryPlugin.js +0 -144
  597. package/schemas/plugins/HashedModuleIdsPlugin.check.js +0 -6
  598. package/schemas/plugins/JsonModulesPluginParser.check.d.ts +0 -7
  599. package/schemas/plugins/JsonModulesPluginParser.check.js +0 -6
  600. package/schemas/plugins/JsonModulesPluginParser.json +0 -12
  601. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +0 -7
  602. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +0 -6
  603. package/schemas/plugins/css/CssAutoGeneratorOptions.json +0 -3
  604. package/schemas/plugins/css/CssAutoParserOptions.check.d.ts +0 -7
  605. package/schemas/plugins/css/CssAutoParserOptions.check.js +0 -6
  606. package/schemas/plugins/css/CssAutoParserOptions.json +0 -3
  607. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +0 -6
  608. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +0 -3
  609. package/schemas/plugins/css/CssGlobalParserOptions.check.js +0 -6
  610. package/schemas/plugins/css/CssGlobalParserOptions.json +0 -3
@@ -6,16 +6,21 @@
6
6
  "use strict";
7
7
 
8
8
  const EventEmitter = require("events");
9
- const { extname, basename } = require("path");
10
- const { URL } = require("url");
11
- const { createGunzip, createBrotliDecompress, createInflate } = require("zlib");
9
+ const { basename, extname } = require("path");
10
+ const {
11
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
12
+ createBrotliDecompress,
13
+ createGunzip,
14
+ createInflate
15
+ } = require("zlib");
12
16
  const NormalModule = require("../NormalModule");
13
17
  const createSchemaValidation = require("../util/create-schema-validation");
14
18
  const createHash = require("../util/createHash");
15
- const { mkdirp, dirname, join } = require("../util/fs");
19
+ const { dirname, join, mkdirp } = require("../util/fs");
16
20
  const memoize = require("../util/memoize");
17
21
 
18
22
  /** @typedef {import("http").IncomingMessage} IncomingMessage */
23
+ /** @typedef {import("http").OutgoingHttpHeaders} OutgoingHttpHeaders */
19
24
  /** @typedef {import("http").RequestOptions} RequestOptions */
20
25
  /** @typedef {import("net").Socket} Socket */
21
26
  /** @typedef {import("stream").Readable} Readable */
@@ -29,10 +34,12 @@ const memoize = require("../util/memoize");
29
34
  const getHttp = memoize(() => require("http"));
30
35
  const getHttps = memoize(() => require("https"));
31
36
 
37
+ const MAX_REDIRECTS = 5;
38
+
32
39
  /**
33
40
  * @param {typeof import("http") | typeof import("https")} request request
34
- * @param {string | { toString: () => string } | undefined} proxy proxy
35
- * @returns {function(URL, RequestOptions, function(IncomingMessage): void): EventEmitter} fn
41
+ * @param {string | URL | undefined} proxy proxy
42
+ * @returns {(url: URL, requestOptions: RequestOptions, callback: (incomingMessage: IncomingMessage) => void) => EventEmitter} fn
36
43
  */
37
44
  const proxyFetch = (request, proxy) => (url, options, callback) => {
38
45
  const eventEmitter = new EventEmitter();
@@ -41,7 +48,7 @@ const proxyFetch = (request, proxy) => (url, options, callback) => {
41
48
  * @param {Socket=} socket socket
42
49
  * @returns {void}
43
50
  */
44
- const doRequest = socket => {
51
+ const doRequest = (socket) => {
45
52
  request
46
53
  .get(url, { ...options, ...(socket && { socket }) }, callback)
47
54
  .on("error", eventEmitter.emit.bind(eventEmitter, "error"));
@@ -63,7 +70,7 @@ const proxyFetch = (request, proxy) => (url, options, callback) => {
63
70
  doRequest(socket);
64
71
  }
65
72
  })
66
- .on("error", err => {
73
+ .on("error", (err) => {
67
74
  eventEmitter.emit(
68
75
  "error",
69
76
  new Error(
@@ -84,7 +91,7 @@ const proxyFetch = (request, proxy) => (url, options, callback) => {
84
91
  let inProgressWrite;
85
92
 
86
93
  const validate = createSchemaValidation(
87
- require("../../schemas/plugins/schemes/HttpUriPlugin.check.js"),
94
+ require("../../schemas/plugins/schemes/HttpUriPlugin.check"),
88
95
  () => require("../../schemas/plugins/schemes/HttpUriPlugin.json"),
89
96
  {
90
97
  name: "Http Uri Plugin",
@@ -96,7 +103,7 @@ const validate = createSchemaValidation(
96
103
  * @param {string} str path
97
104
  * @returns {string} safe path
98
105
  */
99
- const toSafePath = str =>
106
+ const toSafePath = (str) =>
100
107
  str
101
108
  .replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, "")
102
109
  .replace(/[^a-zA-Z0-9._-]+/g, "_");
@@ -105,7 +112,7 @@ const toSafePath = str =>
105
112
  * @param {Buffer} content content
106
113
  * @returns {string} integrity
107
114
  */
108
- const computeIntegrity = content => {
115
+ const computeIntegrity = (content) => {
109
116
  const hash = createHash("sha512");
110
117
  hash.update(content);
111
118
  const integrity = `sha512-${hash.digest("base64")}`;
@@ -126,7 +133,7 @@ const verifyIntegrity = (content, integrity) => {
126
133
  * @param {string} str input
127
134
  * @returns {Record<string, string>} parsed
128
135
  */
129
- const parseKeyValuePairs = str => {
136
+ const parseKeyValuePairs = (str) => {
130
137
  /** @type {Record<string, string>} */
131
138
  const result = {};
132
139
  for (const item of str.split(",")) {
@@ -147,7 +154,7 @@ const parseKeyValuePairs = str => {
147
154
  /**
148
155
  * @param {string | undefined} cacheControl Cache-Control header
149
156
  * @param {number} requestTime timestamp of request
150
- * @returns {{storeCache: boolean, storeLock: boolean, validUntil: number}} Logic for storing in cache and lockfile cache
157
+ * @returns {{ storeCache: boolean, storeLock: boolean, validUntil: number }} Logic for storing in cache and lockfile cache
151
158
  */
152
159
  const parseCacheControl = (cacheControl, requestTime) => {
153
160
  // When false resource is not stored in cache
@@ -190,11 +197,27 @@ const areLockfileEntriesEqual = (a, b) =>
190
197
 
191
198
  /**
192
199
  * @param {LockfileEntry} entry lockfile entry
193
- * @returns {`resolved: ${string}, integrity: ${string}, contentType: ${*}`} stringified entry
200
+ * @returns {`resolved: ${string}, integrity: ${string}, contentType: ${string}`} stringified entry
194
201
  */
195
- const entryToString = entry =>
202
+ const entryToString = (entry) =>
196
203
  `resolved: ${entry.resolved}, integrity: ${entry.integrity}, contentType: ${entry.contentType}`;
197
204
 
205
+ /**
206
+ * Sanitize URL for inclusion in error messages
207
+ * @param {string} href URL string to sanitize
208
+ * @returns {string} sanitized URL text for logs/errors
209
+ */
210
+ const sanitizeUrlForError = (href) => {
211
+ try {
212
+ const u = new URL(href);
213
+ return `${u.protocol}//${u.host}`;
214
+ } catch (_err) {
215
+ return String(href)
216
+ .slice(0, 200)
217
+ .replace(/[\r\n]/g, "");
218
+ }
219
+ };
220
+
198
221
  class Lockfile {
199
222
  constructor() {
200
223
  this.version = 1;
@@ -209,8 +232,9 @@ class Lockfile {
209
232
  static parse(content) {
210
233
  // TODO handle merge conflicts
211
234
  const data = JSON.parse(content);
212
- if (data.version !== 1)
235
+ if (data.version !== 1) {
213
236
  throw new Error(`Unsupported lockfile version ${data.version}`);
237
+ }
214
238
  const lockfile = new Lockfile();
215
239
  for (const key of Object.keys(data)) {
216
240
  if (key === "version") continue;
@@ -233,16 +257,15 @@ class Lockfile {
233
257
  */
234
258
  toString() {
235
259
  let str = "{\n";
236
- const entries = Array.from(this.entries).sort(([a], [b]) =>
237
- a < b ? -1 : 1
238
- );
260
+ const entries = [...this.entries].sort(([a], [b]) => (a < b ? -1 : 1));
239
261
  for (const [key, entry] of entries) {
240
262
  if (typeof entry === "string") {
241
263
  str += ` ${JSON.stringify(key)}: ${JSON.stringify(entry)},\n`;
242
264
  } else {
243
265
  str += ` ${JSON.stringify(key)}: { `;
244
- if (entry.resolved !== key)
266
+ if (entry.resolved !== key) {
245
267
  str += `"resolved": ${JSON.stringify(entry.resolved)}, `;
268
+ }
246
269
  str += `"integrity": ${JSON.stringify(
247
270
  entry.integrity
248
271
  )}, "contentType": ${JSON.stringify(entry.contentType)} },\n`;
@@ -255,18 +278,28 @@ class Lockfile {
255
278
 
256
279
  /**
257
280
  * @template R
258
- * @param {function(function(Error | null, R=): void): void} fn function
259
- * @returns {function(function(Error | null, R=): void): void} cached function
281
+ * @typedef {(err: Error | null, result?: R) => void} FnWithoutKeyCallback
260
282
  */
261
- const cachedWithoutKey = fn => {
283
+
284
+ /**
285
+ * @template R
286
+ * @typedef {(callback: FnWithoutKeyCallback<R>) => void} FnWithoutKey
287
+ */
288
+
289
+ /**
290
+ * @template R
291
+ * @param {FnWithoutKey<R>} fn function
292
+ * @returns {FnWithoutKey<R>} cached function
293
+ */
294
+ const cachedWithoutKey = (fn) => {
262
295
  let inFlight = false;
263
296
  /** @type {Error | undefined} */
264
297
  let cachedError;
265
298
  /** @type {R | undefined} */
266
299
  let cachedResult;
267
- /** @type {(function(Error| null, R=): void)[] | undefined} */
300
+ /** @type {FnWithoutKeyCallback<R>[] | undefined} */
268
301
  let cachedCallbacks;
269
- return callback => {
302
+ return (callback) => {
270
303
  if (inFlight) {
271
304
  if (cachedResult !== undefined) return callback(null, cachedResult);
272
305
  if (cachedError !== undefined) return callback(cachedError);
@@ -286,30 +319,42 @@ const cachedWithoutKey = fn => {
286
319
  };
287
320
  };
288
321
 
322
+ /**
323
+ * @template R
324
+ * @typedef {(err: Error | null, result?: R) => void} FnWithKeyCallback
325
+ */
326
+
289
327
  /**
290
328
  * @template T
291
329
  * @template R
292
- * @param {function(T, function(Error | null, R=): void): void} fn function
293
- * @param {function(T, function(Error | null, R=): void): void=} forceFn function for the second try
294
- * @returns {(function(T, function(Error | null, R=): void): void) & { force: function(T, function(Error | null, R=): void): void }} cached function
330
+ * @typedef {(item: T, callback: FnWithKeyCallback<R>) => void} FnWithKey
331
+ */
332
+
333
+ /**
334
+ * @template T
335
+ * @template R
336
+ * @param {FnWithKey<T, R>} fn function
337
+ * @param {FnWithKey<T, R>=} forceFn function for the second try
338
+ * @returns {FnWithKey<T, R> & { force: FnWithKey<T, R> }} cached function
295
339
  */
296
340
  const cachedWithKey = (fn, forceFn = fn) => {
297
341
  /**
298
342
  * @template R
299
- * @typedef {{ result?: R, error?: Error, callbacks?: (function(Error | null, R=): void)[], force?: true }} CacheEntry
343
+ * @typedef {{ result?: R, error?: Error, callbacks?: FnWithKeyCallback<R>[], force?: true }} CacheEntry
300
344
  */
301
345
  /** @type {Map<T, CacheEntry<R>>} */
302
346
  const cache = new Map();
303
347
  /**
304
348
  * @param {T} arg arg
305
- * @param {function(Error | null, R=): void} callback callback
349
+ * @param {FnWithKeyCallback<R>} callback callback
306
350
  * @returns {void}
307
351
  */
308
352
  const resultFn = (arg, callback) => {
309
353
  const cacheEntry = cache.get(arg);
310
354
  if (cacheEntry !== undefined) {
311
- if (cacheEntry.result !== undefined)
355
+ if (cacheEntry.result !== undefined) {
312
356
  return callback(null, cacheEntry.result);
357
+ }
313
358
  if (cacheEntry.error !== undefined) return callback(cacheEntry.error);
314
359
  if (cacheEntry.callbacks === undefined) cacheEntry.callbacks = [callback];
315
360
  else cacheEntry.callbacks.push(callback);
@@ -333,14 +378,15 @@ const cachedWithKey = (fn, forceFn = fn) => {
333
378
  };
334
379
  /**
335
380
  * @param {T} arg arg
336
- * @param {function(Error | null, R=): void} callback callback
381
+ * @param {FnWithKeyCallback<R>} callback callback
337
382
  * @returns {void}
338
383
  */
339
384
  resultFn.force = (arg, callback) => {
340
385
  const cacheEntry = cache.get(arg);
341
386
  if (cacheEntry !== undefined && cacheEntry.force) {
342
- if (cacheEntry.result !== undefined)
387
+ if (cacheEntry.result !== undefined) {
343
388
  return callback(null, cacheEntry.result);
389
+ }
344
390
  if (cacheEntry.error !== undefined) return callback(cacheEntry.error);
345
391
  if (cacheEntry.callbacks === undefined) cacheEntry.callbacks = [callback];
346
392
  else cacheEntry.callbacks.push(callback);
@@ -384,6 +430,8 @@ const cachedWithKey = (fn, forceFn = fn) => {
384
430
  /** @typedef {FetchResultMeta & { entry: LockfileEntry, content: Buffer }} ContentFetchResult */
385
431
  /** @typedef {RedirectFetchResult | ContentFetchResult} FetchResult */
386
432
 
433
+ const PLUGIN_NAME = "HttpUriPlugin";
434
+
387
435
  class HttpUriPlugin {
388
436
  /**
389
437
  * @param {HttpUriPluginOptions} options options
@@ -419,14 +467,14 @@ class HttpUriPlugin {
419
467
  /** @type {LockfileCache} */
420
468
  let lockfileCache;
421
469
  compiler.hooks.compilation.tap(
422
- "HttpUriPlugin",
470
+ PLUGIN_NAME,
423
471
  (compilation, { normalModuleFactory }) => {
424
472
  const intermediateFs =
425
473
  /** @type {IntermediateFileSystem} */
426
474
  (compiler.intermediateFileSystem);
427
475
  const fs = compilation.inputFileSystem;
428
- const cache = compilation.getCache("webpack.HttpUriPlugin");
429
- const logger = compilation.getLogger("webpack.HttpUriPlugin");
476
+ const cache = compilation.getCache(`webpack.${PLUGIN_NAME}`);
477
+ const logger = compilation.getLogger(`webpack.${PLUGIN_NAME}`);
430
478
  /** @type {string} */
431
479
  const lockfileLocation =
432
480
  this._lockfileLocation ||
@@ -457,7 +505,7 @@ class HttpUriPlugin {
457
505
  * @param {string} url the url
458
506
  * @returns {string} the key
459
507
  */
460
- const getCacheKey = url => {
508
+ const getCacheKey = (url) => {
461
509
  const cachedResult = cacheKeyCache.get(url);
462
510
  if (cachedResult !== undefined) return cachedResult;
463
511
  const result = _getCacheKey(url);
@@ -469,7 +517,7 @@ class HttpUriPlugin {
469
517
  * @param {string} url the url
470
518
  * @returns {string} the key
471
519
  */
472
- const _getCacheKey = url => {
520
+ const _getCacheKey = (url) => {
473
521
  const parsedUrl = new URL(url);
474
522
  const folder = toSafePath(parsedUrl.origin);
475
523
  const name = toSafePath(parsedUrl.pathname);
@@ -487,10 +535,10 @@ class HttpUriPlugin {
487
535
 
488
536
  const getLockfile = cachedWithoutKey(
489
537
  /**
490
- * @param {function(Error | null, Lockfile=): void} callback callback
538
+ * @param {(err: Error | null, lockfile?: Lockfile) => void} callback callback
491
539
  * @returns {void}
492
540
  */
493
- callback => {
541
+ (callback) => {
494
542
  const readLockfile = () => {
495
543
  intermediateFs.readFile(lockfileLocation, (err, buffer) => {
496
544
  if (err && err.code !== "ENOENT") {
@@ -507,7 +555,7 @@ class HttpUriPlugin {
507
555
  (err, s) => {
508
556
  if (err) return callback(err);
509
557
  const lockfile = buffer
510
- ? Lockfile.parse(buffer.toString("utf-8"))
558
+ ? Lockfile.parse(buffer.toString("utf8"))
511
559
  : new Lockfile();
512
560
  lockfileCache = {
513
561
  lockfile,
@@ -581,19 +629,20 @@ class HttpUriPlugin {
581
629
  * @param {Lockfile} lockfile lockfile
582
630
  * @param {string} url url
583
631
  * @param {ResolveContentResult} result result
584
- * @param {function(Error | null, ResolveContentResult=): void} callback callback
632
+ * @param {(err: Error | null, result?: ResolveContentResult) => void} callback callback
585
633
  * @returns {void}
586
634
  */
587
635
  const storeResult = (lockfile, url, result, callback) => {
588
636
  if (result.storeLock) {
589
637
  storeLockEntry(lockfile, url, result.entry);
590
- if (!cacheLocation || !result.content)
638
+ if (!cacheLocation || !result.content) {
591
639
  return callback(null, result);
640
+ }
592
641
  const key = getCacheKey(result.entry.resolved);
593
642
  const filePath = join(intermediateFs, cacheLocation, key);
594
- mkdirp(intermediateFs, dirname(intermediateFs, filePath), err => {
643
+ mkdirp(intermediateFs, dirname(intermediateFs, filePath), (err) => {
595
644
  if (err) return callback(err);
596
- intermediateFs.writeFile(filePath, result.content, err => {
645
+ intermediateFs.writeFile(filePath, result.content, (err) => {
597
646
  if (err) return callback(err);
598
647
  callback(null, result);
599
648
  });
@@ -605,22 +654,70 @@ class HttpUriPlugin {
605
654
  };
606
655
 
607
656
  for (const { scheme, fetch } of schemes) {
657
+ /**
658
+ * @param {string} location Location header value (relative or absolute)
659
+ * @param {string} base current absolute URL
660
+ * @returns {string} absolute, validated redirect target
661
+ */
662
+ const validateRedirectLocation = (location, base) => {
663
+ let nextUrl;
664
+ try {
665
+ nextUrl = new URL(location, base);
666
+ } catch (err) {
667
+ throw new Error(
668
+ `Invalid redirect URL: ${sanitizeUrlForError(location)}`,
669
+ { cause: err }
670
+ );
671
+ }
672
+ if (nextUrl.protocol !== "http:" && nextUrl.protocol !== "https:") {
673
+ throw new Error(
674
+ `Redirected URL uses disallowed protocol: ${sanitizeUrlForError(nextUrl.href)}`
675
+ );
676
+ }
677
+ if (!isAllowed(nextUrl.href)) {
678
+ throw new Error(
679
+ `${nextUrl.href} doesn't match the allowedUris policy after redirect. These URIs are allowed:\n${allowedUris
680
+ .map((uri) => ` - ${uri}`)
681
+ .join("\n")}`
682
+ );
683
+ }
684
+ return nextUrl.href;
685
+ };
608
686
  /**
609
687
  * @param {string} url URL
610
688
  * @param {string | null} integrity integrity
611
- * @param {function(Error | null, ResolveContentResult=): void} callback callback
689
+ * @param {(err: Error | null, resolveContentResult?: ResolveContentResult) => void} callback callback
690
+ * @param {number=} redirectCount number of followed redirects
612
691
  */
613
- const resolveContent = (url, integrity, callback) => {
692
+ const resolveContent = (
693
+ url,
694
+ integrity,
695
+ callback,
696
+ redirectCount = 0
697
+ ) => {
614
698
  /**
615
699
  * @param {Error | null} err error
616
- * @param {TODO} result result result
700
+ * @param {FetchResult=} _result fetch result
617
701
  * @returns {void}
618
702
  */
619
- const handleResult = (err, result) => {
703
+ const handleResult = (err, _result) => {
620
704
  if (err) return callback(err);
705
+
706
+ const result = /** @type {FetchResult} */ (_result);
707
+
621
708
  if ("location" in result) {
709
+ // Validate redirect target before following
710
+ let absolute;
711
+ try {
712
+ absolute = validateRedirectLocation(result.location, url);
713
+ } catch (err_) {
714
+ return callback(/** @type {Error} */ (err_));
715
+ }
716
+ if (redirectCount >= MAX_REDIRECTS) {
717
+ return callback(new Error("Too many redirects"));
718
+ }
622
719
  return resolveContent(
623
- result.location,
720
+ absolute,
624
721
  integrity,
625
722
  (err, innerResult) => {
626
723
  if (err) return callback(err);
@@ -631,9 +728,11 @@ class HttpUriPlugin {
631
728
  content,
632
729
  storeLock: storeLock && result.storeLock
633
730
  });
634
- }
731
+ },
732
+ redirectCount + 1
635
733
  );
636
734
  }
735
+
637
736
  if (
638
737
  !result.fresh &&
639
738
  integrity &&
@@ -642,181 +741,188 @@ class HttpUriPlugin {
642
741
  ) {
643
742
  return fetchContent.force(url, handleResult);
644
743
  }
744
+
645
745
  return callback(null, {
646
746
  entry: result.entry,
647
747
  content: result.content,
648
748
  storeLock: result.storeLock
649
749
  });
650
750
  };
751
+
651
752
  fetchContent(url, handleResult);
652
753
  };
653
754
 
654
755
  /**
655
756
  * @param {string} url URL
656
757
  * @param {FetchResult | RedirectFetchResult | undefined} cachedResult result from cache
657
- * @param {function(Error | null, FetchResult=): void} callback callback
758
+ * @param {(err: Error | null, fetchResult?: FetchResult) => void} callback callback
658
759
  * @returns {void}
659
760
  */
660
761
  const fetchContentRaw = (url, cachedResult, callback) => {
661
762
  const requestTime = Date.now();
662
- fetch(
663
- new URL(url),
664
- {
665
- headers: {
666
- "accept-encoding": "gzip, deflate, br",
667
- "user-agent": "webpack",
668
- "if-none-match": /** @type {TODO} */ (
669
- cachedResult ? cachedResult.etag || null : null
670
- )
671
- }
672
- },
673
- res => {
674
- const etag = res.headers.etag;
675
- const location = res.headers.location;
676
- const cacheControl = res.headers["cache-control"];
677
- const { storeLock, storeCache, validUntil } = parseCacheControl(
678
- cacheControl,
679
- requestTime
680
- );
681
- /**
682
- * @param {Partial<Pick<FetchResultMeta, "fresh">> & (Pick<RedirectFetchResult, "location"> | Pick<ContentFetchResult, "content" | "entry">)} partialResult result
683
- * @returns {void}
684
- */
685
- const finishWith = partialResult => {
686
- if ("location" in partialResult) {
687
- logger.debug(
688
- `GET ${url} [${res.statusCode}] -> ${partialResult.location}`
689
- );
690
- } else {
691
- logger.debug(
692
- `GET ${url} [${res.statusCode}] ${Math.ceil(
693
- partialResult.content.length / 1024
694
- )} kB${!storeLock ? " no-cache" : ""}`
695
- );
696
- }
697
- const result = {
698
- ...partialResult,
699
- fresh: true,
700
- storeLock,
701
- storeCache,
702
- validUntil,
703
- etag
704
- };
705
- if (!storeCache) {
706
- logger.log(
707
- `${url} can't be stored in cache, due to Cache-Control header: ${cacheControl}`
708
- );
709
- return callback(null, result);
710
- }
711
- cache.store(
712
- url,
713
- null,
714
- {
715
- ...result,
716
- fresh: false
717
- },
718
- err => {
719
- if (err) {
720
- logger.warn(
721
- `${url} can't be stored in cache: ${err.message}`
722
- );
723
- logger.debug(err.stack);
724
- }
725
- callback(null, result);
726
- }
763
+ /** @type {OutgoingHttpHeaders} */
764
+ const headers = {
765
+ "accept-encoding": "gzip, deflate, br",
766
+ "user-agent": "webpack"
767
+ };
768
+
769
+ if (cachedResult && cachedResult.etag) {
770
+ headers["if-none-match"] = cachedResult.etag;
771
+ }
772
+
773
+ fetch(new URL(url), { headers }, (res) => {
774
+ const etag = res.headers.etag;
775
+ const location = res.headers.location;
776
+ const cacheControl = res.headers["cache-control"];
777
+ const { storeLock, storeCache, validUntil } = parseCacheControl(
778
+ cacheControl,
779
+ requestTime
780
+ );
781
+ /**
782
+ * @param {Partial<Pick<FetchResultMeta, "fresh">> & (Pick<RedirectFetchResult, "location"> | Pick<ContentFetchResult, "content" | "entry">)} partialResult result
783
+ * @returns {void}
784
+ */
785
+ const finishWith = (partialResult) => {
786
+ if ("location" in partialResult) {
787
+ logger.debug(
788
+ `GET ${url} [${res.statusCode}] -> ${partialResult.location}`
727
789
  );
790
+ } else {
791
+ logger.debug(
792
+ `GET ${url} [${res.statusCode}] ${Math.ceil(
793
+ partialResult.content.length / 1024
794
+ )} kB${!storeLock ? " no-cache" : ""}`
795
+ );
796
+ }
797
+ const result = {
798
+ ...partialResult,
799
+ fresh: true,
800
+ storeLock,
801
+ storeCache,
802
+ validUntil,
803
+ etag
728
804
  };
729
- if (res.statusCode === 304) {
730
- const result = /** @type {FetchResult} */ (cachedResult);
731
- if (
732
- result.validUntil < validUntil ||
733
- result.storeLock !== storeLock ||
734
- result.storeCache !== storeCache ||
735
- result.etag !== etag
736
- ) {
737
- return finishWith(result);
738
- }
739
- logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`);
740
- return callback(null, { ...result, fresh: true });
805
+ if (!storeCache) {
806
+ logger.log(
807
+ `${url} can't be stored in cache, due to Cache-Control header: ${cacheControl}`
808
+ );
809
+ return callback(null, result);
741
810
  }
811
+ cache.store(
812
+ url,
813
+ null,
814
+ {
815
+ ...result,
816
+ fresh: false
817
+ },
818
+ (err) => {
819
+ if (err) {
820
+ logger.warn(
821
+ `${url} can't be stored in cache: ${err.message}`
822
+ );
823
+ logger.debug(err.stack);
824
+ }
825
+ callback(null, result);
826
+ }
827
+ );
828
+ };
829
+ if (res.statusCode === 304) {
830
+ const result = /** @type {FetchResult} */ (cachedResult);
742
831
  if (
743
- location &&
744
- res.statusCode &&
745
- res.statusCode >= 301 &&
746
- res.statusCode <= 308
832
+ result.validUntil < validUntil ||
833
+ result.storeLock !== storeLock ||
834
+ result.storeCache !== storeCache ||
835
+ result.etag !== etag
747
836
  ) {
748
- const result = {
749
- location: new URL(location, url).href
750
- };
751
- if (
752
- !cachedResult ||
753
- !("location" in cachedResult) ||
754
- cachedResult.location !== result.location ||
755
- cachedResult.validUntil < validUntil ||
756
- cachedResult.storeLock !== storeLock ||
757
- cachedResult.storeCache !== storeCache ||
758
- cachedResult.etag !== etag
759
- ) {
760
- return finishWith(result);
761
- }
762
- logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`);
763
- return callback(null, {
764
- ...result,
765
- fresh: true,
766
- storeLock,
767
- storeCache,
768
- validUntil,
769
- etag
770
- });
837
+ return finishWith(result);
771
838
  }
772
- const contentType = res.headers["content-type"] || "";
773
- /** @type {Buffer[]} */
774
- const bufferArr = [];
775
-
776
- const contentEncoding = res.headers["content-encoding"];
777
- /** @type {Readable} */
778
- let stream = res;
779
- if (contentEncoding === "gzip") {
780
- stream = stream.pipe(createGunzip());
781
- } else if (contentEncoding === "br") {
782
- stream = stream.pipe(createBrotliDecompress());
783
- } else if (contentEncoding === "deflate") {
784
- stream = stream.pipe(createInflate());
839
+ logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`);
840
+ return callback(null, { ...result, fresh: true });
841
+ }
842
+ if (
843
+ location &&
844
+ res.statusCode &&
845
+ res.statusCode >= 301 &&
846
+ res.statusCode <= 308
847
+ ) {
848
+ let absolute;
849
+ try {
850
+ absolute = validateRedirectLocation(location, url);
851
+ } catch (err) {
852
+ logger.log(
853
+ `GET ${url} [${res.statusCode}] -> ${String(location)} (rejected: ${/** @type {Error} */ (err).message})`
854
+ );
855
+ return callback(/** @type {Error} */ (err));
785
856
  }
786
-
787
- stream.on("data", chunk => {
788
- bufferArr.push(chunk);
857
+ const result = { location: absolute };
858
+ if (
859
+ !cachedResult ||
860
+ !("location" in cachedResult) ||
861
+ cachedResult.location !== result.location ||
862
+ cachedResult.validUntil < validUntil ||
863
+ cachedResult.storeLock !== storeLock ||
864
+ cachedResult.storeCache !== storeCache ||
865
+ cachedResult.etag !== etag
866
+ ) {
867
+ return finishWith(result);
868
+ }
869
+ logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`);
870
+ return callback(null, {
871
+ ...result,
872
+ fresh: true,
873
+ storeLock,
874
+ storeCache,
875
+ validUntil,
876
+ etag
789
877
  });
878
+ }
879
+ const contentType = res.headers["content-type"] || "";
880
+ /** @type {Buffer[]} */
881
+ const bufferArr = [];
790
882
 
791
- stream.on("end", () => {
792
- if (!res.complete) {
793
- logger.log(`GET ${url} [${res.statusCode}] (terminated)`);
794
- return callback(new Error(`${url} request was terminated`));
795
- }
883
+ const contentEncoding = res.headers["content-encoding"];
884
+ /** @type {Readable} */
885
+ let stream = res;
886
+ if (contentEncoding === "gzip") {
887
+ stream = stream.pipe(createGunzip());
888
+ } else if (contentEncoding === "br") {
889
+ stream = stream.pipe(createBrotliDecompress());
890
+ } else if (contentEncoding === "deflate") {
891
+ stream = stream.pipe(createInflate());
892
+ }
796
893
 
797
- const content = Buffer.concat(bufferArr);
894
+ stream.on("data", (chunk) => {
895
+ bufferArr.push(chunk);
896
+ });
798
897
 
799
- if (res.statusCode !== 200) {
800
- logger.log(`GET ${url} [${res.statusCode}]`);
801
- return callback(
802
- new Error(
803
- `${url} request status code = ${
804
- res.statusCode
805
- }\n${content.toString("utf-8")}`
806
- )
807
- );
808
- }
898
+ stream.on("end", () => {
899
+ if (!res.complete) {
900
+ logger.log(`GET ${url} [${res.statusCode}] (terminated)`);
901
+ return callback(new Error(`${url} request was terminated`));
902
+ }
809
903
 
810
- const integrity = computeIntegrity(content);
811
- const entry = { resolved: url, integrity, contentType };
904
+ const content = Buffer.concat(bufferArr);
812
905
 
813
- finishWith({
814
- entry,
815
- content
816
- });
906
+ if (res.statusCode !== 200) {
907
+ logger.log(`GET ${url} [${res.statusCode}]`);
908
+ return callback(
909
+ new Error(
910
+ `${url} request status code = ${
911
+ res.statusCode
912
+ }\n${content.toString("utf8")}`
913
+ )
914
+ );
915
+ }
916
+
917
+ const integrity = computeIntegrity(content);
918
+ const entry = { resolved: url, integrity, contentType };
919
+
920
+ finishWith({
921
+ entry,
922
+ content
817
923
  });
818
- }
819
- ).on("error", err => {
924
+ });
925
+ }).on("error", (err) => {
820
926
  logger.log(`GET ${url} (error)`);
821
927
  err.message += `\nwhile fetching ${url}`;
822
928
  callback(err);
@@ -826,7 +932,7 @@ class HttpUriPlugin {
826
932
  const fetchContent = cachedWithKey(
827
933
  /**
828
934
  * @param {string} url URL
829
- * @param {function(Error | null, { validUntil: number, etag?: string, entry: LockfileEntry, content: Buffer, fresh: boolean } | { validUntil: number, etag?: string, location: string, fresh: boolean }=): void} callback callback
935
+ * @param {(err: Error | null, result?: FetchResult) => void} callback callback
830
936
  * @returns {void}
831
937
  */
832
938
  (url, callback) => {
@@ -846,13 +952,29 @@ class HttpUriPlugin {
846
952
  * @param {string} uri uri
847
953
  * @returns {boolean} true when allowed, otherwise false
848
954
  */
849
- const isAllowed = uri => {
955
+ const isAllowed = (uri) => {
956
+ let parsedUri;
957
+ try {
958
+ // Parse the URI to prevent userinfo bypass attacks
959
+ // (e.g., http://allowed@malicious/path where @malicious is the actual host)
960
+ parsedUri = new URL(uri);
961
+ } catch (_err) {
962
+ return false;
963
+ }
850
964
  for (const allowed of allowedUris) {
851
965
  if (typeof allowed === "string") {
852
- if (uri.startsWith(allowed)) return true;
966
+ let parsedAllowed;
967
+ try {
968
+ parsedAllowed = new URL(allowed);
969
+ } catch (_err) {
970
+ continue;
971
+ }
972
+ if (parsedUri.href.startsWith(parsedAllowed.href)) {
973
+ return true;
974
+ }
853
975
  } else if (typeof allowed === "function") {
854
- if (allowed(uri)) return true;
855
- } else if (allowed.test(uri)) {
976
+ if (allowed(parsedUri.href)) return true;
977
+ } else if (allowed.test(parsedUri.href)) {
856
978
  return true;
857
979
  }
858
980
  }
@@ -864,7 +986,7 @@ class HttpUriPlugin {
864
986
  const getInfo = cachedWithKey(
865
987
  /**
866
988
  * @param {string} url the url
867
- * @param {function(Error | null, Info=): void} callback callback
989
+ * @param {(err: Error | null, info?: Info) => void} callback callback
868
990
  * @returns {void}
869
991
  */
870
992
  // eslint-disable-next-line no-loop-func
@@ -873,7 +995,7 @@ class HttpUriPlugin {
873
995
  return callback(
874
996
  new Error(
875
997
  `${url} doesn't match the allowedUris policy. These URIs are allowed:\n${allowedUris
876
- .map(uri => ` - ${uri}`)
998
+ .map((uri) => ` - ${uri}`)
877
999
  .join("\n")}`
878
1000
  )
879
1001
  );
@@ -910,8 +1032,9 @@ class HttpUriPlugin {
910
1032
  const result =
911
1033
  /** @type {ResolveContentResult} */
912
1034
  (_result);
913
- if (!result.storeLock || entryTag === "ignore")
1035
+ if (!result.storeLock || entryTag === "ignore") {
914
1036
  return callback(null, result);
1037
+ }
915
1038
  if (frozen) {
916
1039
  return callback(
917
1040
  new Error(
@@ -936,7 +1059,7 @@ Remove this line from the lockfile to force upgrading.`
936
1059
  /**
937
1060
  * @param {Buffer=} lockedContent locked content
938
1061
  */
939
- const doFetch = lockedContent => {
1062
+ const doFetch = (lockedContent) => {
940
1063
  resolveContent(url, entry.integrity, (err, _result) => {
941
1064
  if (err) {
942
1065
  if (lockedContent) {
@@ -1017,7 +1140,7 @@ Remove this line from the lockfile to force upgrading.`
1017
1140
  * @param {Buffer | undefined} _result result
1018
1141
  * @returns {void}
1019
1142
  */
1020
- const continueWithCachedContent = _result => {
1143
+ const continueWithCachedContent = (_result) => {
1021
1144
  if (!upgrade) {
1022
1145
  // When not in upgrade mode, we accept the result from the lockfile cache
1023
1146
  return callback(null, { entry, content });
@@ -1030,7 +1153,7 @@ Remove this line from the lockfile to force upgrading.`
1030
1153
  let isEolChanged = false;
1031
1154
  try {
1032
1155
  contentWithChangedEol = Buffer.from(
1033
- content.toString("utf-8").replace(/\r\n/g, "\n")
1156
+ content.toString("utf8").replace(/\r\n/g, "\n")
1034
1157
  );
1035
1158
  isEolChanged = verifyIntegrity(
1036
1159
  contentWithChangedEol,
@@ -1065,7 +1188,7 @@ This will avoid that the end of line sequence is changed by git on Windows.`;
1065
1188
  filePath,
1066
1189
  /** @type {Buffer} */
1067
1190
  (contentWithChangedEol),
1068
- err => {
1191
+ (err) => {
1069
1192
  if (err) return callback(err);
1070
1193
  continueWithCachedContent(
1071
1194
  /** @type {Buffer} */
@@ -1113,7 +1236,7 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
1113
1236
  /**
1114
1237
  * @param {URL} url url
1115
1238
  * @param {ResourceDataWithData} resourceData resource data
1116
- * @param {function(Error | null, true | void): void} callback callback
1239
+ * @param {(err: Error | null, result: true | void) => void} callback callback
1117
1240
  */
1118
1241
  const respondWithUrlModule = (url, resourceData, callback) => {
1119
1242
  getInfo(url.href, (err, _result) => {
@@ -1133,19 +1256,16 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
1133
1256
  };
1134
1257
  normalModuleFactory.hooks.resolveForScheme
1135
1258
  .for(scheme)
1136
- .tapAsync(
1137
- "HttpUriPlugin",
1138
- (resourceData, resolveData, callback) => {
1139
- respondWithUrlModule(
1140
- new URL(resourceData.resource),
1141
- resourceData,
1142
- callback
1143
- );
1144
- }
1145
- );
1259
+ .tapAsync(PLUGIN_NAME, (resourceData, resolveData, callback) => {
1260
+ respondWithUrlModule(
1261
+ new URL(resourceData.resource),
1262
+ resourceData,
1263
+ callback
1264
+ );
1265
+ });
1146
1266
  normalModuleFactory.hooks.resolveInScheme
1147
1267
  .for(scheme)
1148
- .tapAsync("HttpUriPlugin", (resourceData, data, callback) => {
1268
+ .tapAsync(PLUGIN_NAME, (resourceData, data, callback) => {
1149
1269
  // Only handle relative urls (./xxx, ../xxx, /xxx, //xxx)
1150
1270
  if (
1151
1271
  data.dependencyType !== "url" &&
@@ -1162,42 +1282,38 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
1162
1282
  const hooks = NormalModule.getCompilationHooks(compilation);
1163
1283
  hooks.readResourceForScheme
1164
1284
  .for(scheme)
1165
- .tapAsync("HttpUriPlugin", (resource, module, callback) =>
1285
+ .tapAsync(PLUGIN_NAME, (resource, module, callback) =>
1166
1286
  getInfo(resource, (err, _result) => {
1167
1287
  if (err) return callback(err);
1168
1288
  const result = /** @type {Info} */ (_result);
1169
- /** @type {BuildInfo} */
1170
- (module.buildInfo).resourceIntegrity = result.entry.integrity;
1289
+ if (module) {
1290
+ /** @type {BuildInfo} */
1291
+ (module.buildInfo).resourceIntegrity = result.entry.integrity;
1292
+ }
1171
1293
  callback(null, result.content);
1172
1294
  })
1173
1295
  );
1174
- hooks.needBuild.tapAsync(
1175
- "HttpUriPlugin",
1176
- (module, context, callback) => {
1177
- if (
1178
- module.resource &&
1179
- module.resource.startsWith(`${scheme}://`)
1180
- ) {
1181
- getInfo(module.resource, (err, _result) => {
1182
- if (err) return callback(err);
1183
- const result = /** @type {Info} */ (_result);
1184
- if (
1185
- result.entry.integrity !==
1186
- /** @type {BuildInfo} */
1187
- (module.buildInfo).resourceIntegrity
1188
- ) {
1189
- return callback(null, true);
1190
- }
1191
- callback();
1192
- });
1193
- } else {
1194
- return callback();
1195
- }
1296
+ hooks.needBuild.tapAsync(PLUGIN_NAME, (module, context, callback) => {
1297
+ if (module.resource && module.resource.startsWith(`${scheme}://`)) {
1298
+ getInfo(module.resource, (err, _result) => {
1299
+ if (err) return callback(err);
1300
+ const result = /** @type {Info} */ (_result);
1301
+ if (
1302
+ result.entry.integrity !==
1303
+ /** @type {BuildInfo} */
1304
+ (module.buildInfo).resourceIntegrity
1305
+ ) {
1306
+ return callback(null, true);
1307
+ }
1308
+ callback();
1309
+ });
1310
+ } else {
1311
+ return callback();
1196
1312
  }
1197
- );
1313
+ });
1198
1314
  }
1199
1315
  compilation.hooks.finishModules.tapAsync(
1200
- "HttpUriPlugin",
1316
+ PLUGIN_NAME,
1201
1317
  (modules, callback) => {
1202
1318
  if (!lockfileUpdates) return callback();
1203
1319
  const ext = extname(lockfileLocation);
@@ -1226,22 +1342,17 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
1226
1342
  return callback(err);
1227
1343
  }
1228
1344
  const lockfile = buffer
1229
- ? Lockfile.parse(buffer.toString("utf-8"))
1345
+ ? Lockfile.parse(buffer.toString("utf8"))
1230
1346
  : new Lockfile();
1231
1347
  for (const [key, value] of /** @type {LockfileUpdates} */ (
1232
1348
  lockfileUpdates
1233
1349
  )) {
1234
1350
  lockfile.entries.set(key, value);
1235
1351
  }
1236
- intermediateFs.writeFile(tempFile, lockfile.toString(), err => {
1237
- if (err) {
1238
- writeDone();
1239
- return (
1240
- /** @type {NonNullable<IntermediateFileSystem["unlink"]>} */
1241
- (intermediateFs.unlink)(tempFile, () => callback(err))
1242
- );
1243
- }
1244
- intermediateFs.rename(tempFile, lockfileLocation, err => {
1352
+ intermediateFs.writeFile(
1353
+ tempFile,
1354
+ lockfile.toString(),
1355
+ (err) => {
1245
1356
  if (err) {
1246
1357
  writeDone();
1247
1358
  return (
@@ -1249,10 +1360,19 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
1249
1360
  (intermediateFs.unlink)(tempFile, () => callback(err))
1250
1361
  );
1251
1362
  }
1252
- writeDone();
1253
- callback();
1254
- });
1255
- });
1363
+ intermediateFs.rename(tempFile, lockfileLocation, (err) => {
1364
+ if (err) {
1365
+ writeDone();
1366
+ return (
1367
+ /** @type {NonNullable<IntermediateFileSystem["unlink"]>} */
1368
+ (intermediateFs.unlink)(tempFile, () => callback(err))
1369
+ );
1370
+ }
1371
+ writeDone();
1372
+ callback();
1373
+ });
1374
+ }
1375
+ );
1256
1376
  });
1257
1377
  };
1258
1378
  if (inProgressWrite) {