webpack 5.14.0 → 5.18.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 (71) hide show
  1. package/bin/webpack.js +0 -0
  2. package/hot/lazy-compilation-node.js +38 -0
  3. package/hot/lazy-compilation-web.js +74 -0
  4. package/lib/AutomaticPrefetchPlugin.js +14 -7
  5. package/lib/CacheFacade.js +1 -0
  6. package/lib/ChunkGraph.js +132 -19
  7. package/lib/CodeGenerationResults.js +43 -8
  8. package/lib/Compilation.js +253 -149
  9. package/lib/Compiler.js +7 -2
  10. package/lib/ContextModule.js +2 -2
  11. package/lib/Dependency.js +1 -7
  12. package/lib/ExportsInfo.js +23 -5
  13. package/lib/ExternalModuleFactoryPlugin.js +46 -3
  14. package/lib/FileSystemInfo.js +192 -137
  15. package/lib/HotModuleReplacementPlugin.js +76 -29
  16. package/lib/IgnoreErrorModuleFactory.js +39 -0
  17. package/lib/Module.js +2 -3
  18. package/lib/NormalModuleFactory.js +27 -8
  19. package/lib/Template.js +32 -23
  20. package/lib/WebpackIsIncludedPlugin.js +85 -0
  21. package/lib/WebpackOptionsApply.js +27 -5
  22. package/lib/cache/PackFileCacheStrategy.js +5 -1
  23. package/lib/config/defaults.js +18 -18
  24. package/lib/config/normalization.js +44 -9
  25. package/lib/debug/ProfilingPlugin.js +20 -1
  26. package/lib/dependencies/AMDDefineDependency.js +1 -1
  27. package/lib/dependencies/AMDPlugin.js +6 -7
  28. package/lib/dependencies/CommonJsImportsParserPlugin.js +43 -1
  29. package/lib/dependencies/CommonJsPlugin.js +1 -6
  30. package/lib/dependencies/ContextDependencyHelpers.js +3 -2
  31. package/lib/dependencies/ExportsInfoDependency.js +0 -20
  32. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +1 -2
  33. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +0 -29
  34. package/lib/dependencies/HarmonyImportDependency.js +0 -41
  35. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +2 -3
  36. package/lib/dependencies/HarmonyImportSpecifierDependency.js +2 -36
  37. package/lib/dependencies/HarmonyModulesPlugin.js +2 -2
  38. package/lib/dependencies/ImportPlugin.js +1 -6
  39. package/lib/dependencies/JsonExportsDependency.js +0 -1
  40. package/lib/dependencies/ModuleDecoratorDependency.js +0 -1
  41. package/lib/dependencies/NullDependency.js +0 -8
  42. package/lib/dependencies/ProvidedDependency.js +0 -1
  43. package/lib/dependencies/StaticExportsDependency.js +0 -12
  44. package/lib/dependencies/SystemPlugin.js +0 -4
  45. package/lib/dependencies/URLDependency.js +45 -3
  46. package/lib/dependencies/URLPlugin.js +33 -7
  47. package/lib/dependencies/WebpackIsIncludedDependency.js +80 -0
  48. package/lib/hmr/LazyCompilationPlugin.js +348 -0
  49. package/lib/hmr/lazyCompilationBackend.js +86 -0
  50. package/lib/javascript/JavascriptModulesPlugin.js +4 -3
  51. package/lib/javascript/JavascriptParser.js +20 -5
  52. package/lib/library/AssignLibraryPlugin.js +13 -4
  53. package/lib/library/EnableLibraryPlugin.js +12 -0
  54. package/lib/optimize/ConcatenatedModule.js +0 -12
  55. package/lib/optimize/InnerGraph.js +32 -0
  56. package/lib/optimize/SplitChunksPlugin.js +4 -1
  57. package/lib/serialization/ObjectMiddleware.js +7 -5
  58. package/lib/sharing/ProvideSharedModule.js +1 -1
  59. package/lib/sharing/ShareRuntimeModule.js +2 -2
  60. package/lib/stats/DefaultStatsPresetPlugin.js +1 -0
  61. package/lib/util/MapHelpers.js +22 -0
  62. package/lib/util/binarySearchBounds.js +86 -0
  63. package/lib/util/createHash.js +13 -7
  64. package/lib/util/internalSerializables.js +2 -0
  65. package/lib/util/processAsyncTree.js +61 -0
  66. package/lib/util/runtime.js +12 -1
  67. package/package.json +3 -3
  68. package/schemas/WebpackOptions.json +330 -140
  69. package/schemas/plugins/container/ContainerPlugin.json +2 -1
  70. package/schemas/plugins/container/ModuleFederationPlugin.json +2 -1
  71. package/types.d.ts +320 -121
@@ -39,6 +39,7 @@ const {
39
39
  /** @typedef {import("./Compiler")} Compiler */
40
40
  /** @typedef {import("./Module")} Module */
41
41
  /** @typedef {import("./RuntimeModule")} RuntimeModule */
42
+ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
42
43
 
43
44
  /**
44
45
  * @typedef {Object} HMRJavascriptParserHooks
@@ -316,37 +317,61 @@ class HotModuleReplacementPlugin {
316
317
  /** @type {TupleSet<[Module, Chunk]>} */
317
318
  const updatedModules = new TupleSet();
318
319
  /** @type {TupleSet<[Module, Chunk]>} */
319
- const lazyHashedModules = new TupleSet();
320
+ const fullHashModules = new TupleSet();
321
+ /** @type {TupleSet<[Module, RuntimeSpec]>} */
322
+ const nonCodeGeneratedModules = new TupleSet();
320
323
  compilation.hooks.fullHash.tap("HotModuleReplacementPlugin", hash => {
321
324
  const chunkGraph = compilation.chunkGraph;
322
325
  const records = compilation.records;
323
326
  for (const chunk of compilation.chunks) {
324
- /** @type {Set<Module>} */
325
- const lazyHashedModulesInThisChunk = new Set();
326
- const fullHashModules = chunkGraph.getChunkFullHashModulesIterable(
327
+ const getModuleHash = module => {
328
+ if (
329
+ compilation.codeGenerationResults.has(module, chunk.runtime)
330
+ ) {
331
+ return compilation.codeGenerationResults.getHash(
332
+ module,
333
+ chunk.runtime
334
+ );
335
+ } else {
336
+ nonCodeGeneratedModules.add(module, chunk.runtime);
337
+ return chunkGraph.getModuleHash(module, chunk.runtime);
338
+ }
339
+ };
340
+ const fullHashModulesInThisChunk = chunkGraph.getChunkFullHashModulesSet(
327
341
  chunk
328
342
  );
329
- if (fullHashModules !== undefined) {
330
- for (const module of fullHashModules) {
331
- lazyHashedModules.add(module, chunk);
332
- lazyHashedModulesInThisChunk.add(module);
343
+ if (fullHashModulesInThisChunk !== undefined) {
344
+ for (const module of fullHashModulesInThisChunk) {
345
+ fullHashModules.add(module, chunk);
333
346
  }
334
347
  }
335
348
  const modules = chunkGraph.getChunkModulesIterable(chunk);
336
349
  if (modules !== undefined) {
337
- if (
338
- records.chunkModuleHashes &&
339
- records.fullHashChunkModuleHashes
340
- ) {
341
- for (const module of modules) {
342
- const key = `${chunk.id}|${module.identifier()}`;
343
- const hash = chunkGraph.getModuleHash(module, chunk.runtime);
344
- if (lazyHashedModulesInThisChunk.has(module)) {
345
- if (records.fullHashChunkModuleHashes[key] !== hash) {
346
- updatedModules.add(module, chunk);
350
+ if (records.chunkModuleHashes) {
351
+ if (fullHashModulesInThisChunk !== undefined) {
352
+ for (const module of modules) {
353
+ const key = `${chunk.id}|${module.identifier()}`;
354
+ const hash = getModuleHash(module);
355
+ if (
356
+ fullHashModulesInThisChunk.has(
357
+ /** @type {RuntimeModule} */ (module)
358
+ )
359
+ ) {
360
+ if (records.fullHashChunkModuleHashes[key] !== hash) {
361
+ updatedModules.add(module, chunk);
362
+ }
363
+ fullHashChunkModuleHashes[key] = hash;
364
+ } else {
365
+ if (records.chunkModuleHashes[key] !== hash) {
366
+ updatedModules.add(module, chunk);
367
+ }
368
+ chunkModuleHashes[key] = hash;
347
369
  }
348
- fullHashChunkModuleHashes[key] = hash;
349
- } else {
370
+ }
371
+ } else {
372
+ for (const module of modules) {
373
+ const key = `${chunk.id}|${module.identifier()}`;
374
+ const hash = getModuleHash(module);
350
375
  if (records.chunkModuleHashes[key] !== hash) {
351
376
  updatedModules.add(module, chunk);
352
377
  }
@@ -354,12 +379,24 @@ class HotModuleReplacementPlugin {
354
379
  }
355
380
  }
356
381
  } else {
357
- for (const module of modules) {
358
- const key = `${chunk.id}|${module.identifier()}`;
359
- const hash = chunkGraph.getModuleHash(module, chunk.runtime);
360
- if (lazyHashedModulesInThisChunk.has(module)) {
361
- fullHashChunkModuleHashes[key] = hash;
362
- } else {
382
+ if (fullHashModulesInThisChunk !== undefined) {
383
+ for (const module of modules) {
384
+ const key = `${chunk.id}|${module.identifier()}`;
385
+ const hash = getModuleHash(module);
386
+ if (
387
+ fullHashModulesInThisChunk.has(
388
+ /** @type {RuntimeModule} */ (module)
389
+ )
390
+ ) {
391
+ fullHashChunkModuleHashes[key] = hash;
392
+ } else {
393
+ chunkModuleHashes[key] = hash;
394
+ }
395
+ }
396
+ } else {
397
+ for (const module of modules) {
398
+ const key = `${chunk.id}|${module.identifier()}`;
399
+ const hash = getModuleHash(module);
363
400
  chunkModuleHashes[key] = hash;
364
401
  }
365
402
  }
@@ -388,9 +425,14 @@ class HotModuleReplacementPlugin {
388
425
  ) {
389
426
  return;
390
427
  }
391
- for (const [module, chunk] of lazyHashedModules) {
428
+ for (const [module, chunk] of fullHashModules) {
392
429
  const key = `${chunk.id}|${module.identifier()}`;
393
- const hash = chunkGraph.getModuleHash(module, chunk.runtime);
430
+ const hash = nonCodeGeneratedModules.has(module, chunk.runtime)
431
+ ? chunkGraph.getModuleHash(module, chunk.runtime)
432
+ : compilation.codeGenerationResults.getHash(
433
+ module,
434
+ chunk.runtime
435
+ );
394
436
  if (records.chunkModuleHashes[key] !== hash) {
395
437
  updatedModules.add(module, chunk);
396
438
  }
@@ -500,7 +542,12 @@ class HotModuleReplacementPlugin {
500
542
  const runtimes = chunkGraph.getModuleRuntimes(module);
501
543
  if (oldRuntime === newRuntime && runtimes.has(newRuntime)) {
502
544
  // Module is still in the same runtime combination
503
- const hash = chunkGraph.getModuleHash(module, newRuntime);
545
+ const hash = nonCodeGeneratedModules.has(module, newRuntime)
546
+ ? chunkGraph.getModuleHash(module, newRuntime)
547
+ : compilation.codeGenerationResults.getHash(
548
+ module,
549
+ newRuntime
550
+ );
504
551
  if (hash !== oldHash) {
505
552
  if (module.type === "runtime") {
506
553
  newRuntimeModules = newRuntimeModules || [];
@@ -0,0 +1,39 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Ivan Kopeykin @vankop
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const ModuleFactory = require("./ModuleFactory");
9
+
10
+ /** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
11
+ /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
12
+ /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
13
+
14
+ /**
15
+ * Ignores error when module is unresolved
16
+ */
17
+ class IgnoreErrorModuleFactory extends ModuleFactory {
18
+ /**
19
+ * @param {NormalModuleFactory} normalModuleFactory normalModuleFactory instance
20
+ */
21
+ constructor(normalModuleFactory) {
22
+ super();
23
+
24
+ this.normalModuleFactory = normalModuleFactory;
25
+ }
26
+
27
+ /**
28
+ * @param {ModuleFactoryCreateData} data data object
29
+ * @param {function(Error=, ModuleFactoryResult=): void} callback callback
30
+ * @returns {void}
31
+ */
32
+ create(data, callback) {
33
+ this.normalModuleFactory.create(data, (err, result) => {
34
+ return callback(null, result);
35
+ });
36
+ }
37
+ }
38
+
39
+ module.exports = IgnoreErrorModuleFactory;
package/lib/Module.js CHANGED
@@ -67,6 +67,7 @@ const makeSerializable = require("./util/makeSerializable");
67
67
  * @property {Map<string, Source>} sources the resulting sources for all source types
68
68
  * @property {Map<string, any>=} data the resulting data for all source types
69
69
  * @property {ReadonlySet<string>} runtimeRequirements the runtime requirements
70
+ * @property {string=} hash a hash of the code generation result (will be automatically calculated from sources and runtimeRequirements if not provided)
70
71
  */
71
72
 
72
73
  /**
@@ -703,9 +704,7 @@ class Module extends DependenciesBlock {
703
704
  }
704
705
  ) {
705
706
  const { chunkGraph, runtime } = context;
706
- hash.update(`${chunkGraph.getModuleId(this)}`);
707
- const exportsInfo = chunkGraph.moduleGraph.getExportsInfo(this);
708
- exportsInfo.updateHash(hash, runtime);
707
+ hash.update(chunkGraph.getModuleGraphHash(this, runtime));
709
708
  if (this.presentationalDependencies !== undefined) {
710
709
  for (const dep of this.presentationalDependencies) {
711
710
  dep.updateHash(hash, context);
@@ -28,7 +28,7 @@ const { cachedCleverMerge, cachedSetProperty } = require("./util/cleverMerge");
28
28
  const { join } = require("./util/fs");
29
29
  const { parseResource } = require("./util/identifier");
30
30
 
31
- /** @typedef {import("../declarations/WebpackOptions").ModuleOptions} ModuleOptions */
31
+ /** @typedef {import("../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
32
32
  /** @typedef {import("./Generator")} Generator */
33
33
  /** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
34
34
  /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
@@ -147,10 +147,19 @@ const mergeGlobalOptions = (globalOptions, type, localOptions) => {
147
147
  };
148
148
 
149
149
  // TODO webpack 6 remove
150
- const deprecationChangedHookMessage = name =>
151
- `NormalModuleFactory.${name} is no longer a waterfall hook, but a bailing hook instead. ` +
152
- "Do not return the passed object, but modify it instead. " +
153
- "Returning false will ignore the request and results in no module created.";
150
+ const deprecationChangedHookMessage = (name, hook) => {
151
+ const names = hook.taps
152
+ .map(tapped => {
153
+ return tapped.name;
154
+ })
155
+ .join(", ");
156
+
157
+ return (
158
+ `NormalModuleFactory.${name} (${names}) is no longer a waterfall hook, but a bailing hook instead. ` +
159
+ "Do not return the passed object, but modify it instead. " +
160
+ "Returning false will ignore the request and results in no module created."
161
+ );
162
+ };
154
163
 
155
164
  const dependencyCache = new WeakMap();
156
165
 
@@ -270,7 +279,7 @@ class NormalModuleFactory extends ModuleFactory {
270
279
 
271
280
  if (typeof result === "object")
272
281
  throw new Error(
273
- deprecationChangedHookMessage("resolve") +
282
+ deprecationChangedHookMessage("resolve", this.hooks.resolve) +
274
283
  " Returning a Module object will result in this module used as result."
275
284
  );
276
285
 
@@ -278,7 +287,12 @@ class NormalModuleFactory extends ModuleFactory {
278
287
  if (err) return callback(err);
279
288
 
280
289
  if (typeof result === "object")
281
- throw new Error(deprecationChangedHookMessage("afterResolve"));
290
+ throw new Error(
291
+ deprecationChangedHookMessage(
292
+ "afterResolve",
293
+ this.hooks.afterResolve
294
+ )
295
+ );
282
296
 
283
297
  // Ignored
284
298
  if (result === false) return callback();
@@ -682,7 +696,12 @@ class NormalModuleFactory extends ModuleFactory {
682
696
  }
683
697
 
684
698
  if (typeof result === "object")
685
- throw new Error(deprecationChangedHookMessage("beforeResolve"));
699
+ throw new Error(
700
+ deprecationChangedHookMessage(
701
+ "beforeResolve",
702
+ this.hooks.beforeResolve
703
+ )
704
+ );
686
705
 
687
706
  this.hooks.factorize.callAsync(resolveData, (err, module) => {
688
707
  if (err) {
package/lib/Template.js CHANGED
@@ -349,34 +349,43 @@ class Template {
349
349
 
350
350
  /**
351
351
  * @param {RuntimeModule[]} runtimeModules array of runtime modules in order
352
- * @param {RenderContext} renderContext render context
352
+ * @param {RenderContext & { codeGenerationResults?: CodeGenerationResults }} renderContext render context
353
353
  * @returns {Source} rendered runtime modules in a Source object
354
354
  */
355
355
  static renderRuntimeModules(runtimeModules, renderContext) {
356
356
  const source = new ConcatSource();
357
357
  for (const module of runtimeModules) {
358
- const codeGenResult = module.codeGeneration({
359
- chunkGraph: renderContext.chunkGraph,
360
- dependencyTemplates: renderContext.dependencyTemplates,
361
- moduleGraph: renderContext.moduleGraph,
362
- runtimeTemplate: renderContext.runtimeTemplate,
363
- runtime: renderContext.chunk.runtime
364
- });
365
- if (codeGenResult) {
366
- const moduleSource = codeGenResult.sources.get("runtime");
367
- if (moduleSource) {
368
- source.add(Template.toNormalComment(module.identifier()) + "\n");
369
- if (!module.shouldIsolate()) {
370
- source.add(moduleSource);
371
- } else if (renderContext.runtimeTemplate.supportsArrowFunction()) {
372
- source.add("(() => {\n");
373
- source.add(new PrefixSource("\t", moduleSource));
374
- source.add("\n})();\n\n");
375
- } else {
376
- source.add("!function() {\n");
377
- source.add(new PrefixSource("\t", moduleSource));
378
- source.add("\n}();\n\n");
379
- }
358
+ const codeGenerationResults = renderContext.codeGenerationResults;
359
+ let runtimeSource;
360
+ if (codeGenerationResults) {
361
+ runtimeSource = codeGenerationResults.getSource(
362
+ module,
363
+ renderContext.chunk.runtime,
364
+ "runtime"
365
+ );
366
+ } else {
367
+ const codeGenResult = module.codeGeneration({
368
+ chunkGraph: renderContext.chunkGraph,
369
+ dependencyTemplates: renderContext.dependencyTemplates,
370
+ moduleGraph: renderContext.moduleGraph,
371
+ runtimeTemplate: renderContext.runtimeTemplate,
372
+ runtime: renderContext.chunk.runtime
373
+ });
374
+ if (!codeGenResult) continue;
375
+ runtimeSource = codeGenResult.sources.get("runtime");
376
+ }
377
+ if (runtimeSource) {
378
+ source.add(Template.toNormalComment(module.identifier()) + "\n");
379
+ if (!module.shouldIsolate()) {
380
+ source.add(runtimeSource);
381
+ } else if (renderContext.runtimeTemplate.supportsArrowFunction()) {
382
+ source.add("(() => {\n");
383
+ source.add(new PrefixSource("\t", runtimeSource));
384
+ source.add("\n})();\n\n");
385
+ } else {
386
+ source.add("!function() {\n");
387
+ source.add(new PrefixSource("\t", runtimeSource));
388
+ source.add("\n}();\n\n");
380
389
  }
381
390
  }
382
391
  }
@@ -0,0 +1,85 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Ivan Kopeykin @vankop
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const IgnoreErrorModuleFactory = require("./IgnoreErrorModuleFactory");
9
+ const WebpackIsIncludedDependency = require("./dependencies/WebpackIsIncludedDependency");
10
+ const {
11
+ toConstantDependency
12
+ } = require("./javascript/JavascriptParserHelpers");
13
+
14
+ /** @typedef {import("enhanced-resolve/lib/Resolver")} Resolver */
15
+ /** @typedef {import("./Compiler")} Compiler */
16
+ /** @typedef {import("./Module")} Module */
17
+ /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
18
+
19
+ class WebpackIsIncludedPlugin {
20
+ /**
21
+ * @param {Compiler} compiler the compiler instance
22
+ * @returns {void}
23
+ */
24
+ apply(compiler) {
25
+ compiler.hooks.compilation.tap(
26
+ "WebpackIsIncludedPlugin",
27
+ (compilation, { normalModuleFactory }) => {
28
+ compilation.dependencyFactories.set(
29
+ WebpackIsIncludedDependency,
30
+ new IgnoreErrorModuleFactory(normalModuleFactory)
31
+ );
32
+ compilation.dependencyTemplates.set(
33
+ WebpackIsIncludedDependency,
34
+ new WebpackIsIncludedDependency.Template()
35
+ );
36
+
37
+ /**
38
+ * @param {JavascriptParser} parser the parser
39
+ * @returns {void}
40
+ */
41
+ const handler = parser => {
42
+ parser.hooks.call
43
+ .for("__webpack_is_included__")
44
+ .tap("WebpackIsIncludedPlugin", expr => {
45
+ if (
46
+ expr.type !== "CallExpression" ||
47
+ expr.arguments.length !== 1 ||
48
+ expr.arguments[0].type === "SpreadElement"
49
+ )
50
+ return;
51
+
52
+ const request = parser.evaluateExpression(expr.arguments[0]);
53
+
54
+ if (!request.isString()) return;
55
+
56
+ const dep = new WebpackIsIncludedDependency(
57
+ request.string,
58
+ expr.range
59
+ );
60
+ dep.loc = expr.loc;
61
+ parser.state.module.addDependency(dep);
62
+ return true;
63
+ });
64
+ parser.hooks.typeof
65
+ .for("__webpack_is_included__")
66
+ .tap(
67
+ "WebpackIsIncludedPlugin",
68
+ toConstantDependency(parser, JSON.stringify("function"))
69
+ );
70
+ };
71
+ normalModuleFactory.hooks.parser
72
+ .for("javascript/auto")
73
+ .tap("WebpackIsIncludedPlugin", handler);
74
+ normalModuleFactory.hooks.parser
75
+ .for("javascript/dynamic")
76
+ .tap("WebpackIsIncludedPlugin", handler);
77
+ normalModuleFactory.hooks.parser
78
+ .for("javascript/esm")
79
+ .tap("WebpackIsIncludedPlugin", handler);
80
+ }
81
+ );
82
+ }
83
+ }
84
+
85
+ module.exports = WebpackIsIncludedPlugin;
@@ -22,6 +22,7 @@ const APIPlugin = require("./APIPlugin");
22
22
  const CompatibilityPlugin = require("./CompatibilityPlugin");
23
23
  const ConstPlugin = require("./ConstPlugin");
24
24
  const ExportsInfoApiPlugin = require("./ExportsInfoApiPlugin");
25
+ const WebpackIsIncludedPlugin = require("./WebpackIsIncludedPlugin");
25
26
 
26
27
  const TemplatedPathPlugin = require("./TemplatedPathPlugin");
27
28
  const UseStrictPlugin = require("./UseStrictPlugin");
@@ -243,6 +244,27 @@ class WebpackOptionsApply extends OptionsApply {
243
244
  }).apply(compiler);
244
245
  }
245
246
 
247
+ if (options.experiments.lazyCompilation) {
248
+ const LazyCompilationPlugin = require("./hmr/LazyCompilationPlugin");
249
+ new LazyCompilationPlugin({
250
+ backend:
251
+ (typeof options.experiments.lazyCompilation === "object" &&
252
+ options.experiments.lazyCompilation.backend) ||
253
+ require("./hmr/lazyCompilationBackend"),
254
+ client:
255
+ (typeof options.experiments.lazyCompilation === "object" &&
256
+ options.experiments.lazyCompilation.client) ||
257
+ require.resolve(
258
+ `../hot/lazy-compilation-${
259
+ options.externalsPresets.node ? "node" : "web"
260
+ }.js`
261
+ ),
262
+ entries:
263
+ typeof options.experiments.lazyCompilation !== "object" ||
264
+ options.experiments.lazyCompilation.entries !== false
265
+ }).apply(compiler);
266
+ }
267
+
246
268
  new EntryOptionPlugin().apply(compiler);
247
269
  compiler.hooks.entryOption.call(options.context, options.entry);
248
270
 
@@ -255,16 +277,15 @@ class WebpackOptionsApply extends OptionsApply {
255
277
 
256
278
  new CompatibilityPlugin().apply(compiler);
257
279
  new HarmonyModulesPlugin({
258
- module: options.module,
259
280
  topLevelAwait: options.experiments.topLevelAwait
260
281
  }).apply(compiler);
261
282
  if (options.amd !== false) {
262
283
  const AMDPlugin = require("./dependencies/AMDPlugin");
263
284
  const RequireJsStuffPlugin = require("./RequireJsStuffPlugin");
264
- new AMDPlugin(options.module, options.amd || {}).apply(compiler);
285
+ new AMDPlugin(options.amd || {}).apply(compiler);
265
286
  new RequireJsStuffPlugin().apply(compiler);
266
287
  }
267
- new CommonJsPlugin(options.module).apply(compiler);
288
+ new CommonJsPlugin().apply(compiler);
268
289
  new LoaderPlugin().apply(compiler);
269
290
  if (options.node !== false) {
270
291
  const NodeStuffPlugin = require("./NodeStuffPlugin");
@@ -272,13 +293,14 @@ class WebpackOptionsApply extends OptionsApply {
272
293
  }
273
294
  new APIPlugin().apply(compiler);
274
295
  new ExportsInfoApiPlugin().apply(compiler);
296
+ new WebpackIsIncludedPlugin().apply(compiler);
275
297
  new ConstPlugin().apply(compiler);
276
298
  new UseStrictPlugin().apply(compiler);
277
299
  new RequireIncludePlugin().apply(compiler);
278
300
  new RequireEnsurePlugin().apply(compiler);
279
301
  new RequireContextPlugin().apply(compiler);
280
- new ImportPlugin(options.module).apply(compiler);
281
- new SystemPlugin(options.module).apply(compiler);
302
+ new ImportPlugin().apply(compiler);
303
+ new SystemPlugin().apply(compiler);
282
304
  new ImportMetaPlugin().apply(compiler);
283
305
  new URLPlugin().apply(compiler);
284
306
 
@@ -11,7 +11,10 @@ const { formatSize } = require("../SizeFormatHelpers");
11
11
  const LazySet = require("../util/LazySet");
12
12
  const makeSerializable = require("../util/makeSerializable");
13
13
  const memoize = require("../util/memoize");
14
- const { createFileSerializer } = require("../util/serialization");
14
+ const {
15
+ createFileSerializer,
16
+ NOT_SERIALIZABLE
17
+ } = require("../util/serialization");
15
18
 
16
19
  /** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
17
20
  /** @typedef {import("../Cache").Etag} Etag */
@@ -525,6 +528,7 @@ class PackContentItems {
525
528
  write(value);
526
529
  } catch (e) {
527
530
  rollback(s);
531
+ if (e === NOT_SERIALIZABLE) continue;
528
532
  logger.warn(
529
533
  `Skipped not serializable cache item '${key}': ${e.message}`
530
534
  );
@@ -27,7 +27,7 @@ const {
27
27
  /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
28
28
  /** @typedef {import("../../declarations/WebpackOptions").Loader} Loader */
29
29
  /** @typedef {import("../../declarations/WebpackOptions").Mode} Mode */
30
- /** @typedef {import("../../declarations/WebpackOptions").ModuleOptions} ModuleOptions */
30
+ /** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
31
31
  /** @typedef {import("../../declarations/WebpackOptions").Node} WebpackNode */
32
32
  /** @typedef {import("../../declarations/WebpackOptions").Optimization} Optimization */
33
33
  /** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */
@@ -347,10 +347,25 @@ const applySnapshotDefaults = (snapshot, { production }) => {
347
347
  };
348
348
 
349
349
  /**
350
- * @param {JavascriptParserOptions} options options
350
+ * @param {JavascriptParserOptions} parserOptions parser options
351
351
  * @returns {void}
352
352
  */
353
- const applyJavascriptParserOptionsDefaults = options => {};
353
+ const applyJavascriptParserOptionsDefaults = parserOptions => {
354
+ D(parserOptions, "unknownContextRequest", ".");
355
+ D(parserOptions, "unknownContextRegExp", false);
356
+ D(parserOptions, "unknownContextRecursive", true);
357
+ D(parserOptions, "unknownContextCritical", true);
358
+ D(parserOptions, "exprContextRequest", ".");
359
+ D(parserOptions, "exprContextRegExp", false);
360
+ D(parserOptions, "exprContextRecursive", true);
361
+ D(parserOptions, "exprContextCritical", true);
362
+ D(parserOptions, "wrappedContextRegExp", /.*/);
363
+ D(parserOptions, "wrappedContextRecursive", true);
364
+ D(parserOptions, "wrappedContextCritical", false);
365
+
366
+ D(parserOptions, "strictExportPresence", false);
367
+ D(parserOptions, "strictThisContextOnImports", false);
368
+ };
354
369
 
355
370
  /**
356
371
  * @param {ModuleOptions} module options
@@ -364,21 +379,6 @@ const applyModuleDefaults = (
364
379
  module,
365
380
  { cache, syncWebAssembly, asyncWebAssembly }
366
381
  ) => {
367
- D(module, "unknownContextRequest", ".");
368
- D(module, "unknownContextRegExp", false);
369
- D(module, "unknownContextRecursive", true);
370
- D(module, "unknownContextCritical", true);
371
- D(module, "exprContextRequest", ".");
372
- D(module, "exprContextRegExp", false);
373
- D(module, "exprContextRecursive", true);
374
- D(module, "exprContextCritical", true);
375
- D(module, "wrappedContextRegExp", /.*/);
376
- D(module, "wrappedContextRecursive", true);
377
- D(module, "wrappedContextCritical", false);
378
-
379
- D(module, "strictExportPresence", false);
380
- D(module, "strictThisContextOnImports", false);
381
-
382
382
  if (cache) {
383
383
  D(module, "unsafeCache", module => {
384
384
  const name = module.nameForCondition();
@@ -83,15 +83,31 @@ const optionalNestedArray = (value, fn) =>
83
83
  * @template R
84
84
  * @param {Record<string, T>|undefined} value value or not
85
85
  * @param {function(T): R} fn nested handler
86
+ * @param {Record<string, function(T): R>=} customKeys custom nested handler for some keys
86
87
  * @returns {Record<string, R>} result value
87
88
  */
88
- const keyedNestedConfig = (value, fn) =>
89
- value === undefined
90
- ? {}
91
- : Object.keys(value).reduce(
92
- (obj, key) => ((obj[key] = fn(value[key])), obj),
93
- /** @type {Record<string, R>} */ ({})
94
- );
89
+ const keyedNestedConfig = (value, fn, customKeys) => {
90
+ const result =
91
+ value === undefined
92
+ ? {}
93
+ : Object.keys(value).reduce(
94
+ (obj, key) => (
95
+ (obj[key] = (customKeys && key in customKeys
96
+ ? customKeys[key]
97
+ : fn)(value[key])),
98
+ obj
99
+ ),
100
+ /** @type {Record<string, R>} */ ({})
101
+ );
102
+ if (customKeys) {
103
+ for (const key of Object.keys(customKeys)) {
104
+ if (!(key in result)) {
105
+ result[key] = customKeys[key](/** @type {T} */ ({}));
106
+ }
107
+ }
108
+ }
109
+ return result;
110
+ };
95
111
 
96
112
  /**
97
113
  * @param {WebpackOptions} config input config
@@ -180,9 +196,28 @@ const getNormalizedWebpackOptions = config => {
180
196
  loader: cloneObject(config.loader),
181
197
  mode: config.mode,
182
198
  module: nestedConfig(config.module, module => ({
183
- ...module,
184
- parser: cloneObject(module.parser),
199
+ noParse: module.noParse,
200
+ unsafeCache: module.unsafeCache,
201
+ parser: keyedNestedConfig(module.parser, cloneObject, {
202
+ javascript: parserOptions => ({
203
+ unknownContextRequest: module.unknownContextRequest,
204
+ unknownContextRegExp: module.unknownContextRegExp,
205
+ unknownContextRecursive: module.unknownContextRecursive,
206
+ unknownContextCritical: module.unknownContextCritical,
207
+ exprContextRequest: module.exprContextRequest,
208
+ exprContextRegExp: module.exprContextRegExp,
209
+ exprContextRecursive: module.exprContextRecursive,
210
+ exprContextCritical: module.exprContextCritical,
211
+ wrappedContextRegExp: module.wrappedContextRegExp,
212
+ wrappedContextRecursive: module.wrappedContextRecursive,
213
+ wrappedContextCritical: module.wrappedContextCritical,
214
+ strictExportPresence: module.strictExportPresence,
215
+ strictThisContextOnImports: module.strictThisContextOnImports,
216
+ ...parserOptions
217
+ })
218
+ }),
185
219
  generator: cloneObject(module.generator),
220
+ defaultRules: optionalNestedArray(module.defaultRules, r => [...r]),
186
221
  rules: nestedArray(module.rules, r => [...r])
187
222
  })),
188
223
  name: config.name,