webpack 5.59.0 → 5.71.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 (209) hide show
  1. package/README.md +1 -7
  2. package/hot/lazy-compilation-node.js +3 -1
  3. package/hot/poll.js +1 -1
  4. package/hot/signal.js +1 -1
  5. package/lib/APIPlugin.js +33 -0
  6. package/lib/BannerPlugin.js +10 -4
  7. package/lib/Cache.js +1 -1
  8. package/lib/CacheFacade.js +4 -11
  9. package/lib/Chunk.js +6 -3
  10. package/lib/ChunkGraph.js +1 -2
  11. package/lib/ChunkGroup.js +1 -1
  12. package/lib/CleanPlugin.js +81 -20
  13. package/lib/Compilation.js +179 -91
  14. package/lib/Compiler.js +86 -17
  15. package/lib/ConstPlugin.js +2 -2
  16. package/lib/ContextModule.js +142 -51
  17. package/lib/ContextModuleFactory.js +65 -25
  18. package/lib/DelegatedModule.js +1 -1
  19. package/lib/DelegatedModuleFactoryPlugin.js +1 -1
  20. package/lib/Dependency.js +17 -0
  21. package/lib/DependencyTemplate.js +9 -0
  22. package/lib/DependencyTemplates.js +1 -1
  23. package/lib/DllModule.js +1 -1
  24. package/lib/EntryOptionPlugin.js +2 -0
  25. package/lib/ErrorHelpers.js +2 -2
  26. package/lib/EvalDevToolModulePlugin.js +16 -1
  27. package/lib/EvalSourceMapDevToolPlugin.js +18 -1
  28. package/lib/ExportsInfo.js +4 -4
  29. package/lib/ExternalModule.js +94 -54
  30. package/lib/ExternalModuleFactoryPlugin.js +5 -5
  31. package/lib/FileSystemInfo.js +89 -44
  32. package/lib/Generator.js +3 -0
  33. package/lib/HookWebpackError.js +1 -1
  34. package/lib/HotModuleReplacementPlugin.js +3 -1
  35. package/lib/LoaderOptionsPlugin.js +1 -1
  36. package/lib/Module.js +27 -4
  37. package/lib/ModuleFilenameHelpers.js +8 -4
  38. package/lib/ModuleHashingError.js +29 -0
  39. package/lib/MultiCompiler.js +1 -1
  40. package/lib/MultiWatching.js +1 -1
  41. package/lib/NodeStuffPlugin.js +10 -0
  42. package/lib/NormalModule.js +41 -26
  43. package/lib/NormalModuleFactory.js +42 -37
  44. package/lib/ProgressPlugin.js +4 -5
  45. package/lib/RawModule.js +1 -1
  46. package/lib/RuntimeGlobals.js +29 -1
  47. package/lib/RuntimeModule.js +1 -1
  48. package/lib/RuntimePlugin.js +77 -1
  49. package/lib/RuntimeTemplate.js +114 -2
  50. package/lib/Template.js +2 -1
  51. package/lib/TemplatedPathPlugin.js +48 -23
  52. package/lib/WatchIgnorePlugin.js +19 -7
  53. package/lib/Watching.js +33 -19
  54. package/lib/WebpackOptionsApply.js +57 -11
  55. package/lib/asset/AssetGenerator.js +193 -63
  56. package/lib/asset/AssetModulesPlugin.js +3 -0
  57. package/lib/asset/RawDataUrlModule.js +148 -0
  58. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -4
  59. package/lib/buildChunkGraph.js +36 -6
  60. package/lib/cache/PackFileCacheStrategy.js +7 -4
  61. package/lib/cache/ResolverCachePlugin.js +90 -29
  62. package/lib/cli.js +44 -3
  63. package/lib/config/browserslistTargetHandler.js +41 -6
  64. package/lib/config/defaults.js +115 -19
  65. package/lib/config/normalization.js +9 -0
  66. package/lib/config/target.js +10 -0
  67. package/lib/container/ContainerEntryModule.js +8 -5
  68. package/lib/container/FallbackModule.js +4 -4
  69. package/lib/container/RemoteModule.js +4 -2
  70. package/lib/css/CssExportsGenerator.js +139 -0
  71. package/lib/css/CssGenerator.js +109 -0
  72. package/lib/css/CssLoadingRuntimeModule.js +440 -0
  73. package/lib/css/CssModulesPlugin.js +462 -0
  74. package/lib/css/CssParser.js +618 -0
  75. package/lib/css/walkCssTokens.js +659 -0
  76. package/lib/debug/ProfilingPlugin.js +24 -21
  77. package/lib/dependencies/AMDRequireDependency.js +6 -6
  78. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
  79. package/lib/dependencies/CommonJsFullRequireDependency.js +5 -1
  80. package/lib/dependencies/CommonJsImportsParserPlugin.js +5 -3
  81. package/lib/dependencies/CommonJsRequireContextDependency.js +5 -1
  82. package/lib/dependencies/ContextDependency.js +1 -0
  83. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  84. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +4 -1
  85. package/lib/dependencies/ContextElementDependency.js +41 -3
  86. package/lib/dependencies/CreateScriptUrlDependency.js +12 -0
  87. package/lib/dependencies/CssExportDependency.js +85 -0
  88. package/lib/dependencies/CssImportDependency.js +75 -0
  89. package/lib/dependencies/CssLocalIdentifierDependency.js +119 -0
  90. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +101 -0
  91. package/lib/dependencies/CssUrlDependency.js +132 -0
  92. package/lib/dependencies/ExportsInfoDependency.js +6 -0
  93. package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
  94. package/lib/dependencies/HarmonyCompatibilityDependency.js +5 -5
  95. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +95 -0
  96. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +12 -3
  97. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +25 -17
  98. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  99. package/lib/dependencies/HarmonyImportDependency.js +23 -0
  100. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +142 -45
  101. package/lib/dependencies/HarmonyImportSpecifierDependency.js +46 -22
  102. package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
  103. package/lib/dependencies/ImportContextDependency.js +0 -2
  104. package/lib/dependencies/ImportMetaContextDependency.js +35 -0
  105. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
  106. package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
  107. package/lib/dependencies/ImportMetaPlugin.js +22 -3
  108. package/lib/dependencies/LoaderPlugin.js +4 -2
  109. package/lib/dependencies/RequireContextDependency.js +0 -16
  110. package/lib/dependencies/RequireEnsureDependency.js +2 -2
  111. package/lib/dependencies/URLDependency.js +3 -8
  112. package/lib/dependencies/URLPlugin.js +1 -1
  113. package/lib/esm/ModuleChunkFormatPlugin.js +74 -49
  114. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  115. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +25 -9
  116. package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
  117. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
  118. package/lib/hmr/LazyCompilationPlugin.js +54 -26
  119. package/lib/hmr/lazyCompilationBackend.js +51 -12
  120. package/lib/ids/DeterministicModuleIdsPlugin.js +55 -35
  121. package/lib/ids/HashedModuleIdsPlugin.js +11 -14
  122. package/lib/ids/IdHelpers.js +25 -11
  123. package/lib/ids/NamedModuleIdsPlugin.js +6 -9
  124. package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
  125. package/lib/ids/OccurrenceModuleIdsPlugin.js +13 -10
  126. package/lib/ids/SyncModuleIdsPlugin.js +140 -0
  127. package/lib/index.js +13 -0
  128. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +2 -2
  129. package/lib/javascript/BasicEvaluatedExpression.js +5 -2
  130. package/lib/javascript/ChunkHelpers.js +33 -0
  131. package/lib/javascript/JavascriptGenerator.js +1 -0
  132. package/lib/javascript/JavascriptModulesPlugin.js +27 -2
  133. package/lib/javascript/JavascriptParser.js +82 -48
  134. package/lib/javascript/StartupHelpers.js +7 -30
  135. package/lib/library/AssignLibraryPlugin.js +39 -15
  136. package/lib/library/EnableLibraryPlugin.js +11 -0
  137. package/lib/library/UmdLibraryPlugin.js +5 -3
  138. package/lib/node/NodeTargetPlugin.js +3 -0
  139. package/lib/node/NodeWatchFileSystem.js +85 -31
  140. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +23 -8
  141. package/lib/node/RequireChunkLoadingRuntimeModule.js +24 -9
  142. package/lib/optimize/ConcatenatedModule.js +21 -9
  143. package/lib/optimize/ModuleConcatenationPlugin.js +5 -2
  144. package/lib/optimize/SplitChunksPlugin.js +8 -1
  145. package/lib/runtime/AsyncModuleRuntimeModule.js +27 -17
  146. package/lib/runtime/BaseUriRuntimeModule.js +31 -0
  147. package/lib/runtime/CreateScriptRuntimeModule.js +36 -0
  148. package/lib/runtime/CreateScriptUrlRuntimeModule.js +9 -34
  149. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +76 -0
  150. package/lib/schemes/HttpUriPlugin.js +77 -14
  151. package/lib/serialization/FileMiddleware.js +44 -9
  152. package/lib/sharing/ConsumeSharedModule.js +8 -2
  153. package/lib/sharing/ConsumeSharedRuntimeModule.js +26 -5
  154. package/lib/sharing/ProvideSharedModule.js +4 -2
  155. package/lib/sharing/ShareRuntimeModule.js +1 -1
  156. package/lib/sharing/utils.js +1 -1
  157. package/lib/stats/DefaultStatsFactoryPlugin.js +113 -68
  158. package/lib/stats/DefaultStatsPrinterPlugin.js +89 -24
  159. package/lib/util/ArrayHelpers.js +30 -0
  160. package/lib/util/AsyncQueue.js +1 -1
  161. package/lib/util/compileBooleanMatcher.js +1 -1
  162. package/lib/util/create-schema-validation.js +9 -2
  163. package/lib/util/createHash.js +12 -0
  164. package/lib/util/deprecation.js +10 -2
  165. package/lib/util/deterministicGrouping.js +1 -1
  166. package/lib/util/extractUrlAndGlobal.js +3 -0
  167. package/lib/util/fs.js +11 -0
  168. package/lib/util/hash/BatchedHash.js +7 -4
  169. package/lib/util/hash/md4.js +20 -0
  170. package/lib/util/hash/wasm-hash.js +163 -0
  171. package/lib/util/hash/xxhash64.js +5 -139
  172. package/lib/util/identifier.js +65 -44
  173. package/lib/util/internalSerializables.js +15 -0
  174. package/lib/util/nonNumericOnlyHash.js +22 -0
  175. package/lib/util/semver.js +17 -10
  176. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +9 -3
  177. package/lib/web/JsonpChunkLoadingRuntimeModule.js +20 -9
  178. package/lib/webpack.js +10 -3
  179. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -11
  180. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +33 -22
  181. package/module.d.ts +215 -0
  182. package/package.json +23 -28
  183. package/schemas/WebpackOptions.check.js +1 -1
  184. package/schemas/WebpackOptions.json +254 -29
  185. package/schemas/plugins/DllReferencePlugin.check.js +1 -1
  186. package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
  187. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  188. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  189. package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
  190. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  191. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  192. package/schemas/plugins/container/ContainerPlugin.json +2 -1
  193. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  194. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  195. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  196. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  197. package/schemas/plugins/container/ModuleFederationPlugin.json +3 -1
  198. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
  199. package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
  200. package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
  201. package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
  202. package/schemas/plugins/css/CssParserOptions.check.js +6 -0
  203. package/schemas/plugins/css/CssParserOptions.json +3 -0
  204. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
  205. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
  206. package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
  207. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  208. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  209. package/types.d.ts +628 -179
package/README.md CHANGED
@@ -9,8 +9,6 @@
9
9
 
10
10
  [![node][node]][node-url]
11
11
  [![deps][deps]][deps-url]
12
- [![tests][tests]][tests-url]
13
- [![builds][builds]][builds-url]
14
12
  [![builds2][builds2]][builds2-url]
15
13
  [![coverage][cover]][cover-url]
16
14
  [![licenses][licenses]][licenses-url]
@@ -689,7 +687,7 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI"></a>
689
687
 
690
688
  - [@google](https://github.com/google) for [Google Web Toolkit (GWT)](http://www.gwtproject.org/), which aims to compile Java to JavaScript. It features a similar [Code Splitting](http://www.gwtproject.org/doc/latest/DevGuideCodeSplitting.html) as webpack.
691
689
  - [@medikoo](https://github.com/medikoo) for [modules-webmake](https://github.com/medikoo/modules-webmake), which is a similar project. webpack was born because I wanted Code Splitting for modules-webmake. Interestingly the [Code Splitting issue is still open](https://github.com/medikoo/modules-webmake/issues/7) (thanks also to @Phoscur for the discussion).
692
- - [@substack](https://github.com/substack) for [browserify](http://browserify.org/), which is a similar project and source for many ideas.
690
+ - [@substack](https://github.com/substack) for [browserify](https://browserify.org/), which is a similar project and source for many ideas.
693
691
  - [@jrburke](https://github.com/jrburke) for [require.js](https://requirejs.org/), which is a similar project and source for many ideas.
694
692
  - [@defunctzombie](https://github.com/defunctzombie) for the [browser-field spec](https://github.com/defunctzombie/package-browser-field-spec), which makes modules available for node.js, browserify and webpack.
695
693
  - Every early webpack user, which contributed to webpack by writing issues or PRs. You influenced the direction...
@@ -703,12 +701,8 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI"></a>
703
701
  [node-url]: https://nodejs.org
704
702
  [deps]: https://img.shields.io/david/webpack/webpack.svg
705
703
  [deps-url]: https://david-dm.org/webpack/webpack
706
- [tests]: https://img.shields.io/travis/webpack/webpack/main.svg
707
- [tests-url]: https://travis-ci.org/webpack/webpack
708
704
  [prs]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg
709
705
  [prs-url]: https://webpack.js.org/contribute/
710
- [builds-url]: https://ci.appveyor.com/project/sokra/webpack/branch/main
711
- [builds]: https://ci.appveyor.com/api/projects/status/github/webpack/webpack?svg=true
712
706
  [builds2]: https://dev.azure.com/webpack/webpack/_apis/build/status/webpack.webpack
713
707
  [builds2-url]: https://dev.azure.com/webpack/webpack/_build/latest?definitionId=3
714
708
  [licenses-url]: https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fwebpack%2Fwebpack?ref=badge_shield
@@ -9,7 +9,9 @@ exports.keepAlive = function (options) {
9
9
  var active = options.active;
10
10
  var module = options.module;
11
11
  var response;
12
- var request = require("http").request(
12
+ var request = (
13
+ urlBase.startsWith("https") ? require("https") : require("http")
14
+ ).request(
13
15
  urlBase + data,
14
16
  {
15
17
  agent: false,
package/hot/poll.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  /*globals __resourceQuery */
6
6
  if (module.hot) {
7
- var hotPollInterval = +__resourceQuery.substr(1) || 10 * 60 * 1000;
7
+ var hotPollInterval = +__resourceQuery.slice(1) || 10 * 60 * 1000;
8
8
  var log = require("./log");
9
9
 
10
10
  var checkForUpdate = function checkForUpdate(fromUpdate) {
package/hot/signal.js CHANGED
@@ -45,7 +45,7 @@ if (module.hot) {
45
45
  });
46
46
  };
47
47
 
48
- process.on(__resourceQuery.substr(1) || "SIGUSR2", function () {
48
+ process.on(__resourceQuery.slice(1) || "SIGUSR2", function () {
49
49
  if (module.hot.status() !== "idle") {
50
50
  log(
51
51
  "warning",
package/lib/APIPlugin.js CHANGED
@@ -201,6 +201,39 @@ class APIPlugin {
201
201
  )
202
202
  .setRange(expr.range)
203
203
  );
204
+
205
+ parser.hooks.expression
206
+ .for("__webpack_module__.id")
207
+ .tap("APIPlugin", expr => {
208
+ parser.state.module.buildInfo.moduleConcatenationBailout =
209
+ "__webpack_module__.id";
210
+ const dep = new ConstDependency(
211
+ parser.state.module.moduleArgument + ".id",
212
+ expr.range,
213
+ [RuntimeGlobals.moduleId]
214
+ );
215
+ dep.loc = expr.loc;
216
+ parser.state.module.addPresentationalDependency(dep);
217
+ return true;
218
+ });
219
+
220
+ parser.hooks.expression
221
+ .for("__webpack_module__")
222
+ .tap("APIPlugin", expr => {
223
+ parser.state.module.buildInfo.moduleConcatenationBailout =
224
+ "__webpack_module__";
225
+ const dep = new ConstDependency(
226
+ parser.state.module.moduleArgument,
227
+ expr.range,
228
+ [RuntimeGlobals.module]
229
+ );
230
+ dep.loc = expr.loc;
231
+ parser.state.module.addPresentationalDependency(dep);
232
+ return true;
233
+ });
234
+ parser.hooks.evaluateTypeof
235
+ .for("__webpack_module__")
236
+ .tap("APIPlugin", evaluateToString("object"));
204
237
  };
205
238
 
206
239
  normalModuleFactory.hooks.parser
@@ -77,6 +77,7 @@ class BannerPlugin {
77
77
  undefined,
78
78
  options
79
79
  );
80
+ const cache = new WeakMap();
80
81
 
81
82
  compiler.hooks.compilation.tap("BannerPlugin", compilation => {
82
83
  compilation.hooks.processAssets.tap(
@@ -102,10 +103,15 @@ class BannerPlugin {
102
103
 
103
104
  const comment = compilation.getPath(banner, data);
104
105
 
105
- compilation.updateAsset(
106
- file,
107
- old => new ConcatSource(comment, "\n", old)
108
- );
106
+ compilation.updateAsset(file, old => {
107
+ let cached = cache.get(old);
108
+ if (!cached || cached.comment !== comment) {
109
+ const source = new ConcatSource(comment, "\n", old);
110
+ cache.set(old, { source, comment });
111
+ return source;
112
+ }
113
+ return cached.source;
114
+ });
109
115
  }
110
116
  }
111
117
  }
package/lib/Cache.js CHANGED
@@ -21,7 +21,7 @@ const {
21
21
  /**
22
22
  * @template T
23
23
  * @callback CallbackCache
24
- * @param {WebpackError=} err
24
+ * @param {(WebpackError | null)=} err
25
25
  * @param {T=} result
26
26
  * @returns {void}
27
27
  */
@@ -5,6 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const { forEachBail } = require("enhanced-resolve");
8
9
  const asyncLib = require("neo-async");
9
10
  const getLazyHashedEtag = require("./cache/getLazyHashedEtag");
10
11
  const mergeEtags = require("./cache/mergeEtags");
@@ -18,7 +19,7 @@ const mergeEtags = require("./cache/mergeEtags");
18
19
  /**
19
20
  * @template T
20
21
  * @callback CallbackCache
21
- * @param {WebpackError=} err
22
+ * @param {(WebpackError | null)=} err
22
23
  * @param {T=} result
23
24
  * @returns {void}
24
25
  */
@@ -26,7 +27,7 @@ const mergeEtags = require("./cache/mergeEtags");
26
27
  /**
27
28
  * @template T
28
29
  * @callback CallbackNormalErrorCache
29
- * @param {Error=} err
30
+ * @param {(Error | null)=} err
30
31
  * @param {T=} result
31
32
  * @returns {void}
32
33
  */
@@ -46,15 +47,7 @@ class MultiItemCache {
46
47
  * @returns {void}
47
48
  */
48
49
  get(callback) {
49
- const next = i => {
50
- this._items[i].get((err, result) => {
51
- if (err) return callback(err);
52
- if (result !== undefined) return callback(null, result);
53
- if (++i >= this._items.length) return callback();
54
- next(i);
55
- });
56
- };
57
- next(0);
50
+ forEachBail(this._items, (item, callback) => item.get(callback), callback);
58
51
  }
59
52
 
60
53
  /**
package/lib/Chunk.js CHANGED
@@ -63,8 +63,9 @@ let debugId = 1000;
63
63
  class Chunk {
64
64
  /**
65
65
  * @param {string=} name of chunk being created, is optional (for subclasses)
66
+ * @param {boolean} backCompat enable backward-compatibility
66
67
  */
67
- constructor(name) {
68
+ constructor(name, backCompat = true) {
68
69
  /** @type {number | string | null} */
69
70
  this.id = null;
70
71
  /** @type {(number|string)[] | null} */
@@ -79,12 +80,14 @@ class Chunk {
79
80
  this.preventIntegration = false;
80
81
  /** @type {(string | function(PathData, AssetInfo=): string)?} */
81
82
  this.filenameTemplate = undefined;
83
+ /** @type {(string | function(PathData, AssetInfo=): string)?} */
84
+ this.cssFilenameTemplate = undefined;
82
85
  /** @private @type {SortableSet<ChunkGroup>} */
83
86
  this._groups = new SortableSet(undefined, compareChunkGroupsByIndex);
84
87
  /** @type {RuntimeSpec} */
85
88
  this.runtime = undefined;
86
89
  /** @type {Set<string>} */
87
- this.files = new ChunkFilesSet();
90
+ this.files = backCompat ? new ChunkFilesSet() : new Set();
88
91
  /** @type {Set<string>} */
89
92
  this.auxiliaryFiles = new Set();
90
93
  /** @type {boolean} */
@@ -687,7 +690,7 @@ class Chunk {
687
690
  for (const childGroup of group.childrenIterable) {
688
691
  for (const key of Object.keys(childGroup.options)) {
689
692
  if (key.endsWith("Order")) {
690
- const name = key.substr(0, key.length - "Order".length);
693
+ const name = key.slice(0, key.length - "Order".length);
691
694
  let list = lists.get(name);
692
695
  if (list === undefined) {
693
696
  list = [];
package/lib/ChunkGraph.js CHANGED
@@ -46,6 +46,7 @@ const compareModuleIterables = compareIterables(compareModulesByIdentifier);
46
46
 
47
47
  /** @typedef {(c: Chunk, chunkGraph: ChunkGraph) => boolean} ChunkFilterPredicate */
48
48
  /** @typedef {(m: Module) => boolean} ModuleFilterPredicate */
49
+ /** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */
49
50
 
50
51
  /**
51
52
  * @typedef {Object} ChunkSizeOptions
@@ -1180,8 +1181,6 @@ class ChunkGraph {
1180
1181
  return cgc.dependentHashModules;
1181
1182
  }
1182
1183
 
1183
- /** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */
1184
-
1185
1184
  /**
1186
1185
  * @param {Chunk} chunk the chunk
1187
1186
  * @returns {Iterable<EntryModuleWithChunkGroup>} iterable of modules (do not modify)
package/lib/ChunkGroup.js CHANGED
@@ -486,7 +486,7 @@ class ChunkGroup {
486
486
  for (const childGroup of this._children) {
487
487
  for (const key of Object.keys(childGroup.options)) {
488
488
  if (key.endsWith("Order")) {
489
- const name = key.substr(0, key.length - "Order".length);
489
+ const name = key.slice(0, key.length - "Order".length);
490
490
  let list = lists.get(name);
491
491
  if (list === undefined) {
492
492
  lists.set(name, (list = []));
@@ -16,8 +16,10 @@ const processAsyncTree = require("./util/processAsyncTree");
16
16
  /** @typedef {import("./Compiler")} Compiler */
17
17
  /** @typedef {import("./logging/Logger").Logger} Logger */
18
18
  /** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
19
+ /** @typedef {import("./util/fs").StatsCallback} StatsCallback */
19
20
 
20
21
  /** @typedef {(function(string):boolean)|RegExp} IgnoreItem */
22
+ /** @typedef {Map<string, number>} Assets */
21
23
  /** @typedef {function(IgnoreItem): void} AddToIgnoreCallback */
22
24
 
23
25
  /**
@@ -39,18 +41,32 @@ const validate = createSchemaValidation(
39
41
  baseDataPath: "options"
40
42
  }
41
43
  );
44
+ const _10sec = 10 * 1000;
45
+
46
+ /**
47
+ * marge assets map 2 into map 1
48
+ * @param {Assets} as1 assets
49
+ * @param {Assets} as2 assets
50
+ * @returns {void}
51
+ */
52
+ const mergeAssets = (as1, as2) => {
53
+ for (const [key, value1] of as2) {
54
+ const value2 = as1.get(key);
55
+ if (!value2 || value1 > value2) as1.set(key, value1);
56
+ }
57
+ };
42
58
 
43
59
  /**
44
60
  * @param {OutputFileSystem} fs filesystem
45
61
  * @param {string} outputPath output path
46
- * @param {Set<string>} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator)
47
- * @param {function(Error=, Set<string>=): void} callback returns the filenames of the assets that shouldn't be there
62
+ * @param {Map<string, number>} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator)
63
+ * @param {function((Error | null)=, Set<string>=): void} callback returns the filenames of the assets that shouldn't be there
48
64
  * @returns {void}
49
65
  */
50
66
  const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
51
67
  const directories = new Set();
52
68
  // get directories of assets
53
- for (const asset of currentAssets) {
69
+ for (const [asset] of currentAssets) {
54
70
  directories.add(asset.replace(/(^|\/)[^/]*$/, ""));
55
71
  }
56
72
  // and all parent directories
@@ -90,18 +106,34 @@ const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
90
106
  };
91
107
 
92
108
  /**
93
- * @param {Set<string>} currentAssets assets list
94
- * @param {Set<string>} oldAssets old assets list
109
+ * @param {Assets} currentAssets assets list
110
+ * @param {Assets} oldAssets old assets list
95
111
  * @returns {Set<string>} diff
96
112
  */
97
113
  const getDiffToOldAssets = (currentAssets, oldAssets) => {
98
114
  const diff = new Set();
99
- for (const asset of oldAssets) {
115
+ const now = Date.now();
116
+ for (const [asset, ts] of oldAssets) {
117
+ if (ts >= now) continue;
100
118
  if (!currentAssets.has(asset)) diff.add(asset);
101
119
  }
102
120
  return diff;
103
121
  };
104
122
 
123
+ /**
124
+ * @param {OutputFileSystem} fs filesystem
125
+ * @param {string} filename path to file
126
+ * @param {StatsCallback} callback callback for provided filename
127
+ * @returns {void}
128
+ */
129
+ const doStat = (fs, filename, callback) => {
130
+ if ("lstat" in fs) {
131
+ fs.lstat(filename, callback);
132
+ } else {
133
+ fs.stat(filename, callback);
134
+ }
135
+ };
136
+
105
137
  /**
106
138
  * @param {OutputFileSystem} fs filesystem
107
139
  * @param {string} outputPath output path
@@ -109,7 +141,7 @@ const getDiffToOldAssets = (currentAssets, oldAssets) => {
109
141
  * @param {Logger} logger logger
110
142
  * @param {Set<string>} diff filenames of the assets that shouldn't be there
111
143
  * @param {function(string): boolean} isKept check if the entry is ignored
112
- * @param {function(Error=): void} callback callback
144
+ * @param {function(Error=, Assets=): void} callback callback
113
145
  * @returns {void}
114
146
  */
115
147
  const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
@@ -122,11 +154,13 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
122
154
  };
123
155
  /** @typedef {{ type: "check" | "unlink" | "rmdir", filename: string, parent: { remaining: number, job: Job } | undefined }} Job */
124
156
  /** @type {Job[]} */
125
- const jobs = Array.from(diff, filename => ({
157
+ const jobs = Array.from(diff.keys(), filename => ({
126
158
  type: "check",
127
159
  filename,
128
160
  parent: undefined
129
161
  }));
162
+ /** @type {Assets} */
163
+ const keptAssets = new Map();
130
164
  processAsyncTree(
131
165
  jobs,
132
166
  10,
@@ -146,11 +180,12 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
146
180
  switch (type) {
147
181
  case "check":
148
182
  if (isKept(filename)) {
183
+ keptAssets.set(filename, 0);
149
184
  // do not decrement parent entry as we don't want to delete the parent
150
185
  log(`${filename} will be kept`);
151
186
  return process.nextTick(callback);
152
187
  }
153
- fs.stat(path, (err, stats) => {
188
+ doStat(fs, path, (err, stats) => {
154
189
  if (err) return handleError(err);
155
190
  if (!stats.isDirectory()) {
156
191
  push({
@@ -232,7 +267,10 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
232
267
  break;
233
268
  }
234
269
  },
235
- callback
270
+ err => {
271
+ if (err) return callback(err);
272
+ callback(undefined, keptAssets);
273
+ }
236
274
  );
237
275
  };
238
276
 
@@ -287,6 +325,7 @@ class CleanPlugin {
287
325
  // We assume that no external modification happens while the compiler is active
288
326
  // So we can store the old assets and only diff to them to avoid fs access on
289
327
  // incremental builds
328
+ /** @type {undefined|Assets} */
290
329
  let oldAssets;
291
330
 
292
331
  compiler.hooks.emit.tapAsync(
@@ -307,7 +346,9 @@ class CleanPlugin {
307
346
  );
308
347
  }
309
348
 
310
- const currentAssets = new Set();
349
+ /** @type {Assets} */
350
+ const currentAssets = new Map();
351
+ const now = Date.now();
311
352
  for (const asset of Object.keys(compilation.assets)) {
312
353
  if (/^[A-Za-z]:\\|^\/|^\\\\/.test(asset)) continue;
313
354
  let normalizedAsset;
@@ -320,7 +361,12 @@ class CleanPlugin {
320
361
  );
321
362
  } while (newNormalizedAsset !== normalizedAsset);
322
363
  if (normalizedAsset.startsWith("../")) continue;
323
- currentAssets.add(normalizedAsset);
364
+ const assetInfo = compilation.assetsInfo.get(asset);
365
+ if (assetInfo && assetInfo.hotModuleReplacement) {
366
+ currentAssets.set(normalizedAsset, now + _10sec);
367
+ } else {
368
+ currentAssets.set(normalizedAsset, 0);
369
+ }
324
370
  }
325
371
 
326
372
  const outputPath = compilation.getPath(compiler.outputPath, {});
@@ -331,19 +377,34 @@ class CleanPlugin {
331
377
  return keepFn(path);
332
378
  };
333
379
 
380
+ /**
381
+ * @param {Error=} err err
382
+ * @param {Set<string>=} diff diff
383
+ */
334
384
  const diffCallback = (err, diff) => {
335
385
  if (err) {
336
386
  oldAssets = undefined;
337
- return callback(err);
387
+ callback(err);
388
+ return;
338
389
  }
339
- applyDiff(fs, outputPath, dry, logger, diff, isKept, err => {
340
- if (err) {
341
- oldAssets = undefined;
342
- } else {
343
- oldAssets = currentAssets;
390
+ applyDiff(
391
+ fs,
392
+ outputPath,
393
+ dry,
394
+ logger,
395
+ diff,
396
+ isKept,
397
+ (err, keptAssets) => {
398
+ if (err) {
399
+ oldAssets = undefined;
400
+ } else {
401
+ if (oldAssets) mergeAssets(currentAssets, oldAssets);
402
+ oldAssets = currentAssets;
403
+ if (keptAssets) mergeAssets(oldAssets, keptAssets);
404
+ }
405
+ callback(err);
344
406
  }
345
- callback(err);
346
- });
407
+ );
347
408
  };
348
409
 
349
410
  if (oldAssets) {