webpack 5.101.0 → 5.101.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.
@@ -0,0 +1,70 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Natsu @xiaoxiaojx
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { updateHashForEntryStartup } = require("./StartupHelpers");
9
+
10
+ /** @typedef {import("../ChunkGraph")} ChunkGraph */
11
+ /** @typedef {import("../Module")} Module */
12
+ /** @typedef {import("../Chunk")} Chunk */
13
+ /** @typedef {import("../Entrypoint")} Entrypoint */
14
+ /** @typedef {import("../util/Hash")} Hash */
15
+ /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
16
+
17
+ /**
18
+ * Gets information about a chunk including its entries and runtime chunk
19
+ * @param {Chunk} chunk The chunk to get information for
20
+ * @param {ChunkGraph} chunkGraph The chunk graph containing the chunk
21
+ * @returns {{entries: Array<[Module, Entrypoint | undefined]>, runtimeChunk: Chunk|null}} Object containing chunk entries and runtime chunk
22
+ */
23
+ function getChunkInfo(chunk, chunkGraph) {
24
+ const entries = [
25
+ ...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
26
+ ];
27
+ const runtimeChunk =
28
+ entries.length > 0
29
+ ? /** @type {Entrypoint[][]} */
30
+ (entries)[0][1].getRuntimeChunk()
31
+ : null;
32
+
33
+ return {
34
+ entries,
35
+ runtimeChunk
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Creates a chunk hash handler
41
+ * @param {string} name The name of the chunk
42
+ * @returns {(chunk: Chunk, hash: Hash, { chunkGraph }: ChunkHashContext) => void} The chunk hash handler
43
+ */
44
+ function createChunkHashHandler(name) {
45
+ /**
46
+ * @param {Chunk} chunk The chunk to get information for
47
+ * @param {Hash} hash The hash to update
48
+ * @param {ChunkHashContext} chunkHashContext The chunk hash context
49
+ * @returns {void}
50
+ */
51
+ return (chunk, hash, { chunkGraph }) => {
52
+ if (chunk.hasRuntime()) return;
53
+ const { entries, runtimeChunk } = getChunkInfo(chunk, chunkGraph);
54
+ hash.update(name);
55
+ hash.update("1");
56
+ if (runtimeChunk && runtimeChunk.hash) {
57
+ // https://github.com/webpack/webpack/issues/19439
58
+ // Any change to runtimeChunk should trigger a hash update,
59
+ // we shouldn't depend on or inspect its internal implementation.
60
+ // import __webpack_require__ from "./runtime-main.e9400aee33633a3973bd.js";
61
+ hash.update(runtimeChunk.hash);
62
+ }
63
+ updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
64
+ };
65
+ }
66
+
67
+ module.exports = {
68
+ createChunkHashHandler,
69
+ getChunkInfo
70
+ };
@@ -9,14 +9,15 @@ const { ConcatSource, RawSource } = require("webpack-sources");
9
9
  const RuntimeGlobals = require("../RuntimeGlobals");
10
10
  const Template = require("../Template");
11
11
  const { getUndoPath } = require("../util/identifier");
12
+ const {
13
+ createChunkHashHandler,
14
+ getChunkInfo
15
+ } = require("./ChunkFormatHelpers");
12
16
  const {
13
17
  getChunkFilenameTemplate,
14
18
  getCompilationHooks
15
19
  } = require("./JavascriptModulesPlugin");
16
- const {
17
- generateEntryStartup,
18
- updateHashForEntryStartup
19
- } = require("./StartupHelpers");
20
+ const { generateEntryStartup } = require("./StartupHelpers");
20
21
 
21
22
  /** @typedef {import("../Chunk")} Chunk */
22
23
  /** @typedef {import("../Compiler")} Compiler */
@@ -59,13 +60,8 @@ class CommonJsChunkFormatPlugin {
59
60
  Template.renderChunkRuntimeModules(runtimeModules, renderContext)
60
61
  );
61
62
  }
62
- const entries = [
63
- ...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
64
- ];
65
- if (entries.length > 0) {
66
- const runtimeChunk =
67
- /** @type {Entrypoint} */
68
- (entries[0][1]).getRuntimeChunk();
63
+ const { entries, runtimeChunk } = getChunkInfo(chunk, chunkGraph);
64
+ if (runtimeChunk) {
69
65
  const currentOutputName = compilation
70
66
  .getPath(
71
67
  getChunkFilenameTemplate(chunk, compilation.outputOptions),
@@ -144,15 +140,8 @@ class CommonJsChunkFormatPlugin {
144
140
  }
145
141
  return source;
146
142
  });
147
- hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash, { chunkGraph }) => {
148
- if (chunk.hasRuntime()) return;
149
- hash.update(PLUGIN_NAME);
150
- hash.update("1");
151
- const entries = [
152
- ...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
153
- ];
154
- updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
155
- });
143
+
144
+ hooks.chunkHash.tap(PLUGIN_NAME, createChunkHashHandler(PLUGIN_NAME));
156
145
  });
157
146
  }
158
147
  }
@@ -173,13 +173,38 @@ const printGeneratedCodeForStack = (module, code) => {
173
173
  * @property {string} hash hash to be used for render call
174
174
  */
175
175
 
176
- /** @typedef {RenderContext & { inlined: boolean }} StartupRenderContext */
176
+ /**
177
+ * @typedef {object} StartupRenderContext
178
+ * @property {Chunk} chunk the chunk
179
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
180
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
181
+ * @property {ModuleGraph} moduleGraph the module graph
182
+ * @property {ChunkGraph} chunkGraph the chunk graph
183
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
184
+ * @property {boolean | undefined} strictMode rendering in strict context
185
+ * @property {boolean } inlined inlined
186
+ * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE
187
+ */
188
+
189
+ /**
190
+ * @typedef {object} ModuleRenderContext
191
+ * @property {Chunk} chunk the chunk
192
+ * @property {DependencyTemplates} dependencyTemplates the dependency templates
193
+ * @property {RuntimeTemplate} runtimeTemplate the runtime template
194
+ * @property {ModuleGraph} moduleGraph the module graph
195
+ * @property {ChunkGraph} chunkGraph the chunk graph
196
+ * @property {CodeGenerationResults} codeGenerationResults results of code generation
197
+ * @property {InitFragment<ChunkRenderContext>[]} chunkInitFragments init fragments for the chunk
198
+ * @property {boolean | undefined} strictMode rendering in strict context
199
+ * @property {boolean} factory true: renders as factory method, false: pure module content
200
+ * @property {boolean=} inlinedInIIFE the inlined entry module is wrapped in an IIFE, existing only when `factory` is set to false
201
+ */
177
202
 
178
203
  /**
179
204
  * @typedef {object} CompilationHooks
180
- * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContent
181
- * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContainer
182
- * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage
205
+ * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContent
206
+ * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModuleContainer
207
+ * @property {SyncWaterfallHook<[Source, Module, ModuleRenderContext]>} renderModulePackage
183
208
  * @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk
184
209
  * @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain
185
210
  * @property {SyncWaterfallHook<[Source, RenderContext]>} renderContent
@@ -217,17 +242,17 @@ class JavascriptModulesPlugin {
217
242
  renderModuleContent: new SyncWaterfallHook([
218
243
  "source",
219
244
  "module",
220
- "renderContext"
245
+ "moduleRenderContext"
221
246
  ]),
222
247
  renderModuleContainer: new SyncWaterfallHook([
223
248
  "source",
224
249
  "module",
225
- "renderContext"
250
+ "moduleRenderContext"
226
251
  ]),
227
252
  renderModulePackage: new SyncWaterfallHook([
228
253
  "source",
229
254
  "module",
230
- "renderContext"
255
+ "moduleRenderContext"
231
256
  ]),
232
257
  render: new SyncWaterfallHook(["source", "renderContext"]),
233
258
  renderContent: new SyncWaterfallHook(["source", "renderContext"]),
@@ -575,18 +600,18 @@ class JavascriptModulesPlugin {
575
600
 
576
601
  /**
577
602
  * @param {Module} module the rendered module
578
- * @param {ChunkRenderContext} renderContext options object
603
+ * @param {ModuleRenderContext} renderContext options object
579
604
  * @param {CompilationHooks} hooks hooks
580
- * @param {boolean} factory true: renders as factory method, false: pure module content
581
605
  * @returns {Source | null} the newly generated source from rendering
582
606
  */
583
- renderModule(module, renderContext, hooks, factory) {
607
+ renderModule(module, renderContext, hooks) {
584
608
  const {
585
609
  chunk,
586
610
  chunkGraph,
587
611
  runtimeTemplate,
588
612
  codeGenerationResults,
589
- strictMode
613
+ strictMode,
614
+ factory
590
615
  } = renderContext;
591
616
  try {
592
617
  const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
@@ -729,7 +754,11 @@ class JavascriptModulesPlugin {
729
754
  };
730
755
  const moduleSources =
731
756
  Template.renderChunkModules(chunkRenderContext, allModules, (module) =>
732
- this.renderModule(module, chunkRenderContext, hooks, true)
757
+ this.renderModule(
758
+ module,
759
+ { ...chunkRenderContext, factory: true },
760
+ hooks
761
+ )
733
762
  ) || new RawSource("{}");
734
763
  let source = tryRunOrWebpackError(
735
764
  () => hooks.renderChunk.call(moduleSources, chunkRenderContext),
@@ -841,7 +870,12 @@ class JavascriptModulesPlugin {
841
870
  (m) => !(/** @type {Set<Module>} */ (inlinedModules).has(m))
842
871
  )
843
872
  : allModules,
844
- (module) => this.renderModule(module, chunkRenderContext, hooks, true),
873
+ (module) =>
874
+ this.renderModule(
875
+ module,
876
+ { ...chunkRenderContext, factory: true },
877
+ hooks
878
+ ),
845
879
  prefix
846
880
  );
847
881
  if (
@@ -913,6 +947,8 @@ class JavascriptModulesPlugin {
913
947
  const avoidEntryIife = compilation.options.optimization.avoidEntryIife;
914
948
  /** @type {Map<Module, Source> | false} */
915
949
  let renamedInlinedModule = false;
950
+ let inlinedInIIFE = false;
951
+
916
952
  if (avoidEntryIife) {
917
953
  renamedInlinedModule = this.getRenamedInlineModule(
918
954
  allModules,
@@ -926,31 +962,46 @@ class JavascriptModulesPlugin {
926
962
  }
927
963
 
928
964
  for (const m of inlinedModules) {
965
+ const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
966
+ m,
967
+ chunk.runtime
968
+ );
969
+ const exports = runtimeRequirements.has(RuntimeGlobals.exports);
970
+ const webpackExports =
971
+ exports && m.exportsArgument === RuntimeGlobals.exports;
972
+
973
+ const innerStrict =
974
+ !allStrict && /** @type {BuildInfo} */ (m.buildInfo).strict;
975
+
976
+ const iife = innerStrict
977
+ ? "it needs to be in strict mode."
978
+ : inlinedModules.size > 1
979
+ ? // TODO check globals and top-level declarations of other entries and chunk modules
980
+ // to make a better decision
981
+ "it needs to be isolated against other entry modules."
982
+ : chunkModules && !renamedInlinedModule
983
+ ? "it needs to be isolated against other modules in the chunk."
984
+ : exports && !webpackExports
985
+ ? `it uses a non-standard name for the exports (${m.exportsArgument}).`
986
+ : hooks.embedInRuntimeBailout.call(m, renderContext);
987
+
988
+ if (iife) {
989
+ inlinedInIIFE = true;
990
+ }
991
+
929
992
  const renderedModule = renamedInlinedModule
930
993
  ? renamedInlinedModule.get(m)
931
- : this.renderModule(m, chunkRenderContext, hooks, false);
994
+ : this.renderModule(
995
+ m,
996
+ {
997
+ ...chunkRenderContext,
998
+ factory: false,
999
+ inlinedInIIFE
1000
+ },
1001
+ hooks
1002
+ );
932
1003
 
933
1004
  if (renderedModule) {
934
- const innerStrict =
935
- !allStrict && /** @type {BuildInfo} */ (m.buildInfo).strict;
936
- const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
937
- m,
938
- chunk.runtime
939
- );
940
- const exports = runtimeRequirements.has(RuntimeGlobals.exports);
941
- const webpackExports =
942
- exports && m.exportsArgument === RuntimeGlobals.exports;
943
- const iife = innerStrict
944
- ? "it needs to be in strict mode."
945
- : inlinedModules.size > 1
946
- ? // TODO check globals and top-level declarations of other entries and chunk modules
947
- // to make a better decision
948
- "it needs to be isolated against other entry modules."
949
- : chunkModules && !renamedInlinedModule
950
- ? "it needs to be isolated against other modules in the chunk."
951
- : exports && !webpackExports
952
- ? `it uses a non-standard name for the exports (${m.exportsArgument}).`
953
- : hooks.embedInRuntimeBailout.call(m, renderContext);
954
1005
  let footer;
955
1006
  if (iife !== undefined) {
956
1007
  startupSource.add(
@@ -989,7 +1040,8 @@ class JavascriptModulesPlugin {
989
1040
  source.add(
990
1041
  hooks.renderStartup.call(startupSource, lastInlinedModule, {
991
1042
  ...renderContext,
992
- inlined: true
1043
+ inlined: true,
1044
+ inlinedInIIFE
993
1045
  })
994
1046
  );
995
1047
  if (bootstrap.afterStartup.length > 0) {
@@ -1557,7 +1609,6 @@ class JavascriptModulesPlugin {
1557
1609
  allModules.every((m) => /** @type {BuildInfo} */ (m.buildInfo).strict);
1558
1610
  const isMultipleEntries = inlinedModules.size > 1;
1559
1611
  const singleEntryWithModules = inlinedModules.size === 1 && hasChunkModules;
1560
-
1561
1612
  // TODO:
1562
1613
  // This step is before the IIFE reason calculation. Ideally, it should only be executed when this function can optimize the
1563
1614
  // IIFE reason. Otherwise, it should directly return false. There are four reasons now, we have skipped two already, the left
@@ -1581,9 +1632,12 @@ class JavascriptModulesPlugin {
1581
1632
  const isInlinedModule = inlinedModules && inlinedModules.has(m);
1582
1633
  const moduleSource = this.renderModule(
1583
1634
  m,
1584
- chunkRenderContext,
1585
- hooks,
1586
- !isInlinedModule
1635
+ {
1636
+ ...chunkRenderContext,
1637
+ factory: !isInlinedModule,
1638
+ inlinedInIIFE: false
1639
+ },
1640
+ hooks
1587
1641
  );
1588
1642
 
1589
1643
  if (!moduleSource) continue;
@@ -19,6 +19,8 @@ const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin")
19
19
  /** @typedef {import("../Module")} Module */
20
20
  /** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
21
21
  /** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
22
+ /** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
23
+ /** @typedef {import("../javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
22
24
  /** @typedef {import("../util/Hash")} Hash */
23
25
 
24
26
  const COMMON_LIBRARY_NAME_MESSAGE =
@@ -173,6 +175,20 @@ class AbstractLibraryPlugin {
173
175
  });
174
176
  }
175
177
 
178
+ if (
179
+ this.renderModuleContent !==
180
+ AbstractLibraryPlugin.prototype.renderModuleContent
181
+ ) {
182
+ hooks.renderModuleContent.tap(
183
+ _pluginName,
184
+ (source, module, renderContext) =>
185
+ this.renderModuleContent(source, module, renderContext, {
186
+ compilation,
187
+ chunkGraph: compilation.chunkGraph
188
+ })
189
+ );
190
+ }
191
+
176
192
  if (
177
193
  this.renderStartup !== AbstractLibraryPlugin.prototype.renderStartup
178
194
  ) {
@@ -288,6 +304,17 @@ class AbstractLibraryPlugin {
288
304
  return source;
289
305
  }
290
306
 
307
+ /**
308
+ * @param {Source} source source
309
+ * @param {Module} module module
310
+ * @param {ModuleRenderContext} renderContext render context
311
+ * @param {Omit<LibraryContext<T>, 'options'>} libraryContext context
312
+ * @returns {Source} source with library export
313
+ */
314
+ renderModuleContent(source, module, renderContext, libraryContext) {
315
+ return source;
316
+ }
317
+
291
318
  /**
292
319
  * @param {Chunk} chunk the chunk
293
320
  * @param {Hash} hash hash
@@ -8,7 +8,7 @@
8
8
  const { ConcatSource } = require("webpack-sources");
9
9
  const RuntimeGlobals = require("../RuntimeGlobals");
10
10
  const Template = require("../Template");
11
- const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
11
+ const CommonJsSelfReferenceDependency = require("../dependencies/CommonJsSelfReferenceDependency");
12
12
  const ConcatenatedModule = require("../optimize/ConcatenatedModule");
13
13
  const propertyAccess = require("../util/propertyAccess");
14
14
  const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
@@ -22,6 +22,7 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
22
22
  /** @typedef {import("../Module")} Module */
23
23
  /** @typedef {import("../Module").BuildMeta} BuildMeta */
24
24
  /** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
25
+ /** @typedef {import("../javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
25
26
  /** @typedef {import("../util/Hash")} Hash */
26
27
 
27
28
  /**
@@ -66,37 +67,9 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
66
67
  super.apply(compiler);
67
68
 
68
69
  compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
69
- const { exportsDefinitions } =
70
+ const { onDemandExportsGeneration } =
70
71
  ConcatenatedModule.getCompilationHooks(compilation);
71
- exportsDefinitions.tap(PLUGIN_NAME, (definitions, module) => {
72
- const bailout = JavascriptModulesPlugin.getCompilationHooks(
73
- compilation
74
- ).inlineInRuntimeBailout.call(module, {});
75
- if (bailout) return false;
76
- // If we have connections not all modules were concatenated, so we need the wrapper
77
- const connections =
78
- compilation.moduleGraph.getIncomingConnections(module);
79
-
80
- for (const connection of connections) {
81
- if (connection.originModule) {
82
- return false;
83
- }
84
- }
85
-
86
- // Runtime and splitting chunks now requires the wrapper too
87
- for (const chunk of compilation.chunkGraph.getModuleChunksIterable(
88
- module
89
- )) {
90
- if (
91
- !chunk.hasRuntime() ||
92
- compilation.chunkGraph.getNumberOfEntryModules(chunk) > 1
93
- ) {
94
- return false;
95
- }
96
- }
97
-
98
- return true;
99
- });
72
+ onDemandExportsGeneration.tap(PLUGIN_NAME, (_module) => true);
100
73
  });
101
74
  }
102
75
 
@@ -128,10 +101,21 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
128
101
  renderStartup(
129
102
  source,
130
103
  module,
131
- { moduleGraph, chunk, codeGenerationResults },
104
+ { moduleGraph, chunk, codeGenerationResults, inlined, inlinedInIIFE },
132
105
  { options, compilation }
133
106
  ) {
134
107
  const result = new ConcatSource(source);
108
+
109
+ if (!module.buildMeta || !module.buildMeta.exportsType) {
110
+ for (const dependency of module.dependencies) {
111
+ if (dependency instanceof CommonJsSelfReferenceDependency) {
112
+ result.add(`export { ${RuntimeGlobals.exports} as default }`);
113
+ break;
114
+ }
115
+ }
116
+ return result;
117
+ }
118
+
135
119
  const exportsInfo = options.export
136
120
  ? [
137
121
  moduleGraph.getExportInfo(
@@ -141,8 +125,11 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
141
125
  ]
142
126
  : moduleGraph.getExportsInfo(module).orderedExports;
143
127
  const definitions =
144
- /** @type {BuildMeta} */
145
- (module.buildMeta).exportsFinalName || {};
128
+ inlined && !inlinedInIIFE
129
+ ? (module.buildMeta &&
130
+ /** @type {GenerationMeta} */ module.buildMeta.exportsFinalName) ||
131
+ {}
132
+ : {};
146
133
  /** @type {string[]} */
147
134
  const shortHandedExports = [];
148
135
  /** @type {[string, string][]} */
@@ -241,6 +228,32 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
241
228
 
242
229
  return result;
243
230
  }
231
+
232
+ /**
233
+ * @param {Source} source source
234
+ * @param {Module} module module
235
+ * @param {ModuleRenderContext} renderContext render context
236
+ * @param {Omit<LibraryContext<T>, 'options'>} libraryContext context
237
+ * @returns {Source} source with library export
238
+ */
239
+ renderModuleContent(
240
+ source,
241
+ module,
242
+ { factory, inlinedInIIFE },
243
+ libraryContext
244
+ ) {
245
+ const result = new ConcatSource(source);
246
+ // Re-add `factoryExportsBinding` to the source
247
+ // when the module is rendered as a factory or treated as an inlined (startup) module but wrapped in an IIFE
248
+ if (
249
+ (inlinedInIIFE || factory) &&
250
+ module.buildMeta &&
251
+ module.buildMeta.factoryExportsBinding
252
+ ) {
253
+ result.add(module.buildMeta.factoryExportsBinding);
254
+ }
255
+ return result;
256
+ }
244
257
  }
245
258
 
246
259
  module.exports = ModuleLibraryPlugin;
@@ -158,11 +158,16 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
158
158
  ? "if(true) { // all chunks have JS"
159
159
  : `if(${hasJsMatcher("chunkId")}) {`,
160
160
  Template.indent([
161
- `installChunk(require(${JSON.stringify(
161
+ // The require function loads and runs a chunk. When the chunk is being run,
162
+ // it can call __webpack_require__.C to directly complete installed.
163
+ `var installedChunk = require(${JSON.stringify(
162
164
  rootOutputDir
163
165
  )} + ${
164
166
  RuntimeGlobals.getChunkScriptFilename
165
- }(chunkId)));`
167
+ }(chunkId));`,
168
+ "if (!installedChunks[chunkId]) {",
169
+ Template.indent(["installChunk(installedChunk);"]),
170
+ "}"
166
171
  ]),
167
172
  "} else installedChunks[chunkId] = 1;",
168
173
  ""
@@ -668,7 +668,7 @@ const getFinalName = (
668
668
 
669
669
  /**
670
670
  * @typedef {object} ConcatenateModuleHooks
671
- * @property {SyncBailHook<[Record<string, string>, ConcatenatedModule], boolean | void>} exportsDefinitions
671
+ * @property {SyncBailHook<[ConcatenatedModule], boolean>} onDemandExportsGeneration
672
672
  * @property {SyncBailHook<[Partial<ConcatenatedModuleInfo>, ConcatenatedModuleInfo], boolean | void>} concatenatedModuleInfo
673
673
  */
674
674
 
@@ -716,7 +716,7 @@ class ConcatenatedModule extends Module {
716
716
  let hooks = compilationHooksMap.get(compilation);
717
717
  if (hooks === undefined) {
718
718
  hooks = {
719
- exportsDefinitions: new SyncBailHook(["definitions", "module"]),
719
+ onDemandExportsGeneration: new SyncBailHook(["module"]),
720
720
  concatenatedModuleInfo: new SyncBailHook([
721
721
  "updatedInfo",
722
722
  "concatenatedModuleInfo"
@@ -1692,11 +1692,6 @@ class ConcatenatedModule extends Module {
1692
1692
 
1693
1693
  // define exports
1694
1694
  if (exportsMap.size > 0) {
1695
- const { exportsDefinitions } = ConcatenatedModule.getCompilationHooks(
1696
- /** @type {Compilation} */
1697
- (this.compilation)
1698
- );
1699
-
1700
1695
  const definitions = [];
1701
1696
  for (const [key, value] of exportsMap) {
1702
1697
  definitions.push(
@@ -1706,34 +1701,39 @@ class ConcatenatedModule extends Module {
1706
1701
  );
1707
1702
  }
1708
1703
 
1709
- const shouldSkipRenderDefinitions = exportsDefinitions.call(
1710
- exportsFinalName,
1711
- this
1712
- );
1704
+ const { onDemandExportsGeneration } =
1705
+ ConcatenatedModule.getCompilationHooks(
1706
+ /** @type {Compilation} */
1707
+ (this.compilation)
1708
+ );
1713
1709
 
1714
- if (!shouldSkipRenderDefinitions) {
1715
- runtimeRequirements.add(RuntimeGlobals.exports);
1716
- runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1710
+ runtimeRequirements.add(RuntimeGlobals.exports);
1711
+ runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
1717
1712
 
1718
- if (shouldAddHarmonyFlag) {
1719
- result.add("// ESM COMPAT FLAG\n");
1720
- result.add(
1721
- runtimeTemplate.defineEsModuleFlagStatement({
1722
- exportsArgument: this.exportsArgument,
1723
- runtimeRequirements
1724
- })
1725
- );
1726
- }
1713
+ if (shouldAddHarmonyFlag) {
1714
+ result.add("// ESM COMPAT FLAG\n");
1715
+ result.add(
1716
+ runtimeTemplate.defineEsModuleFlagStatement({
1717
+ exportsArgument: this.exportsArgument,
1718
+ runtimeRequirements
1719
+ })
1720
+ );
1721
+ }
1727
1722
 
1723
+ if (onDemandExportsGeneration.call(this)) {
1724
+ /** @type {BuildMeta} */ (this.buildMeta).factoryExportsBinding =
1725
+ `${RuntimeGlobals.definePropertyGetters}(${
1726
+ this.exportsArgument
1727
+ }, {${definitions.join(",")}\n});\n`;
1728
+ /** @type {BuildMeta} */ (this.buildMeta).exportsFinalName =
1729
+ exportsFinalName;
1730
+ } else {
1728
1731
  result.add("\n// EXPORTS\n");
1729
1732
  result.add(
1730
1733
  `${RuntimeGlobals.definePropertyGetters}(${
1731
1734
  this.exportsArgument
1732
1735
  }, {${definitions.join(",")}\n});\n`
1733
1736
  );
1734
- } else {
1735
- /** @type {BuildMeta} */
1736
- (this.buildMeta).exportsFinalName = exportsFinalName;
1737
1737
  }
1738
1738
  }
1739
1739
 
@@ -107,6 +107,10 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
107
107
  )) {
108
108
  addChunk(c);
109
109
  }
110
+ includedChunksMessages.push("chunks that the entrypoint depends on");
111
+ for (const c of chunkGraph.getChunkEntryDependOnChunksIterable(chunk)) {
112
+ addChunk(c);
113
+ }
110
114
  }
111
115
  }
112
116
  for (const entrypoint of chunk.getAllReferencedAsyncEntrypoints()) {
@@ -272,6 +272,7 @@ const deserialize = async (middleware, name, readFile) => {
272
272
  while (contentItemLength - contentPosition < n) {
273
273
  const remaining = contentItem.slice(contentPosition);
274
274
  let lengthFromNext = n - remaining.length;
275
+ /** @type {Buffer[]} */
275
276
  const buffers = [remaining];
276
277
  for (let i = contentsIndex + 1; i < contents.length; i++) {
277
278
  const l = contents[i].length;
package/lib/util/fs.js CHANGED
@@ -65,7 +65,7 @@ const path = require("path");
65
65
 
66
66
  /** @typedef {string | number | boolean | null} JsonPrimitive */
67
67
  /** @typedef {JsonValue[]} JsonArray */
68
- /** @typedef {{[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined}} JsonObject */
68
+ /** @typedef {{ [Key in string]?: JsonValue }} JsonObject */
69
69
  /** @typedef {JsonPrimitive | JsonObject | JsonArray} JsonValue */
70
70
 
71
71
  /** @typedef {(err: NodeJS.ErrnoException | null) => void} NoParamCallback */
@@ -43,7 +43,7 @@ const WebAssemblyUtils = require("./WebAssemblyUtils");
43
43
  /**
44
44
  * @template T
45
45
  * @param {((prev: ArrayBuffer) => ArrayBuffer)[]} fns transforms
46
- * @returns {ArrayBufferTransform} composed transform
46
+ * @returns {(buf: ArrayBuffer) => ArrayBuffer} composed transform
47
47
  */
48
48
  const compose = (...fns) =>
49
49
  fns.reduce(
@@ -514,8 +514,7 @@ class WebAssemblyGenerator extends Generator {
514
514
  })
515
515
  );
516
516
 
517
- const newBin = transform(bin);
518
-
517
+ const newBin = transform(/** @type {ArrayBuffer} */ (bin.buffer));
519
518
  const newBuf = Buffer.from(newBin);
520
519
 
521
520
  return new RawSource(newBuf);