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

@@ -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
  /**
@@ -520,29 +520,33 @@ class NormalModuleFactory extends ModuleFactory {
520
520
  )
521
521
  );
522
522
  }
523
- Object.assign(data.createData, {
524
- layer:
525
- layer === undefined ? contextInfo.issuerLayer || null : layer,
526
- request: stringifyLoadersAndResource(
527
- allLoaders,
528
- resourceData.resource
529
- ),
530
- userRequest,
531
- rawRequest: request,
532
- loaders: allLoaders,
533
- resource: resourceData.resource,
534
- matchResource: matchResourceData
535
- ? matchResourceData.resource
536
- : undefined,
537
- resourceResolveData: resourceData.data,
538
- settings,
539
- type,
540
- parser: this.getParser(type, settings.parser),
541
- parserOptions: settings.parser,
542
- generator: this.getGenerator(type, settings.generator),
543
- generatorOptions: settings.generator,
544
- resolveOptions
545
- });
523
+ try {
524
+ Object.assign(data.createData, {
525
+ layer:
526
+ layer === undefined ? contextInfo.issuerLayer || null : layer,
527
+ request: stringifyLoadersAndResource(
528
+ allLoaders,
529
+ resourceData.resource
530
+ ),
531
+ userRequest,
532
+ rawRequest: request,
533
+ loaders: allLoaders,
534
+ resource: resourceData.resource,
535
+ matchResource: matchResourceData
536
+ ? matchResourceData.resource
537
+ : undefined,
538
+ resourceResolveData: resourceData.data,
539
+ settings,
540
+ type,
541
+ parser: this.getParser(type, settings.parser),
542
+ parserOptions: settings.parser,
543
+ generator: this.getGenerator(type, settings.generator),
544
+ generatorOptions: settings.generator,
545
+ resolveOptions
546
+ });
547
+ } catch (e) {
548
+ return callback(e);
549
+ }
546
550
  callback();
547
551
  });
548
552
  this.resolveRequestArray(
@@ -569,6 +569,7 @@ class WebpackOptionsApply extends OptionsApply {
569
569
  ),
570
570
  snapshot: options.snapshot,
571
571
  maxAge: cacheOptions.maxAge,
572
+ profile: cacheOptions.profile,
572
573
  allowCollectingMemory: cacheOptions.allowCollectingMemory
573
574
  }),
574
575
  cacheOptions.idleTimeout,
@@ -997,10 +997,15 @@ const visitModules = (
997
997
  };
998
998
 
999
999
  const processChunkGroupsForCombining = () => {
1000
- loop: for (const info of chunkGroupsForCombining) {
1000
+ for (const info of chunkGroupsForCombining) {
1001
1001
  for (const source of info.availableSources) {
1002
- if (!source.minAvailableModules) continue loop;
1002
+ if (!source.minAvailableModules) {
1003
+ chunkGroupsForCombining.delete(info);
1004
+ break;
1005
+ }
1003
1006
  }
1007
+ }
1008
+ for (const info of chunkGroupsForCombining) {
1004
1009
  const availableModules = /** @type {ModuleSetPlus} */ (new Set());
1005
1010
  availableModules.plus = EMPTY_SET;
1006
1011
  const mergeSet = set => {
@@ -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();
@@ -787,6 +843,7 @@ class PackFileCacheStrategy {
787
843
  * @param {Logger} options.logger a logger
788
844
  * @param {SnapshotOptions} options.snapshot options regarding snapshotting
789
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
790
847
  * @param {boolean} options.allowCollectingMemory allow to collect unused memory created during deserialization
791
848
  */
792
849
  constructor({
@@ -798,6 +855,7 @@ class PackFileCacheStrategy {
798
855
  logger,
799
856
  snapshot,
800
857
  maxAge,
858
+ profile,
801
859
  allowCollectingMemory
802
860
  }) {
803
861
  this.fileSerializer = createFileSerializer(fs);
@@ -812,6 +870,7 @@ class PackFileCacheStrategy {
812
870
  this.version = version;
813
871
  this.logger = logger;
814
872
  this.maxAge = maxAge;
873
+ this.profile = profile;
815
874
  this.allowCollectingMemory = allowCollectingMemory;
816
875
  this.snapshot = snapshot;
817
876
  /** @type {Set<string>} */
@@ -840,7 +899,7 @@ class PackFileCacheStrategy {
840
899
  * @returns {Promise<Pack>} the pack
841
900
  */
842
901
  _openPack() {
843
- const { logger, cacheLocation, version } = this;
902
+ const { logger, profile, cacheLocation, version } = this;
844
903
  /** @type {Snapshot} */
845
904
  let buildSnapshot;
846
905
  /** @type {Set<string>} */
@@ -857,6 +916,7 @@ class PackFileCacheStrategy {
857
916
  filename: `${cacheLocation}/index.pack`,
858
917
  extension: ".pack",
859
918
  logger,
919
+ profile,
860
920
  retainedBuffer: this.allowCollectingMemory
861
921
  ? allowCollectingMemory
862
922
  : undefined
@@ -1172,7 +1232,8 @@ class PackFileCacheStrategy {
1172
1232
  .serialize(content, {
1173
1233
  filename: `${this.cacheLocation}/index.pack`,
1174
1234
  extension: ".pack",
1175
- logger: this.logger
1235
+ logger: this.logger,
1236
+ profile: this.profile
1176
1237
  })
1177
1238
  .then(() => {
1178
1239
  for (const dep of newBuildDependencies) {
@@ -293,6 +293,7 @@ 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
299
  D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
@@ -948,7 +949,7 @@ const applyOptimizationDefaults = (
948
949
  A(splitChunks, "defaultSizeTypes", () => ["javascript", "unknown"]);
949
950
  D(splitChunks, "hidePathInfo", production);
950
951
  D(splitChunks, "chunks", "async");
951
- D(splitChunks, "usedExports", true);
952
+ D(splitChunks, "usedExports", optimization.usedExports === true);
952
953
  D(splitChunks, "minChunks", 1);
953
954
  F(splitChunks, "minSize", () => (production ? 20000 : 10000));
954
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 (
@@ -9,9 +9,9 @@ const { pathToFileURL } = require("url");
9
9
  const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
10
10
  const CommentCompilationWarning = require("../CommentCompilationWarning");
11
11
  const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
12
- const formatLocation = require("../formatLocation");
13
12
  const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
14
13
  const { equals } = require("../util/ArrayHelpers");
14
+ const createHash = require("../util/createHash");
15
15
  const { contextify } = require("../util/identifier");
16
16
  const EnableWasmLoadingPlugin = require("../wasm/EnableWasmLoadingPlugin");
17
17
  const ConstDependency = require("./ConstDependency");
@@ -27,6 +27,7 @@ const WorkerDependency = require("./WorkerDependency");
27
27
  /** @typedef {import("estree").SpreadElement} SpreadElement */
28
28
  /** @typedef {import("../Compiler")} Compiler */
29
29
  /** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
30
+ /** @typedef {import("../Parser").ParserState} ParserState */
30
31
  /** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
31
32
  /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
32
33
  /** @typedef {import("./HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
@@ -42,6 +43,9 @@ const DEFAULT_SYNTAX = [
42
43
  "Worker from worker_threads"
43
44
  ];
44
45
 
46
+ /** @type {WeakMap<ParserState, number>} */
47
+ const workerIndexMap = new WeakMap();
48
+
45
49
  class WorkerPlugin {
46
50
  constructor(chunkLoading, wasmLoading) {
47
51
  this._chunkLoading = chunkLoading;
@@ -264,9 +268,20 @@ class WorkerPlugin {
264
268
  }
265
269
 
266
270
  if (!entryOptions.runtime) {
267
- entryOptions.runtime = `${cachedContextify(
271
+ let i = workerIndexMap.get(parser.state) || 0;
272
+ workerIndexMap.set(parser.state, i + 1);
273
+ let name = `${cachedContextify(
268
274
  parser.state.module.identifier()
269
- )}|${formatLocation(expr.loc)}`;
275
+ )}|${i}`;
276
+ const hash = createHash(compilation.outputOptions.hashFunction);
277
+ hash.update(name);
278
+ const digest = /** @type {string} */ (hash.digest(
279
+ compilation.outputOptions.hashDigest
280
+ ));
281
+ entryOptions.runtime = digest.slice(
282
+ 0,
283
+ compilation.outputOptions.hashDigestLength
284
+ );
270
285
  }
271
286
 
272
287
  const block = new AsyncDependenciesBlock({
@@ -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) {