webpack 5.31.2 → 5.33.2

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 (55) hide show
  1. package/lib/CaseSensitiveModulesWarning.js +3 -3
  2. package/lib/Compilation.js +488 -48
  3. package/lib/DefinePlugin.js +21 -5
  4. package/lib/EntryOptionPlugin.js +1 -0
  5. package/lib/FlagDependencyExportsPlugin.js +22 -0
  6. package/lib/Module.js +1 -1
  7. package/lib/ModuleGraph.js +24 -0
  8. package/lib/NormalModule.js +14 -3
  9. package/lib/NormalModuleFactory.js +15 -1
  10. package/lib/RuntimeModule.js +5 -1
  11. package/lib/RuntimePlugin.js +7 -2
  12. package/lib/WarnCaseSensitiveModulesPlugin.js +15 -9
  13. package/lib/WebpackOptionsApply.js +3 -1
  14. package/lib/asset/AssetModulesPlugin.js +13 -0
  15. package/lib/config/defaults.js +1 -3
  16. package/lib/config/normalization.js +1 -0
  17. package/lib/container/RemoteRuntimeModule.js +2 -1
  18. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -3
  19. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +191 -39
  20. package/lib/dependencies/LoaderImportDependency.js +28 -0
  21. package/lib/dependencies/LoaderPlugin.js +134 -2
  22. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +2 -2
  23. package/lib/javascript/CommonJsChunkFormatPlugin.js +2 -2
  24. package/lib/javascript/JavascriptModulesPlugin.js +67 -2
  25. package/lib/library/AbstractLibraryPlugin.js +26 -8
  26. package/lib/node/CommonJsChunkLoadingPlugin.js +3 -1
  27. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +2 -2
  28. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +3 -1
  29. package/lib/node/ReadFileCompileWasmPlugin.js +3 -1
  30. package/lib/node/RequireChunkLoadingRuntimeModule.js +2 -2
  31. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -4
  32. package/lib/runtime/CompatRuntimeModule.js +1 -2
  33. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -2
  34. package/lib/runtime/PublicPathRuntimeModule.js +5 -5
  35. package/lib/runtime/RuntimeIdRuntimeModule.js +1 -2
  36. package/lib/runtime/StartupChunkDependenciesPlugin.js +5 -3
  37. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +2 -2
  38. package/lib/serialization/ObjectMiddleware.js +13 -4
  39. package/lib/sharing/ConsumeSharedRuntimeModule.js +2 -5
  40. package/lib/sharing/ShareRuntimeModule.js +2 -2
  41. package/lib/stats/DefaultStatsFactoryPlugin.js +5 -0
  42. package/lib/stats/DefaultStatsPrinterPlugin.js +2 -0
  43. package/lib/util/AsyncQueue.js +45 -10
  44. package/lib/util/WeakTupleMap.js +168 -0
  45. package/lib/util/processAsyncTree.js +3 -2
  46. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +2 -2
  47. package/lib/web/FetchCompileAsyncWasmPlugin.js +3 -1
  48. package/lib/web/FetchCompileWasmPlugin.js +3 -1
  49. package/lib/web/JsonpChunkLoadingPlugin.js +3 -1
  50. package/lib/web/JsonpChunkLoadingRuntimeModule.js +1 -2
  51. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -1
  52. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  53. package/package.json +3 -3
  54. package/schemas/WebpackOptions.json +10 -0
  55. package/types.d.ts +131 -14
@@ -12,7 +12,8 @@ const {
12
12
  SyncBailHook,
13
13
  SyncWaterfallHook,
14
14
  AsyncSeriesHook,
15
- AsyncSeriesBailHook
15
+ AsyncSeriesBailHook,
16
+ AsyncParallelHook
16
17
  } = require("tapable");
17
18
  const util = require("util");
18
19
  const { CachedSource } = require("webpack-sources");
@@ -32,7 +33,10 @@ const {
32
33
  connectChunkGroupAndChunk,
33
34
  connectChunkGroupParentAndChild
34
35
  } = require("./GraphHelpers");
35
- const { makeWebpackError } = require("./HookWebpackError");
36
+ const {
37
+ makeWebpackError,
38
+ tryRunOrWebpackError
39
+ } = require("./HookWebpackError");
36
40
  const MainTemplate = require("./MainTemplate");
37
41
  const Module = require("./Module");
38
42
  const ModuleDependencyError = require("./ModuleDependencyError");
@@ -71,6 +75,7 @@ const {
71
75
  soonFrozenObjectDeprecation,
72
76
  createFakeHook
73
77
  } = require("./util/deprecation");
78
+ const processAsyncTree = require("./util/processAsyncTree");
74
79
  const { getRuntimeKey } = require("./util/runtime");
75
80
  const { isSourceEqual } = require("./util/source");
76
81
 
@@ -119,6 +124,13 @@ const { isSourceEqual } = require("./util/source");
119
124
  * @returns {void}
120
125
  */
121
126
 
127
+ /**
128
+ * @callback ExecuteModuleCallback
129
+ * @param {WebpackError=} err
130
+ * @param {ExecuteModuleResult=} result
131
+ * @returns {void}
132
+ */
133
+
122
134
  /**
123
135
  * @callback DepBlockVarDependenciesCallback
124
136
  * @param {Dependency} dependency
@@ -158,6 +170,44 @@ const { isSourceEqual } = require("./util/source");
158
170
  * @property {ChunkGraph} chunkGraph the chunk graph
159
171
  */
160
172
 
173
+ /**
174
+ * @typedef {Object} RuntimeRequirementsContext
175
+ * @property {ChunkGraph} chunkGraph the chunk graph
176
+ * @property {CodeGenerationResults} codeGenerationResults the code generation results
177
+ */
178
+
179
+ /**
180
+ * @typedef {Object} ExecuteModuleOptions
181
+ * @property {EntryOptions=} entryOptions
182
+ */
183
+
184
+ /**
185
+ * @typedef {Object} ExecuteModuleResult
186
+ * @property {any} exports
187
+ * @property {boolean} cacheable
188
+ * @property {Map<string, { source: Source, info: AssetInfo }>} assets
189
+ * @property {LazySet<string>} fileDependencies
190
+ * @property {LazySet<string>} contextDependencies
191
+ * @property {LazySet<string>} missingDependencies
192
+ * @property {LazySet<string>} buildDependencies
193
+ */
194
+
195
+ /**
196
+ * @typedef {Object} ExecuteModuleArgument
197
+ * @property {Module} module
198
+ * @property {{ id: string, exports: any, loaded: boolean }=} moduleObject
199
+ * @property {any} preparedInfo
200
+ * @property {CodeGenerationResult} codeGenerationResult
201
+ */
202
+
203
+ /**
204
+ * @typedef {Object} ExecuteModuleContext
205
+ * @property {Map<string, { source: Source, info: AssetInfo }>} assets
206
+ * @property {Chunk} chunk
207
+ * @property {ChunkGraph} chunkGraph
208
+ * @property {function(string): any=} __webpack_require__
209
+ */
210
+
161
211
  /**
162
212
  * @typedef {Object} EntryData
163
213
  * @property {Dependency[]} dependencies dependencies of the entrypoint that should be evaluated at startup
@@ -525,6 +575,11 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
525
575
  "runtime"
526
576
  ]),
527
577
 
578
+ /** @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */
579
+ executeModule: new SyncHook(["options", "context"]),
580
+ /** @type {AsyncParallelHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */
581
+ prepareModuleExecution: new AsyncParallelHook(["options", "context"]),
582
+
528
583
  /** @type {AsyncSeriesHook<[Iterable<Module>]>} */
529
584
  finishModules: new AsyncSeriesHook(["modules"]),
530
585
  /** @type {AsyncSeriesHook<[Module]>} */
@@ -568,32 +623,35 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
568
623
  /** @type {SyncBailHook<[], boolean>} */
569
624
  shouldRecord: new SyncBailHook([]),
570
625
 
571
- /** @type {SyncHook<[Chunk, Set<string>]>} */
626
+ /** @type {SyncHook<[Chunk, Set<string>, RuntimeRequirementsContext]>} */
572
627
  additionalChunkRuntimeRequirements: new SyncHook([
573
628
  "chunk",
574
- "runtimeRequirements"
629
+ "runtimeRequirements",
630
+ "context"
575
631
  ]),
576
- /** @type {HookMap<SyncBailHook<[Chunk, Set<string>]>>} */
632
+ /** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext]>>} */
577
633
  runtimeRequirementInChunk: new HookMap(
578
- () => new SyncBailHook(["chunk", "runtimeRequirements"])
634
+ () => new SyncBailHook(["chunk", "runtimeRequirements", "context"])
579
635
  ),
580
- /** @type {SyncHook<[Module, Set<string>]>} */
636
+ /** @type {SyncHook<[Module, Set<string>, RuntimeRequirementsContext]>} */
581
637
  additionalModuleRuntimeRequirements: new SyncHook([
582
638
  "module",
583
- "runtimeRequirements"
639
+ "runtimeRequirements",
640
+ "context"
584
641
  ]),
585
- /** @type {HookMap<SyncBailHook<[Module, Set<string>]>>} */
642
+ /** @type {HookMap<SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext]>>} */
586
643
  runtimeRequirementInModule: new HookMap(
587
- () => new SyncBailHook(["module", "runtimeRequirements"])
644
+ () => new SyncBailHook(["module", "runtimeRequirements", "context"])
588
645
  ),
589
- /** @type {SyncHook<[Chunk, Set<string>]>} */
646
+ /** @type {SyncHook<[Chunk, Set<string>, RuntimeRequirementsContext]>} */
590
647
  additionalTreeRuntimeRequirements: new SyncHook([
591
648
  "chunk",
592
- "runtimeRequirements"
649
+ "runtimeRequirements",
650
+ "context"
593
651
  ]),
594
- /** @type {HookMap<SyncBailHook<[Chunk, Set<string>]>>} */
652
+ /** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext]>>} */
595
653
  runtimeRequirementInTree: new HookMap(
596
- () => new SyncBailHook(["chunk", "runtimeRequirements"])
654
+ () => new SyncBailHook(["chunk", "runtimeRequirements", "context"])
597
655
  ),
598
656
 
599
657
  /** @type {SyncHook<[RuntimeModule, Chunk]>} */
@@ -776,7 +834,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
776
834
  if (compiler.contextTimestamps) {
777
835
  this.fileSystemInfo.addContextTimestamps(compiler.contextTimestamps);
778
836
  }
779
- /** @type {Map<string, string>} */
837
+ /** @type {Map<string, string | Set<string>>} */
780
838
  this.valueCacheVersions = new Map();
781
839
  this.requestShortener = compiler.requestShortener;
782
840
  this.compilerPath = compiler.compilerPath;
@@ -824,6 +882,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
824
882
  });
825
883
 
826
884
  this.moduleGraph = new ModuleGraph();
885
+ /** @type {ChunkGraph} */
827
886
  this.chunkGraph = undefined;
828
887
  /** @type {CodeGenerationResults} */
829
888
  this.codeGenerationResults = undefined;
@@ -928,6 +987,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
928
987
  this.builtModules = new WeakSet();
929
988
  /** @type {WeakSet<Module>} */
930
989
  this.codeGeneratedModules = new WeakSet();
990
+ /** @type {WeakSet<Module>} */
991
+ this.buildTimeExecutedModules = new WeakSet();
931
992
  /** @private @type {Map<Module, Callback[]>} */
932
993
  this._rebuildingModules = new Map();
933
994
  /** @type {Set<string>} */
@@ -1435,6 +1496,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
1435
1496
  * @property {Partial<ModuleFactoryCreateDataContextInfo>=} contextInfo
1436
1497
  * @property {string=} context
1437
1498
  * @property {boolean=} recursive recurse into dependencies of the created module
1499
+ * @property {boolean=} connectOrigin connect the resolved module with the origin module
1438
1500
  */
1439
1501
 
1440
1502
  /**
@@ -1449,7 +1511,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
1449
1511
  originModule,
1450
1512
  contextInfo,
1451
1513
  context,
1452
- recursive = true
1514
+ recursive = true,
1515
+ connectOrigin = recursive
1453
1516
  },
1454
1517
  callback
1455
1518
  ) {
@@ -1497,7 +1560,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
1497
1560
  for (let i = 0; i < dependencies.length; i++) {
1498
1561
  const dependency = dependencies[i];
1499
1562
  moduleGraph.setResolvedModule(
1500
- recursive ? originModule : null,
1563
+ connectOrigin ? originModule : null,
1501
1564
  dependency,
1502
1565
  module
1503
1566
  );
@@ -1888,6 +1951,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
1888
1951
  }
1889
1952
 
1890
1953
  this.processDependenciesQueue.invalidate(module);
1954
+ this.moduleGraph.unfreeze();
1891
1955
  this.processModuleDependencies(module, err => {
1892
1956
  if (err) return callback(err);
1893
1957
  this.removeReasonsOfDependencyBlock(module, {
@@ -2094,6 +2158,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2094
2158
 
2095
2159
  // extract warnings and errors from modules
2096
2160
  this.logger.time("report dependency errors and warnings");
2161
+ this.moduleGraph.freeze();
2097
2162
  for (const module of modules) {
2098
2163
  this.reportDependencyErrorsAndWarnings(module, [module]);
2099
2164
  const errors = module.getErrors();
@@ -2115,6 +2180,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2115
2180
  }
2116
2181
  }
2117
2182
  }
2183
+ this.moduleGraph.unfreeze();
2118
2184
  this.logger.timeEnd("report dependency errors and warnings");
2119
2185
 
2120
2186
  callback();
@@ -2132,6 +2198,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2132
2198
  this.assets = {};
2133
2199
  this.assetsInfo.clear();
2134
2200
  this.moduleGraph.removeAllModuleAttributes();
2201
+ this.moduleGraph.unfreeze();
2135
2202
  }
2136
2203
 
2137
2204
  /**
@@ -2157,6 +2224,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2157
2224
 
2158
2225
  this.logger.time("create chunks");
2159
2226
  this.hooks.beforeChunks.call();
2227
+ this.moduleGraph.freeze();
2160
2228
  /** @type {Map<Entrypoint, Module[]>} */
2161
2229
  const chunkGraphInit = new Map();
2162
2230
  for (const [name, { dependencies, includeDependencies, options }] of this
@@ -2644,20 +2712,45 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2644
2712
  });
2645
2713
  }
2646
2714
 
2715
+ _getChunkGraphEntries() {
2716
+ /** @type {Set<Chunk>} */
2717
+ const treeEntries = new Set();
2718
+ for (const ep of this.entrypoints.values()) {
2719
+ const chunk = ep.getRuntimeChunk();
2720
+ if (chunk) treeEntries.add(chunk);
2721
+ }
2722
+ for (const ep of this.asyncEntrypoints) {
2723
+ const chunk = ep.getRuntimeChunk();
2724
+ if (chunk) treeEntries.add(chunk);
2725
+ }
2726
+ return treeEntries;
2727
+ }
2728
+
2647
2729
  /**
2730
+ * @param {Object} options options
2731
+ * @param {ChunkGraph=} options.chunkGraph the chunk graph
2732
+ * @param {Iterable<Module>=} options.modules modules
2733
+ * @param {Iterable<Chunk>=} options.chunks chunks
2734
+ * @param {CodeGenerationResults=} options.codeGenerationResults codeGenerationResults
2735
+ * @param {Iterable<Chunk>=} options.chunkGraphEntries chunkGraphEntries
2648
2736
  * @returns {void}
2649
2737
  */
2650
- processRuntimeRequirements() {
2651
- const { chunkGraph } = this;
2652
-
2738
+ processRuntimeRequirements({
2739
+ chunkGraph = this.chunkGraph,
2740
+ modules = this.modules,
2741
+ chunks = this.chunks,
2742
+ codeGenerationResults = this.codeGenerationResults,
2743
+ chunkGraphEntries = this._getChunkGraphEntries()
2744
+ } = {}) {
2745
+ const context = { chunkGraph, codeGenerationResults };
2653
2746
  const additionalModuleRuntimeRequirements = this.hooks
2654
2747
  .additionalModuleRuntimeRequirements;
2655
2748
  const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
2656
- for (const module of this.modules) {
2749
+ for (const module of modules) {
2657
2750
  if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
2658
2751
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
2659
2752
  let set;
2660
- const runtimeRequirements = this.codeGenerationResults.getRuntimeRequirements(
2753
+ const runtimeRequirements = codeGenerationResults.getRuntimeRequirements(
2661
2754
  module,
2662
2755
  runtime
2663
2756
  );
@@ -2668,18 +2761,18 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2668
2761
  } else {
2669
2762
  continue;
2670
2763
  }
2671
- additionalModuleRuntimeRequirements.call(module, set);
2764
+ additionalModuleRuntimeRequirements.call(module, set, context);
2672
2765
 
2673
2766
  for (const r of set) {
2674
2767
  const hook = runtimeRequirementInModule.get(r);
2675
- if (hook !== undefined) hook.call(module, set);
2768
+ if (hook !== undefined) hook.call(module, set, context);
2676
2769
  }
2677
2770
  chunkGraph.addModuleRuntimeRequirements(module, runtime, set);
2678
2771
  }
2679
2772
  }
2680
2773
  }
2681
2774
 
2682
- for (const chunk of this.chunks) {
2775
+ for (const chunk of chunks) {
2683
2776
  const set = new Set();
2684
2777
  for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
2685
2778
  const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
@@ -2688,27 +2781,16 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2688
2781
  );
2689
2782
  for (const r of runtimeRequirements) set.add(r);
2690
2783
  }
2691
- this.hooks.additionalChunkRuntimeRequirements.call(chunk, set);
2784
+ this.hooks.additionalChunkRuntimeRequirements.call(chunk, set, context);
2692
2785
 
2693
2786
  for (const r of set) {
2694
- this.hooks.runtimeRequirementInChunk.for(r).call(chunk, set);
2787
+ this.hooks.runtimeRequirementInChunk.for(r).call(chunk, set, context);
2695
2788
  }
2696
2789
 
2697
2790
  chunkGraph.addChunkRuntimeRequirements(chunk, set);
2698
2791
  }
2699
2792
 
2700
- /** @type {Set<Chunk>} */
2701
- const treeEntries = new Set();
2702
- for (const ep of this.entrypoints.values()) {
2703
- const chunk = ep.getRuntimeChunk();
2704
- if (chunk) treeEntries.add(chunk);
2705
- }
2706
- for (const ep of this.asyncEntrypoints) {
2707
- const chunk = ep.getRuntimeChunk();
2708
- if (chunk) treeEntries.add(chunk);
2709
- }
2710
-
2711
- for (const treeEntry of treeEntries) {
2793
+ for (const treeEntry of chunkGraphEntries) {
2712
2794
  const set = new Set();
2713
2795
  for (const chunk of treeEntry.getAllReferencedChunks()) {
2714
2796
  const runtimeRequirements = chunkGraph.getChunkRuntimeRequirements(
@@ -2717,22 +2799,30 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2717
2799
  for (const r of runtimeRequirements) set.add(r);
2718
2800
  }
2719
2801
 
2720
- this.hooks.additionalTreeRuntimeRequirements.call(treeEntry, set);
2802
+ this.hooks.additionalTreeRuntimeRequirements.call(
2803
+ treeEntry,
2804
+ set,
2805
+ context
2806
+ );
2721
2807
 
2722
2808
  for (const r of set) {
2723
- this.hooks.runtimeRequirementInTree.for(r).call(treeEntry, set);
2809
+ this.hooks.runtimeRequirementInTree
2810
+ .for(r)
2811
+ .call(treeEntry, set, context);
2724
2812
  }
2725
2813
 
2726
2814
  chunkGraph.addTreeRuntimeRequirements(treeEntry, set);
2727
2815
  }
2728
2816
  }
2729
2817
 
2818
+ // TODO webpack 6 make chunkGraph argument non-optional
2730
2819
  /**
2731
2820
  * @param {Chunk} chunk target chunk
2732
2821
  * @param {RuntimeModule} module runtime module
2822
+ * @param {ChunkGraph} chunkGraph the chunk graph
2733
2823
  * @returns {void}
2734
2824
  */
2735
- addRuntimeModule(chunk, module) {
2825
+ addRuntimeModule(chunk, module, chunkGraph = this.chunkGraph) {
2736
2826
  // Deprecated ModuleGraph association
2737
2827
  ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
2738
2828
 
@@ -2741,14 +2831,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2741
2831
  this._modules.set(module.identifier(), module);
2742
2832
 
2743
2833
  // connect to the chunk graph
2744
- this.chunkGraph.connectChunkAndModule(chunk, module);
2745
- this.chunkGraph.connectChunkAndRuntimeModule(chunk, module);
2834
+ chunkGraph.connectChunkAndModule(chunk, module);
2835
+ chunkGraph.connectChunkAndRuntimeModule(chunk, module);
2746
2836
  if (module.fullHash) {
2747
- this.chunkGraph.addFullHashModuleToChunk(chunk, module);
2837
+ chunkGraph.addFullHashModuleToChunk(chunk, module);
2748
2838
  }
2749
2839
 
2750
2840
  // attach runtime module
2751
- module.attach(this, chunk);
2841
+ module.attach(this, chunk, chunkGraph);
2752
2842
 
2753
2843
  // Setup internals
2754
2844
  const exportsInfo = this.moduleGraph.getExportsInfo(module);
@@ -2762,14 +2852,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2762
2852
  exportsInfo.setUsedForSideEffectsOnly(runtime);
2763
2853
  }
2764
2854
  }
2765
- this.chunkGraph.addModuleRuntimeRequirements(
2855
+ chunkGraph.addModuleRuntimeRequirements(
2766
2856
  module,
2767
2857
  chunk.runtime,
2768
2858
  new Set([RuntimeGlobals.requireScope])
2769
2859
  );
2770
2860
 
2771
2861
  // runtime modules don't need ids
2772
- this.chunkGraph.setModuleId(module, "");
2862
+ chunkGraph.setModuleId(module, "");
2773
2863
 
2774
2864
  // Call hook
2775
2865
  this.hooks.runtimeModule.call(module, chunk);
@@ -3889,6 +3979,356 @@ This prevents using hashes of each other and should be avoided.`);
3889
3979
  );
3890
3980
  }
3891
3981
 
3982
+ /**
3983
+ * @param {Module} module the module
3984
+ * @param {ExecuteModuleOptions} options options
3985
+ * @param {ExecuteModuleCallback} callback callback
3986
+ */
3987
+ executeModule(module, options, callback) {
3988
+ // Aggregate all referenced modules and ensure they are ready
3989
+ const modules = new Set([module]);
3990
+ processAsyncTree(
3991
+ modules,
3992
+ 10,
3993
+ /**
3994
+ * @param {Module} module the module
3995
+ * @param {function(Module): void} push push more jobs
3996
+ * @param {Callback} callback callback
3997
+ * @returns {void}
3998
+ */
3999
+ (module, push, callback) => {
4000
+ this.addModuleQueue.waitFor(module, err => {
4001
+ if (err) return callback(err);
4002
+ this.buildQueue.waitFor(module, err => {
4003
+ if (err) return callback(err);
4004
+ this.processDependenciesQueue.waitFor(module, err => {
4005
+ if (err) return callback(err);
4006
+ for (const {
4007
+ module: m
4008
+ } of this.moduleGraph.getOutgoingConnections(module)) {
4009
+ const size = modules.size;
4010
+ modules.add(m);
4011
+ if (modules.size !== size) push(m);
4012
+ }
4013
+ callback();
4014
+ });
4015
+ });
4016
+ });
4017
+ },
4018
+ err => {
4019
+ if (err) return callback(err);
4020
+
4021
+ // Create new chunk graph, chunk and entrypoint for the build time execution
4022
+ const chunkGraph = new ChunkGraph(this.moduleGraph);
4023
+ const runtime = "build time";
4024
+ const {
4025
+ hashFunction,
4026
+ hashDigest,
4027
+ hashDigestLength
4028
+ } = this.outputOptions;
4029
+ const runtimeTemplate = this.runtimeTemplate;
4030
+
4031
+ const chunk = new Chunk("build time chunk");
4032
+ chunk.id = chunk.name;
4033
+ chunk.ids = [chunk.id];
4034
+ chunk.runtime = runtime;
4035
+
4036
+ const entrypoint = new Entrypoint({
4037
+ runtime,
4038
+ chunkLoading: false,
4039
+ ...options.entryOptions
4040
+ });
4041
+ chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint);
4042
+ connectChunkGroupAndChunk(entrypoint, chunk);
4043
+ entrypoint.setRuntimeChunk(chunk);
4044
+ entrypoint.setEntrypointChunk(chunk);
4045
+
4046
+ const chunks = new Set([chunk]);
4047
+
4048
+ // Assign ids to modules and modules to the chunk
4049
+ for (const module of modules) {
4050
+ const id = module.identifier();
4051
+ chunkGraph.setModuleId(module, id);
4052
+ chunkGraph.connectChunkAndModule(chunk, module);
4053
+ }
4054
+
4055
+ // Hash modules
4056
+ for (const module of modules) {
4057
+ this._createModuleHash(
4058
+ module,
4059
+ chunkGraph,
4060
+ runtime,
4061
+ hashFunction,
4062
+ runtimeTemplate,
4063
+ hashDigest,
4064
+ hashDigestLength
4065
+ );
4066
+ }
4067
+
4068
+ const codeGenerationResults = new CodeGenerationResults();
4069
+ /** @type {WebpackError[]} */
4070
+ const errors = [];
4071
+ /**
4072
+ * @param {Module} module the module
4073
+ * @param {Callback} callback callback
4074
+ * @returns {void}
4075
+ */
4076
+ const codeGen = (module, callback) => {
4077
+ this._codeGenerationModule(
4078
+ module,
4079
+ runtime,
4080
+ [runtime],
4081
+ chunkGraph.getModuleHash(module, runtime),
4082
+ this.dependencyTemplates,
4083
+ chunkGraph,
4084
+ this.moduleGraph,
4085
+ runtimeTemplate,
4086
+ errors,
4087
+ codeGenerationResults,
4088
+ (err, codeGenerated) => {
4089
+ callback(err);
4090
+ }
4091
+ );
4092
+ };
4093
+
4094
+ const reportErrors = () => {
4095
+ if (errors.length > 0) {
4096
+ errors.sort(
4097
+ compareSelect(err => err.module, compareModulesByIdentifier)
4098
+ );
4099
+ for (const error of errors) {
4100
+ this.errors.push(error);
4101
+ }
4102
+ errors.length = 0;
4103
+ }
4104
+ };
4105
+
4106
+ // Generate code for all aggregated modules
4107
+ asyncLib.eachLimit(modules, 10, codeGen, err => {
4108
+ if (err) return callback(err);
4109
+ reportErrors();
4110
+
4111
+ // for backward-compat temporary set the chunk graph
4112
+ // TODO webpack 6
4113
+ const old = this.chunkGraph;
4114
+ this.chunkGraph = chunkGraph;
4115
+ this.processRuntimeRequirements({
4116
+ chunkGraph,
4117
+ modules,
4118
+ chunks,
4119
+ codeGenerationResults,
4120
+ chunkGraphEntries: chunks
4121
+ });
4122
+ this.chunkGraph = old;
4123
+
4124
+ const runtimeModules = chunkGraph.getChunkRuntimeModulesIterable(
4125
+ chunk
4126
+ );
4127
+
4128
+ // Hash runtime modules
4129
+ for (const module of runtimeModules) {
4130
+ modules.add(module);
4131
+ this._createModuleHash(
4132
+ module,
4133
+ chunkGraph,
4134
+ runtime,
4135
+ hashFunction,
4136
+ runtimeTemplate,
4137
+ hashDigest,
4138
+ hashDigestLength
4139
+ );
4140
+ }
4141
+
4142
+ // Generate code for all runtime modules
4143
+ asyncLib.eachLimit(runtimeModules, 10, codeGen, err => {
4144
+ if (err) return callback(err);
4145
+ reportErrors();
4146
+
4147
+ /** @type {Map<Module, ExecuteModuleArgument>} */
4148
+ const moduleArgumentsMap = new Map();
4149
+ /** @type {Map<string, ExecuteModuleArgument>} */
4150
+ const moduleArgumentsById = new Map();
4151
+
4152
+ /** @type {ExecuteModuleResult["fileDependencies"]} */
4153
+ const fileDependencies = new LazySet();
4154
+ /** @type {ExecuteModuleResult["contextDependencies"]} */
4155
+ const contextDependencies = new LazySet();
4156
+ /** @type {ExecuteModuleResult["missingDependencies"]} */
4157
+ const missingDependencies = new LazySet();
4158
+ /** @type {ExecuteModuleResult["buildDependencies"]} */
4159
+ const buildDependencies = new LazySet();
4160
+
4161
+ /** @type {ExecuteModuleResult["assets"]} */
4162
+ const assets = new Map();
4163
+
4164
+ let cacheable = true;
4165
+
4166
+ /** @type {ExecuteModuleContext} */
4167
+ const context = {
4168
+ assets,
4169
+ __webpack_require__: undefined,
4170
+ chunk,
4171
+ chunkGraph
4172
+ };
4173
+
4174
+ // Prepare execution
4175
+ asyncLib.eachLimit(
4176
+ modules,
4177
+ 10,
4178
+ (module, callback) => {
4179
+ const codeGenerationResult = codeGenerationResults.get(
4180
+ module,
4181
+ runtime
4182
+ );
4183
+ /** @type {ExecuteModuleArgument} */
4184
+ const moduleArgument = {
4185
+ module,
4186
+ codeGenerationResult,
4187
+ preparedInfo: undefined,
4188
+ moduleObject: undefined
4189
+ };
4190
+ moduleArgumentsMap.set(module, moduleArgument);
4191
+ moduleArgumentsById.set(module.identifier(), moduleArgument);
4192
+ module.addCacheDependencies(
4193
+ fileDependencies,
4194
+ contextDependencies,
4195
+ missingDependencies,
4196
+ buildDependencies
4197
+ );
4198
+ if (module.buildInfo.cacheable === false) {
4199
+ cacheable = false;
4200
+ }
4201
+ if (module.buildInfo && module.buildInfo.assets) {
4202
+ const { assets: moduleAssets, assetsInfo } = module.buildInfo;
4203
+ for (const assetName of Object.keys(moduleAssets)) {
4204
+ assets.set(assetName, {
4205
+ source: moduleAssets[assetName],
4206
+ info: assetsInfo ? assetsInfo.get(assetName) : undefined
4207
+ });
4208
+ }
4209
+ }
4210
+ this.hooks.prepareModuleExecution.callAsync(
4211
+ moduleArgument,
4212
+ context,
4213
+ callback
4214
+ );
4215
+ },
4216
+ err => {
4217
+ if (err) return callback(err);
4218
+
4219
+ let exports;
4220
+ try {
4221
+ const {
4222
+ strictModuleErrorHandling,
4223
+ strictModuleExceptionHandling
4224
+ } = this.outputOptions;
4225
+ const __webpack_require__ = id => {
4226
+ const cached = moduleCache[id];
4227
+ if (cached !== undefined) {
4228
+ if (cached.error) throw cached.error;
4229
+ return cached.exports;
4230
+ }
4231
+ const moduleArgument = moduleArgumentsById.get(id);
4232
+ return __webpack_require_module__(moduleArgument, id);
4233
+ };
4234
+ const interceptModuleExecution = (__webpack_require__[
4235
+ RuntimeGlobals.interceptModuleExecution.replace(
4236
+ "__webpack_require__.",
4237
+ ""
4238
+ )
4239
+ ] = []);
4240
+ const moduleCache = (__webpack_require__[
4241
+ RuntimeGlobals.moduleCache.replace(
4242
+ "__webpack_require__.",
4243
+ ""
4244
+ )
4245
+ ] = {});
4246
+
4247
+ context.__webpack_require__ = __webpack_require__;
4248
+
4249
+ /**
4250
+ * @param {ExecuteModuleArgument} moduleArgument the module argument
4251
+ * @param {string=} id id
4252
+ * @returns {any} exports
4253
+ */
4254
+ const __webpack_require_module__ = (moduleArgument, id) => {
4255
+ var execOptions = {
4256
+ id,
4257
+ module: {
4258
+ id,
4259
+ exports: {},
4260
+ loaded: false,
4261
+ error: undefined
4262
+ },
4263
+ require: __webpack_require__
4264
+ };
4265
+ interceptModuleExecution.forEach(handler =>
4266
+ handler(execOptions)
4267
+ );
4268
+ const module = moduleArgument.module;
4269
+ this.buildTimeExecutedModules.add(module);
4270
+ const moduleObject = execOptions.module;
4271
+ moduleArgument.moduleObject = moduleObject;
4272
+ try {
4273
+ if (id) moduleCache[id] = moduleObject;
4274
+
4275
+ tryRunOrWebpackError(
4276
+ () =>
4277
+ this.hooks.executeModule.call(
4278
+ moduleArgument,
4279
+ context
4280
+ ),
4281
+ "Compilation.hooks.executeModule"
4282
+ );
4283
+ moduleObject.loaded = true;
4284
+ return moduleObject.exports;
4285
+ } catch (e) {
4286
+ if (strictModuleExceptionHandling) {
4287
+ if (id) delete moduleCache[id];
4288
+ } else if (strictModuleErrorHandling) {
4289
+ moduleObject.error = e;
4290
+ }
4291
+ if (!e.module) e.module = module;
4292
+ throw e;
4293
+ }
4294
+ };
4295
+
4296
+ for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder(
4297
+ chunk
4298
+ )) {
4299
+ __webpack_require_module__(
4300
+ moduleArgumentsMap.get(runtimeModule)
4301
+ );
4302
+ }
4303
+ exports = __webpack_require__(module.identifier());
4304
+ } catch (e) {
4305
+ const err = new WebpackError(
4306
+ `Execution of module code from module graph (${module.readableIdentifier(
4307
+ this.requestShortener
4308
+ )}) failed: ${e.message}`
4309
+ );
4310
+ err.stack = e.stack;
4311
+ err.module = e.module;
4312
+ return callback(err);
4313
+ }
4314
+
4315
+ callback(null, {
4316
+ exports,
4317
+ assets,
4318
+ cacheable,
4319
+ fileDependencies,
4320
+ contextDependencies,
4321
+ missingDependencies,
4322
+ buildDependencies
4323
+ });
4324
+ }
4325
+ );
4326
+ });
4327
+ });
4328
+ }
4329
+ );
4330
+ }
4331
+
3892
4332
  checkConstraints() {
3893
4333
  const chunkGraph = this.chunkGraph;
3894
4334