webpack 5.34.0 → 5.36.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

@@ -35,6 +35,7 @@ class FlagDependencyExportsPlugin {
35
35
  "webpack.FlagDependencyExportsPlugin"
36
36
  );
37
37
  let statRestoredFromCache = 0;
38
+ let statNoExports = 0;
38
39
  let statFlaggedUncached = 0;
39
40
  let statNotCached = 0;
40
41
  let statQueueItemsProcessed = 0;
@@ -47,6 +48,16 @@ class FlagDependencyExportsPlugin {
47
48
  asyncLib.each(
48
49
  modules,
49
50
  (module, callback) => {
51
+ const exportsInfo = moduleGraph.getExportsInfo(module);
52
+ if (!module.buildMeta || !module.buildMeta.exportsType) {
53
+ if (exportsInfo.otherExportsInfo.provided !== null) {
54
+ // It's a module without declared exports
55
+ statNoExports++;
56
+ exportsInfo.setHasProvideInfo();
57
+ exportsInfo.setUnknownExportsProvided();
58
+ return callback();
59
+ }
60
+ }
50
61
  if (
51
62
  module.buildInfo.cacheable !== true ||
52
63
  typeof module.buildInfo.hash !== "string"
@@ -54,7 +65,7 @@ class FlagDependencyExportsPlugin {
54
65
  statFlaggedUncached++;
55
66
  // Enqueue uncacheable module for determining the exports
56
67
  queue.enqueue(module);
57
- moduleGraph.getExportsInfo(module).setHasProvideInfo();
68
+ exportsInfo.setHasProvideInfo();
58
69
  return callback();
59
70
  }
60
71
  cache.get(
@@ -72,7 +83,7 @@ class FlagDependencyExportsPlugin {
72
83
  statNotCached++;
73
84
  // Without cached info enqueue module for determining the exports
74
85
  queue.enqueue(module);
75
- moduleGraph.getExportsInfo(module).setHasProvideInfo();
86
+ exportsInfo.setHasProvideInfo();
76
87
  }
77
88
  callback();
78
89
  }
@@ -300,49 +311,39 @@ class FlagDependencyExportsPlugin {
300
311
  statQueueItemsProcessed++;
301
312
 
302
313
  exportsInfo = moduleGraph.getExportsInfo(module);
303
- if (!module.buildMeta || !module.buildMeta.exportsType) {
304
- if (exportsInfo.otherExportsInfo.provided !== null) {
305
- // It's a module without declared exports
306
- exportsInfo.setUnknownExportsProvided();
307
- modulesToStore.add(module);
308
- notifyDependencies();
309
- }
310
- } else {
311
- // It's a module with declared exports
312
-
313
- cacheable = true;
314
- changed = false;
315
-
316
- exportsSpecsFromDependencies.clear();
317
- moduleGraph.freeze();
318
- processDependenciesBlock(module);
319
- moduleGraph.unfreeze();
320
- for (const [
321
- dep,
322
- exportsSpec
323
- ] of exportsSpecsFromDependencies) {
324
- processExportsSpec(dep, exportsSpec);
325
- }
326
314
 
327
- if (cacheable) {
328
- modulesToStore.add(module);
329
- }
315
+ cacheable = true;
316
+ changed = false;
317
+
318
+ exportsSpecsFromDependencies.clear();
319
+ moduleGraph.freeze();
320
+ processDependenciesBlock(module);
321
+ moduleGraph.unfreeze();
322
+ for (const [
323
+ dep,
324
+ exportsSpec
325
+ ] of exportsSpecsFromDependencies) {
326
+ processExportsSpec(dep, exportsSpec);
327
+ }
330
328
 
331
- if (changed) {
332
- notifyDependencies();
333
- }
329
+ if (cacheable) {
330
+ modulesToStore.add(module);
331
+ }
332
+
333
+ if (changed) {
334
+ notifyDependencies();
334
335
  }
335
336
  }
336
337
  logger.timeEnd("figure out provided exports");
337
338
 
338
339
  logger.log(
339
340
  `${Math.round(
340
- 100 -
341
- (100 * statRestoredFromCache) /
342
- (statRestoredFromCache +
343
- statNotCached +
344
- statFlaggedUncached)
345
- )}% of exports of modules have been determined (${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${
341
+ (100 * (statFlaggedUncached + statNotCached)) /
342
+ (statRestoredFromCache +
343
+ statNotCached +
344
+ statFlaggedUncached +
345
+ statNoExports)
346
+ )}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${
346
347
  statQueueItemsProcessed -
347
348
  statNotCached -
348
349
  statFlaggedUncached
@@ -73,13 +73,25 @@ class InitFragment {
73
73
  // Deduplicate fragments. If a fragment has no key, it is always included.
74
74
  const keyedFragments = new Map();
75
75
  for (const [fragment] of sortedFragments) {
76
- if (typeof fragment.merge === "function") {
76
+ if (typeof fragment.mergeAll === "function") {
77
+ if (!fragment.key) {
78
+ throw new Error(
79
+ `InitFragment with mergeAll function must have a valid key: ${fragment.constructor.name}`
80
+ );
81
+ }
82
+ const oldValue = keyedFragments.get(fragment.key);
83
+ if (oldValue === undefined) {
84
+ keyedFragments.set(fragment.key, fragment);
85
+ } else if (Array.isArray(oldValue)) {
86
+ oldValue.push(fragment);
87
+ } else {
88
+ keyedFragments.set(fragment.key, [oldValue, fragment]);
89
+ }
90
+ continue;
91
+ } else if (typeof fragment.merge === "function") {
77
92
  const oldValue = keyedFragments.get(fragment.key);
78
93
  if (oldValue !== undefined) {
79
- keyedFragments.set(
80
- fragment.key || Symbol(),
81
- fragment.merge(oldValue)
82
- );
94
+ keyedFragments.set(fragment.key, fragment.merge(oldValue));
83
95
  continue;
84
96
  }
85
97
  }
@@ -88,7 +100,10 @@ class InitFragment {
88
100
 
89
101
  const concatSource = new ConcatSource();
90
102
  const endContents = [];
91
- for (const fragment of keyedFragments.values()) {
103
+ for (let fragment of keyedFragments.values()) {
104
+ if (Array.isArray(fragment)) {
105
+ fragment = fragment[0].mergeAll(fragment);
106
+ }
92
107
  concatSource.add(fragment.getContent(generateContext));
93
108
  const endContent = fragment.getEndContent(generateContext);
94
109
  if (endContent) {
@@ -25,7 +25,7 @@ const WeakTupleMap = require("./util/WeakTupleMap");
25
25
  * @returns {string}
26
26
  */
27
27
 
28
- const EMPTY_ARRAY = [];
28
+ const EMPTY_SET = new Set();
29
29
 
30
30
  /**
31
31
  * @param {SortableSet<ModuleGraphConnection>} set input
@@ -82,20 +82,9 @@ class ModuleGraphModule {
82
82
  }
83
83
  }
84
84
 
85
- class ModuleGraphDependency {
86
- constructor() {
87
- /** @type {ModuleGraphConnection} */
88
- this.connection = undefined;
89
- /** @type {Module} */
90
- this.parentModule = undefined;
91
- /** @type {DependenciesBlock} */
92
- this.parentBlock = undefined;
93
- }
94
- }
95
-
96
85
  class ModuleGraph {
97
86
  constructor() {
98
- /** @type {Map<Dependency, ModuleGraphDependency>} */
87
+ /** @type {Map<Dependency, ModuleGraphConnection>} */
99
88
  this._dependencyMap = new Map();
100
89
  /** @type {Map<Module, ModuleGraphModule>} */
101
90
  this._moduleMap = new Map();
@@ -137,23 +126,6 @@ class ModuleGraph {
137
126
  return mgm;
138
127
  }
139
128
 
140
- /**
141
- * @param {Dependency} dependency the dependency
142
- * @returns {ModuleGraphDependency} the internal dependency
143
- */
144
- _getModuleGraphDependency(dependency) {
145
- if (this._cacheModuleGraphDependencyKey === dependency)
146
- return this._cacheModuleGraphDependencyValue;
147
- let mgd = this._dependencyMap.get(dependency);
148
- if (mgd === undefined) {
149
- mgd = new ModuleGraphDependency();
150
- this._dependencyMap.set(dependency, mgd);
151
- }
152
- this._cacheModuleGraphDependencyKey = dependency;
153
- this._cacheModuleGraphDependencyValue = mgd;
154
- return mgd;
155
- }
156
-
157
129
  /**
158
130
  * @param {Dependency} dependency the dependency
159
131
  * @param {DependenciesBlock} block parent block
@@ -161,9 +133,8 @@ class ModuleGraph {
161
133
  * @returns {void}
162
134
  */
163
135
  setParents(dependency, block, module) {
164
- const mgd = this._getModuleGraphDependency(dependency);
165
- mgd.parentBlock = block;
166
- mgd.parentModule = module;
136
+ dependency._parentDependenciesBlock = block;
137
+ dependency._parentModule = module;
167
138
  }
168
139
 
169
140
  /**
@@ -171,8 +142,7 @@ class ModuleGraph {
171
142
  * @returns {Module} parent module
172
143
  */
173
144
  getParentModule(dependency) {
174
- const mgd = this._getModuleGraphDependency(dependency);
175
- return mgd.parentModule;
145
+ return dependency._parentModule;
176
146
  }
177
147
 
178
148
  /**
@@ -180,8 +150,7 @@ class ModuleGraph {
180
150
  * @returns {DependenciesBlock} parent block
181
151
  */
182
152
  getParentBlock(dependency) {
183
- const mgd = this._getModuleGraphDependency(dependency);
184
- return mgd.parentBlock;
153
+ return dependency._parentDependenciesBlock;
185
154
  }
186
155
 
187
156
  /**
@@ -199,8 +168,7 @@ class ModuleGraph {
199
168
  dependency.weak,
200
169
  dependency.getCondition(this)
201
170
  );
202
- const mgd = this._getModuleGraphDependency(dependency);
203
- mgd.connection = connection;
171
+ this._dependencyMap.set(dependency, connection);
204
172
  const connections = this._getModuleGraphModule(module).incomingConnections;
205
173
  connections.add(connection);
206
174
  const mgm = this._getModuleGraphModule(originModule);
@@ -216,12 +184,11 @@ class ModuleGraph {
216
184
  * @returns {void}
217
185
  */
218
186
  updateModule(dependency, module) {
219
- const mgd = this._getModuleGraphDependency(dependency);
220
- if (mgd.connection.module === module) return;
221
- const { connection } = mgd;
187
+ const connection = this._dependencyMap.get(dependency);
188
+ if (connection.module === module) return;
222
189
  const newConnection = connection.clone();
223
190
  newConnection.module = module;
224
- mgd.connection = newConnection;
191
+ this._dependencyMap.set(dependency, newConnection);
225
192
  connection.setActive(false);
226
193
  const originMgm = this._getModuleGraphModule(connection.originModule);
227
194
  originMgm.outgoingConnections.add(newConnection);
@@ -234,13 +201,12 @@ class ModuleGraph {
234
201
  * @returns {void}
235
202
  */
236
203
  removeConnection(dependency) {
237
- const mgd = this._getModuleGraphDependency(dependency);
238
- const { connection } = mgd;
204
+ const connection = this._dependencyMap.get(dependency);
239
205
  const targetMgm = this._getModuleGraphModule(connection.module);
240
206
  targetMgm.incomingConnections.delete(connection);
241
207
  const originMgm = this._getModuleGraphModule(connection.originModule);
242
208
  originMgm.outgoingConnections.delete(connection);
243
- mgd.connection = undefined;
209
+ this._dependencyMap.delete(dependency);
244
210
  }
245
211
 
246
212
  /**
@@ -249,7 +215,7 @@ class ModuleGraph {
249
215
  * @returns {void}
250
216
  */
251
217
  addExplanation(dependency, explanation) {
252
- const { connection } = this._getModuleGraphDependency(dependency);
218
+ const connection = this._dependencyMap.get(dependency);
253
219
  connection.addExplanation(explanation);
254
220
  }
255
221
 
@@ -375,7 +341,7 @@ class ModuleGraph {
375
341
  * @returns {Module} the referenced module
376
342
  */
377
343
  getResolvedModule(dependency) {
378
- const { connection } = this._getModuleGraphDependency(dependency);
344
+ const connection = this._dependencyMap.get(dependency);
379
345
  return connection !== undefined ? connection.resolvedModule : null;
380
346
  }
381
347
 
@@ -384,7 +350,7 @@ class ModuleGraph {
384
350
  * @returns {ModuleGraphConnection | undefined} the connection
385
351
  */
386
352
  getConnection(dependency) {
387
- const { connection } = this._getModuleGraphDependency(dependency);
353
+ const connection = this._dependencyMap.get(dependency);
388
354
  return connection;
389
355
  }
390
356
 
@@ -393,7 +359,7 @@ class ModuleGraph {
393
359
  * @returns {Module} the referenced module
394
360
  */
395
361
  getModule(dependency) {
396
- const { connection } = this._getModuleGraphDependency(dependency);
362
+ const connection = this._dependencyMap.get(dependency);
397
363
  return connection !== undefined ? connection.module : null;
398
364
  }
399
365
 
@@ -402,7 +368,7 @@ class ModuleGraph {
402
368
  * @returns {Module} the referencing module
403
369
  */
404
370
  getOrigin(dependency) {
405
- const { connection } = this._getModuleGraphDependency(dependency);
371
+ const connection = this._dependencyMap.get(dependency);
406
372
  return connection !== undefined ? connection.originModule : null;
407
373
  }
408
374
 
@@ -411,7 +377,7 @@ class ModuleGraph {
411
377
  * @returns {Module} the original referencing module
412
378
  */
413
379
  getResolvedOrigin(dependency) {
414
- const { connection } = this._getModuleGraphDependency(dependency);
380
+ const connection = this._dependencyMap.get(dependency);
415
381
  return connection !== undefined ? connection.resolvedOriginModule : null;
416
382
  }
417
383
 
@@ -430,7 +396,7 @@ class ModuleGraph {
430
396
  */
431
397
  getOutgoingConnections(module) {
432
398
  const connections = this._getModuleGraphModule(module).outgoingConnections;
433
- return connections === undefined ? EMPTY_ARRAY : connections;
399
+ return connections === undefined ? EMPTY_SET : connections;
434
400
  }
435
401
 
436
402
  /**
@@ -568,7 +568,9 @@ class WebpackOptionsApply extends OptionsApply {
568
568
  "webpack.cache.PackFileCacheStrategy"
569
569
  ),
570
570
  snapshot: options.snapshot,
571
- maxAge: cacheOptions.maxAge
571
+ maxAge: cacheOptions.maxAge,
572
+ profile: cacheOptions.profile,
573
+ allowCollectingMemory: cacheOptions.allowCollectingMemory
572
574
  }),
573
575
  cacheOptions.idleTimeout,
574
576
  cacheOptions.idleTimeoutForInitialStore
@@ -561,7 +561,40 @@ class PackContentItems {
561
561
  this.map = map;
562
562
  }
563
563
 
564
- serialize({ write, snapshot, rollback, logger }) {
564
+ serialize({ write, snapshot, rollback, logger, profile }) {
565
+ if (profile) {
566
+ write(false);
567
+ for (const [key, value] of this.map) {
568
+ const s = snapshot();
569
+ try {
570
+ write(key);
571
+ const start = process.hrtime();
572
+ write(value);
573
+ const durationHr = process.hrtime(start);
574
+ const duration = durationHr[0] * 1000 + durationHr[1] / 1e6;
575
+ if (duration > 1) {
576
+ if (duration > 500)
577
+ logger.error(`Serialization of '${key}': ${duration} ms`);
578
+ else if (duration > 50)
579
+ logger.warn(`Serialization of '${key}': ${duration} ms`);
580
+ else if (duration > 10)
581
+ logger.info(`Serialization of '${key}': ${duration} ms`);
582
+ else if (duration > 5)
583
+ logger.log(`Serialization of '${key}': ${duration} ms`);
584
+ else logger.debug(`Serialization of '${key}': ${duration} ms`);
585
+ }
586
+ } catch (e) {
587
+ rollback(s);
588
+ if (e === NOT_SERIALIZABLE) continue;
589
+ logger.warn(
590
+ `Skipped not serializable cache item '${key}': ${e.message}`
591
+ );
592
+ logger.debug(e.stack);
593
+ }
594
+ }
595
+ write(null);
596
+ return;
597
+ }
565
598
  // Try to serialize all at once
566
599
  const s = snapshot();
567
600
  try {
@@ -590,9 +623,32 @@ class PackContentItems {
590
623
  }
591
624
  }
592
625
 
593
- deserialize({ read }) {
626
+ deserialize({ read, logger, profile }) {
594
627
  if (read()) {
595
628
  this.map = read();
629
+ } else if (profile) {
630
+ const map = new Map();
631
+ let key = read();
632
+ while (key !== null) {
633
+ const start = process.hrtime();
634
+ const value = read();
635
+ const durationHr = process.hrtime(start);
636
+ const duration = durationHr[0] * 1000 + durationHr[1] / 1e6;
637
+ if (duration > 1) {
638
+ if (duration > 100)
639
+ logger.error(`Deserialization of '${key}': ${duration} ms`);
640
+ else if (duration > 20)
641
+ logger.warn(`Deserialization of '${key}': ${duration} ms`);
642
+ else if (duration > 5)
643
+ logger.info(`Deserialization of '${key}': ${duration} ms`);
644
+ else if (duration > 2)
645
+ logger.log(`Deserialization of '${key}': ${duration} ms`);
646
+ else logger.debug(`Deserialization of '${key}': ${duration} ms`);
647
+ }
648
+ map.set(key, value);
649
+ key = read();
650
+ }
651
+ this.map = map;
596
652
  } else {
597
653
  const map = new Map();
598
654
  let key = read();
@@ -768,6 +824,14 @@ class PackContent {
768
824
  }
769
825
  }
770
826
 
827
+ const allowCollectingMemory = buf => {
828
+ const wasted = buf.buffer.byteLength - buf.byteLength;
829
+ if (wasted > 8192 && (wasted > 1048576 || wasted > buf.byteLength)) {
830
+ return Buffer.from(buf);
831
+ }
832
+ return buf;
833
+ };
834
+
771
835
  class PackFileCacheStrategy {
772
836
  /**
773
837
  * @param {Object} options options
@@ -779,6 +843,8 @@ class PackFileCacheStrategy {
779
843
  * @param {Logger} options.logger a logger
780
844
  * @param {SnapshotOptions} options.snapshot options regarding snapshotting
781
845
  * @param {number} options.maxAge max age of cache items
846
+ * @param {boolean} options.profile track and log detailed timing information for individual cache items
847
+ * @param {boolean} options.allowCollectingMemory allow to collect unused memory created during deserialization
782
848
  */
783
849
  constructor({
784
850
  compiler,
@@ -788,7 +854,9 @@ class PackFileCacheStrategy {
788
854
  version,
789
855
  logger,
790
856
  snapshot,
791
- maxAge
857
+ maxAge,
858
+ profile,
859
+ allowCollectingMemory
792
860
  }) {
793
861
  this.fileSerializer = createFileSerializer(fs);
794
862
  this.fileSystemInfo = new FileSystemInfo(fs, {
@@ -802,6 +870,8 @@ class PackFileCacheStrategy {
802
870
  this.version = version;
803
871
  this.logger = logger;
804
872
  this.maxAge = maxAge;
873
+ this.profile = profile;
874
+ this.allowCollectingMemory = allowCollectingMemory;
805
875
  this.snapshot = snapshot;
806
876
  /** @type {Set<string>} */
807
877
  this.buildDependencies = new Set();
@@ -829,7 +899,7 @@ class PackFileCacheStrategy {
829
899
  * @returns {Promise<Pack>} the pack
830
900
  */
831
901
  _openPack() {
832
- const { logger, cacheLocation, version } = this;
902
+ const { logger, profile, cacheLocation, version } = this;
833
903
  /** @type {Snapshot} */
834
904
  let buildSnapshot;
835
905
  /** @type {Set<string>} */
@@ -845,7 +915,11 @@ class PackFileCacheStrategy {
845
915
  .deserialize(null, {
846
916
  filename: `${cacheLocation}/index.pack`,
847
917
  extension: ".pack",
848
- logger
918
+ logger,
919
+ profile,
920
+ retainedBuffer: this.allowCollectingMemory
921
+ ? allowCollectingMemory
922
+ : undefined
849
923
  })
850
924
  .catch(err => {
851
925
  if (err.code !== "ENOENT") {
@@ -1158,7 +1232,8 @@ class PackFileCacheStrategy {
1158
1232
  .serialize(content, {
1159
1233
  filename: `${this.cacheLocation}/index.pack`,
1160
1234
  extension: ".pack",
1161
- logger: this.logger
1235
+ logger: this.logger,
1236
+ profile: this.profile
1162
1237
  })
1163
1238
  .then(() => {
1164
1239
  for (const dep of newBuildDependencies) {
@@ -293,10 +293,12 @@ const applyCacheDefaults = (cache, { name, mode, development }) => {
293
293
  );
294
294
  D(cache, "hashAlgorithm", "md4");
295
295
  D(cache, "store", "pack");
296
+ D(cache, "profile", false);
296
297
  D(cache, "idleTimeout", 60000);
297
298
  D(cache, "idleTimeoutForInitialStore", 0);
298
- D(cache, "maxMemoryGenerations", development ? 10 : Infinity);
299
+ D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
299
300
  D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
301
+ D(cache, "allowCollectingMemory", development);
300
302
  D(cache.buildDependencies, "defaultWebpack", [
301
303
  path.resolve(__dirname, "..") + path.sep
302
304
  ]);
@@ -947,7 +949,7 @@ const applyOptimizationDefaults = (
947
949
  A(splitChunks, "defaultSizeTypes", () => ["javascript", "unknown"]);
948
950
  D(splitChunks, "hidePathInfo", production);
949
951
  D(splitChunks, "chunks", "async");
950
- D(splitChunks, "usedExports", true);
952
+ D(splitChunks, "usedExports", optimization.usedExports === true);
951
953
  D(splitChunks, "minChunks", 1);
952
954
  F(splitChunks, "minSize", () => (production ? 20000 : 10000));
953
955
  F(splitChunks, "minRemainingSize", () => (development ? 0 : undefined));
@@ -131,6 +131,7 @@ const getNormalizedWebpackOptions = config => {
131
131
  type: "filesystem",
132
132
  maxMemoryGenerations: cache.maxMemoryGenerations,
133
133
  maxAge: cache.maxAge,
134
+ profile: cache.profile,
134
135
  buildDependencies: cloneObject(cache.buildDependencies),
135
136
  cacheDirectory: cache.cacheDirectory,
136
137
  cacheLocation: cache.cacheLocation,
@@ -48,6 +48,53 @@ class HarmonyExportInitFragment extends InitFragment {
48
48
  this.unusedExports = unusedExports;
49
49
  }
50
50
 
51
+ /**
52
+ * @param {HarmonyExportInitFragment[]} fragments all fragments to merge
53
+ * @returns {HarmonyExportInitFragment} merged fragment
54
+ */
55
+ mergeAll(fragments) {
56
+ let exportMap;
57
+ let exportMapOwned = false;
58
+ let unusedExports;
59
+ let unusedExportsOwned = false;
60
+
61
+ for (const fragment of fragments) {
62
+ if (fragment.exportMap.size !== 0) {
63
+ if (exportMap === undefined) {
64
+ exportMap = fragment.exportMap;
65
+ exportMapOwned = false;
66
+ } else {
67
+ if (!exportMapOwned) {
68
+ exportMap = new Map(exportMap);
69
+ exportMapOwned = true;
70
+ }
71
+ for (const [key, value] of fragment.exportMap) {
72
+ if (!exportMap.has(key)) exportMap.set(key, value);
73
+ }
74
+ }
75
+ }
76
+ if (fragment.unusedExports.size !== 0) {
77
+ if (unusedExports === undefined) {
78
+ unusedExports = fragment.unusedExports;
79
+ unusedExportsOwned = false;
80
+ } else {
81
+ if (!unusedExportsOwned) {
82
+ unusedExports = new Set(unusedExports);
83
+ unusedExportsOwned = true;
84
+ }
85
+ for (const value of fragment.unusedExports) {
86
+ unusedExports.add(value);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ return new HarmonyExportInitFragment(
92
+ this.exportsArgument,
93
+ exportMap,
94
+ unusedExports
95
+ );
96
+ }
97
+
51
98
  merge(other) {
52
99
  let exportMap;
53
100
  if (this.exportMap.size === 0) {
@@ -19,14 +19,6 @@ class NullDependency extends Dependency {
19
19
  get type() {
20
20
  return "null";
21
21
  }
22
-
23
- serialize({ write }) {
24
- write(this.loc);
25
- }
26
-
27
- deserialize({ read }) {
28
- this.loc = read();
29
- }
30
22
  }
31
23
 
32
24
  NullDependency.Template = class NullDependencyTemplate extends (
@@ -124,6 +124,13 @@ class ArrayPushCallbackChunkFormatPlugin {
124
124
  }
125
125
  )
126
126
  );
127
+ if (
128
+ chunkGraph
129
+ .getChunkRuntimeRequirements(chunk)
130
+ .has(RuntimeGlobals.returnExportsFromRuntime)
131
+ ) {
132
+ runtime.add("return __webpack_exports__;\n");
133
+ }
127
134
  }
128
135
  runtime.add("}\n");
129
136
  source.add(",\n");
@@ -625,8 +625,9 @@ class JavascriptModulesPlugin {
625
625
  ) || []
626
626
  );
627
627
 
628
+ const hasEntryModules = chunkGraph.getNumberOfEntryModules(chunk) > 0;
628
629
  let inlinedModules;
629
- if (bootstrap.allowInlineStartup) {
630
+ if (bootstrap.allowInlineStartup && hasEntryModules) {
630
631
  inlinedModules = new Set(chunkGraph.getChunkEntryModulesIterable(chunk));
631
632
  }
632
633
 
@@ -836,7 +837,10 @@ class JavascriptModulesPlugin {
836
837
  )
837
838
  );
838
839
  }
839
- if (runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime)) {
840
+ if (
841
+ hasEntryModules &&
842
+ runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime)
843
+ ) {
840
844
  source.add(`${prefix}return __webpack_exports__;\n`);
841
845
  }
842
846
  if (iife) {