webpack 5.1.2 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (42) hide show
  1. package/lib/ChunkGraph.js +19 -0
  2. package/lib/Compilation.js +37 -9
  3. package/lib/Compiler.js +26 -2
  4. package/lib/ConditionalInitFragment.js +109 -0
  5. package/lib/ContextModule.js +1 -1
  6. package/lib/DelegatedModule.js +1 -1
  7. package/lib/Dependency.js +1 -0
  8. package/lib/ExportsInfo.js +62 -16
  9. package/lib/ExternalModule.js +7 -6
  10. package/lib/FlagDependencyUsagePlugin.js +38 -42
  11. package/lib/Module.js +8 -0
  12. package/lib/NormalModule.js +26 -20
  13. package/lib/RawModule.js +1 -1
  14. package/lib/RuntimeGlobals.js +5 -0
  15. package/lib/RuntimeModule.js +4 -1
  16. package/lib/RuntimePlugin.js +8 -0
  17. package/lib/RuntimeTemplate.js +41 -0
  18. package/lib/SourceMapDevToolModuleOptionsPlugin.js +25 -0
  19. package/lib/SourceMapDevToolPlugin.js +6 -2
  20. package/lib/Template.js +1 -0
  21. package/lib/WebpackOptionsApply.js +3 -1
  22. package/lib/asset/AssetGenerator.js +10 -6
  23. package/lib/buildChunkGraph.js +111 -25
  24. package/lib/config/browserslistTargetHandler.js +4 -2
  25. package/lib/config/defaults.js +1 -1
  26. package/lib/container/ContainerEntryModule.js +4 -2
  27. package/lib/dependencies/HarmonyAcceptDependency.js +33 -5
  28. package/lib/dependencies/HarmonyImportDependency.js +70 -28
  29. package/lib/dependencies/HarmonyImportSpecifierDependency.js +2 -2
  30. package/lib/dependencies/PureExpressionDependency.js +30 -6
  31. package/lib/dependencies/WorkerPlugin.js +8 -3
  32. package/lib/javascript/JavascriptModulesPlugin.js +16 -10
  33. package/lib/optimize/ConcatenatedModule.js +87 -20
  34. package/lib/optimize/ModuleConcatenationPlugin.js +71 -6
  35. package/lib/optimize/SideEffectsFlagPlugin.js +112 -100
  36. package/lib/runtime/RuntimeIdRuntimeModule.js +29 -0
  37. package/lib/stats/DefaultStatsPrinterPlugin.js +17 -1
  38. package/lib/util/compileBooleanMatcher.js +13 -1
  39. package/lib/util/runtime.js +63 -1
  40. package/package.json +7 -7
  41. package/schemas/WebpackOptions.json +13 -2
  42. package/types.d.ts +63 -8
package/lib/ChunkGraph.js CHANGED
@@ -200,6 +200,8 @@ class ChunkGraph {
200
200
  this._chunks = new WeakMap();
201
201
  /** @private @type {WeakMap<AsyncDependenciesBlock, ChunkGroup>} */
202
202
  this._blockChunkGroups = new WeakMap();
203
+ /** @private @type {Map<string, string | number>} */
204
+ this._runtimeIds = new Map();
203
205
  /** @type {ModuleGraph} */
204
206
  this.moduleGraph = moduleGraph;
205
207
 
@@ -1144,6 +1146,23 @@ class ChunkGraph {
1144
1146
  cgm.id = id;
1145
1147
  }
1146
1148
 
1149
+ /**
1150
+ * @param {string} runtime runtime
1151
+ * @returns {string | number} the id of the runtime
1152
+ */
1153
+ getRuntimeId(runtime) {
1154
+ return this._runtimeIds.get(runtime);
1155
+ }
1156
+
1157
+ /**
1158
+ * @param {string} runtime runtime
1159
+ * @param {string | number} id the id of the runtime
1160
+ * @returns {void}
1161
+ */
1162
+ setRuntimeId(runtime, id) {
1163
+ this._runtimeIds.set(runtime, id);
1164
+ }
1165
+
1147
1166
  /**
1148
1167
  * @param {Module} module the module
1149
1168
  * @param {RuntimeSpec} runtime the runtime
@@ -179,9 +179,11 @@ const { getRuntimeKey } = require("./util/runtime");
179
179
  * @property {string | string[]=} chunkhash the value(s) of the chunk hash used for this asset
180
180
  * @property {string | string[]=} modulehash the value(s) of the module hash used for this asset
181
181
  * @property {string | string[]=} contenthash the value(s) of the content hash used for this asset
182
+ * @property {string=} sourceFilename when asset was created from a source file (potentially transformed), the original filename relative to compilation context
182
183
  * @property {number=} size size in bytes, only set after asset has been emitted
183
184
  * @property {boolean=} development true, when asset is only used for development and doesn't count towards user-facing assets
184
185
  * @property {boolean=} hotModuleReplacement true, when asset ships data for updating an existing application (HMR)
186
+ * @property {boolean=} javascriptModule true, when asset is javascript and an ESM
185
187
  * @property {Record<string, string | string[]>=} related object of pointers to other assets, keyed by type of relation (only points from parent to child)
186
188
  */
187
189
 
@@ -1937,6 +1939,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
1937
1939
  this.hooks.optimizeChunkIds.call(this.chunks);
1938
1940
  this.hooks.afterOptimizeChunkIds.call(this.chunks);
1939
1941
 
1942
+ this.assignRuntimeIds();
1943
+
1940
1944
  this.sortItemsWithChunkIds();
1941
1945
 
1942
1946
  if (shouldRecord) {
@@ -2554,6 +2558,21 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2554
2558
  }
2555
2559
  }
2556
2560
 
2561
+ assignRuntimeIds() {
2562
+ const { chunkGraph } = this;
2563
+ const processEntrypoint = ep => {
2564
+ const runtime = ep.options.runtime || ep.name;
2565
+ const chunk = ep.getRuntimeChunk();
2566
+ chunkGraph.setRuntimeId(runtime, chunk.id);
2567
+ };
2568
+ for (const ep of this.entrypoints.values()) {
2569
+ processEntrypoint(ep);
2570
+ }
2571
+ for (const ep of this.asyncEntrypoints) {
2572
+ processEntrypoint(ep);
2573
+ }
2574
+ }
2575
+
2557
2576
  sortItemsWithChunkIds() {
2558
2577
  for (const chunkGroup of this.chunkGroups) {
2559
2578
  chunkGroup.sortItems();
@@ -2590,7 +2609,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2590
2609
 
2591
2610
  createModuleHashes() {
2592
2611
  let statModulesHashed = 0;
2593
- const chunkGraph = this.chunkGraph;
2612
+ const { chunkGraph, runtimeTemplate } = this;
2594
2613
  const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
2595
2614
  for (const module of this.modules) {
2596
2615
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
@@ -2598,7 +2617,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2598
2617
  const moduleHash = createHash(hashFunction);
2599
2618
  module.updateHash(moduleHash, {
2600
2619
  chunkGraph,
2601
- runtime
2620
+ runtime,
2621
+ runtimeTemplate
2602
2622
  });
2603
2623
  const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2604
2624
  hashDigest
@@ -2621,6 +2641,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2621
2641
  createHash() {
2622
2642
  this.logger.time("hashing: initialize hash");
2623
2643
  const chunkGraph = this.chunkGraph;
2644
+ const runtimeTemplate = this.runtimeTemplate;
2624
2645
  const outputOptions = this.outputOptions;
2625
2646
  const hashFunction = outputOptions.hashFunction;
2626
2647
  const hashDigest = outputOptions.hashDigest;
@@ -2705,7 +2726,8 @@ This prevents using hashes of each other and should be avoided.`
2705
2726
  const moduleHash = createHash(hashFunction);
2706
2727
  module.updateHash(moduleHash, {
2707
2728
  chunkGraph,
2708
- runtime: chunk.runtime
2729
+ runtime: chunk.runtime,
2730
+ runtimeTemplate
2709
2731
  });
2710
2732
  const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2711
2733
  hashDigest
@@ -2767,7 +2789,8 @@ This prevents using hashes of each other and should be avoided.`
2767
2789
  const moduleHash = createHash(hashFunction);
2768
2790
  module.updateHash(moduleHash, {
2769
2791
  chunkGraph,
2770
- runtime: chunk.runtime
2792
+ runtime: chunk.runtime,
2793
+ runtimeTemplate
2771
2794
  });
2772
2795
  const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2773
2796
  hashDigest
@@ -3148,7 +3171,12 @@ This prevents using hashes of each other and should be avoided.`
3148
3171
  fileManifest.pathOptions
3149
3172
  );
3150
3173
  file = pathAndInfo.path;
3151
- assetInfo = pathAndInfo.info;
3174
+ assetInfo = fileManifest.info
3175
+ ? {
3176
+ ...pathAndInfo.info,
3177
+ ...fileManifest.info
3178
+ }
3179
+ : pathAndInfo.info;
3152
3180
  }
3153
3181
 
3154
3182
  if (err) {
@@ -3443,14 +3471,14 @@ Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE = 1000;
3443
3471
  Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING = 2000;
3444
3472
 
3445
3473
  /**
3446
- * Optimize the transfer of existing assets, e. g. by preparing a compressed (gzip) file as separate asset.
3474
+ * Optimize the hashes of the assets, e. g. by generating real hashes of the asset content.
3447
3475
  */
3448
- Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER = 3000;
3476
+ Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH = 2500;
3449
3477
 
3450
3478
  /**
3451
- * Optimize the hashes of the assets, e. g. by generating real hashes of the asset content.
3479
+ * Optimize the transfer of existing assets, e. g. by preparing a compressed (gzip) file as separate asset.
3452
3480
  */
3453
- Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH = 3500;
3481
+ Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER = 3000;
3454
3482
 
3455
3483
  /**
3456
3484
  * Analyse existing assets.
package/lib/Compiler.js CHANGED
@@ -97,6 +97,20 @@ const sortObject = (obj, keys) => {
97
97
  return o;
98
98
  };
99
99
 
100
+ /**
101
+ * @param {string} filename filename
102
+ * @param {string | string[] | undefined} hashes list of hashes
103
+ * @returns {boolean} true, if the filename contains any hash
104
+ */
105
+ const includesHash = (filename, hashes) => {
106
+ if (!hashes) return false;
107
+ if (Array.isArray(hashes)) {
108
+ return hashes.some(hash => filename.includes(hash));
109
+ } else {
110
+ return filename.includes(hashes);
111
+ }
112
+ };
113
+
100
114
  class Compiler {
101
115
  /**
102
116
  * @param {string} context the compilation path
@@ -522,9 +536,19 @@ class Compiler {
522
536
  15,
523
537
  ({ name: file, source, info }, callback) => {
524
538
  let targetFile = file;
539
+ let immutable = info.immutable;
525
540
  const queryStringIdx = targetFile.indexOf("?");
526
541
  if (queryStringIdx >= 0) {
527
542
  targetFile = targetFile.substr(0, queryStringIdx);
543
+ // We may remove the hash, which is in the query string
544
+ // So we recheck if the file is immutable
545
+ // This doesn't cover all cases, but immutable is only a performance optimization anyway
546
+ immutable =
547
+ immutable &&
548
+ (includesHash(targetFile, info.contenthash) ||
549
+ includesHash(targetFile, info.chunkhash) ||
550
+ includesHash(targetFile, info.modulehash) ||
551
+ includesHash(targetFile, info.fullhash));
528
552
  }
529
553
 
530
554
  const writeOut = err => {
@@ -639,7 +663,7 @@ ${other}`);
639
663
 
640
664
  const processExistingFile = stats => {
641
665
  // skip emitting if it's already there and an immutable file
642
- if (info.immutable) {
666
+ if (immutable) {
643
667
  updateWithReplacementSource(stats.size);
644
668
  return alreadyWritten();
645
669
  }
@@ -693,7 +717,7 @@ ${other}`);
693
717
  return callback();
694
718
  }
695
719
 
696
- if (!info.immutable) {
720
+ if (!immutable) {
697
721
  // We wrote to this file before which has very likely a different content
698
722
  // skip comparing and assume content is different for performance
699
723
  // This case happens often during watch mode.
@@ -0,0 +1,109 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { ConcatSource, PrefixSource } = require("webpack-sources");
9
+ const InitFragment = require("./InitFragment");
10
+ const Template = require("./Template");
11
+ const { mergeRuntime } = require("./util/runtime");
12
+
13
+ /** @typedef {import("webpack-sources").Source} Source */
14
+ /** @typedef {import("./Generator").GenerateContext} GenerateContext */
15
+ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
16
+
17
+ const wrapInCondition = (condition, source) => {
18
+ if (typeof source === "string") {
19
+ return Template.asString([
20
+ `if (${condition}) {`,
21
+ Template.indent(source),
22
+ "}",
23
+ ""
24
+ ]);
25
+ } else {
26
+ return new ConcatSource(
27
+ `if (${condition}) {\n`,
28
+ new PrefixSource("\t", source),
29
+ "}\n"
30
+ );
31
+ }
32
+ };
33
+
34
+ class ConditionalInitFragment extends InitFragment {
35
+ /**
36
+ * @param {string|Source} content the source code that will be included as initialization code
37
+ * @param {number} stage category of initialization code (contribute to order)
38
+ * @param {number} position position in the category (contribute to order)
39
+ * @param {string} key unique key to avoid emitting the same initialization code twice
40
+ * @param {RuntimeSpec | boolean} runtimeCondition in which runtime this fragment should be executed
41
+ * @param {string|Source=} endContent the source code that will be included at the end of the module
42
+ */
43
+ constructor(
44
+ content,
45
+ stage,
46
+ position,
47
+ key,
48
+ runtimeCondition = true,
49
+ endContent
50
+ ) {
51
+ super(content, stage, position, key, endContent);
52
+ this.runtimeCondition = runtimeCondition;
53
+ }
54
+
55
+ /**
56
+ * @param {GenerateContext} generateContext context for generate
57
+ * @returns {string|Source} the source code that will be included as initialization code
58
+ */
59
+ getContent(generateContext) {
60
+ if (this.runtimeCondition === false || !this.content) return "";
61
+ if (this.runtimeCondition === true) return this.content;
62
+ const expr = generateContext.runtimeTemplate.runtimeConditionExpression({
63
+ chunkGraph: generateContext.chunkGraph,
64
+ runtimeRequirements: generateContext.runtimeRequirements,
65
+ runtime: generateContext.runtime,
66
+ runtimeCondition: this.runtimeCondition
67
+ });
68
+ if (expr === "true") return this.content;
69
+ return wrapInCondition(expr, this.content);
70
+ }
71
+
72
+ /**
73
+ * @param {GenerateContext} generateContext context for generate
74
+ * @returns {string|Source=} the source code that will be included at the end of the module
75
+ */
76
+ getEndContent(generateContext) {
77
+ if (this.runtimeCondition === false || !this.endContent) return "";
78
+ if (this.runtimeCondition === true) return this.endContent;
79
+ const expr = generateContext.runtimeTemplate.runtimeConditionExpression({
80
+ chunkGraph: generateContext.chunkGraph,
81
+ runtimeRequirements: generateContext.runtimeRequirements,
82
+ runtime: generateContext.runtime,
83
+ runtimeCondition: this.runtimeCondition
84
+ });
85
+ if (expr === "true") return this.endContent;
86
+ return wrapInCondition(expr, this.endContent);
87
+ }
88
+
89
+ merge(other) {
90
+ if (this.runtimeCondition === true) return this;
91
+ if (other.runtimeCondition === true) return other;
92
+ if (this.runtimeCondition === false) return other;
93
+ if (other.runtimeCondition === false) return this;
94
+ const runtimeCondition = mergeRuntime(
95
+ this.runtimeCondition,
96
+ other.runtimeCondition
97
+ );
98
+ return new ConditionalInitFragment(
99
+ this.content,
100
+ this.stage,
101
+ this.position,
102
+ this.key,
103
+ runtimeCondition,
104
+ this.endContent
105
+ );
106
+ }
107
+ }
108
+
109
+ module.exports = ConditionalInitFragment;
@@ -980,7 +980,7 @@ module.exports = webpackEmptyAsyncContext;`;
980
980
  }
981
981
 
982
982
  getSource(sourceString) {
983
- if (this.useSourceMap) {
983
+ if (this.useSourceMap || this.useSimpleSourceMap) {
984
984
  return new OriginalSource(sourceString, this.identifier());
985
985
  }
986
986
  return new RawSource(sourceString);
@@ -154,7 +154,7 @@ class DelegatedModule extends Module {
154
154
  }
155
155
 
156
156
  const sources = new Map();
157
- if (this.useSourceMap) {
157
+ if (this.useSourceMap || this.useSimpleSourceMap) {
158
158
  sources.set("javascript", new OriginalSource(str, this.identifier()));
159
159
  } else {
160
160
  sources.set("javascript", new RawSource(str));
package/lib/Dependency.js CHANGED
@@ -21,6 +21,7 @@
21
21
  * @typedef {Object} UpdateHashContext
22
22
  * @property {ChunkGraph} chunkGraph
23
23
  * @property {RuntimeSpec} runtime
24
+ * @property {RuntimeTemplate=} runtimeTemplate
24
25
  */
25
26
 
26
27
  /**
@@ -416,7 +416,7 @@ class ExportsInfo {
416
416
 
417
417
  /**
418
418
  * @param {RuntimeSpec} runtime the runtime
419
- * @returns {boolean} true, when the module is used in any way
419
+ * @returns {boolean} true, when the module exports are used in any way
420
420
  */
421
421
  isUsed(runtime) {
422
422
  if (this._redirectTo !== undefined) {
@@ -436,6 +436,17 @@ class ExportsInfo {
436
436
  return false;
437
437
  }
438
438
 
439
+ /**
440
+ * @param {RuntimeSpec} runtime the runtime
441
+ * @returns {boolean} true, when the module is used in any way
442
+ */
443
+ isModuleUsed(runtime) {
444
+ if (this.isUsed(runtime)) return true;
445
+ if (this._sideEffectsOnlyInfo.getUsed(runtime) !== UsageState.Unused)
446
+ return true;
447
+ return false;
448
+ }
449
+
439
450
  /**
440
451
  * @param {RuntimeSpec} runtime the runtime
441
452
  * @returns {SortableSet<string> | boolean | null} set of used exports, or true (when namespace object is used), or false (when unused), or null (when unknown)
@@ -752,6 +763,8 @@ class ExportInfo {
752
763
  this.name = name;
753
764
  /** @private @type {string | null} */
754
765
  this._usedName = initFrom ? initFrom._usedName : null;
766
+ /** @private @type {UsageStateType} */
767
+ this._globalUsed = initFrom ? initFrom._globalUsed : undefined;
755
768
  /** @private @type {Map<string, RuntimeUsageStateType>} */
756
769
  this._usedInRuntime =
757
770
  initFrom && initFrom._usedInRuntime
@@ -907,7 +920,17 @@ class ExportInfo {
907
920
  * @returns {boolean} true when something has changed
908
921
  */
909
922
  setUsedConditionally(condition, newValue, runtime) {
910
- if (this._usedInRuntime === undefined) {
923
+ if (runtime === undefined) {
924
+ if (this._globalUsed === undefined) {
925
+ this._globalUsed = newValue;
926
+ return true;
927
+ } else {
928
+ if (this._globalUsed !== newValue && condition(this._globalUsed)) {
929
+ this._globalUsed = newValue;
930
+ return true;
931
+ }
932
+ }
933
+ } else if (this._usedInRuntime === undefined) {
911
934
  if (newValue !== UsageState.Unused && condition(UsageState.Unused)) {
912
935
  this._usedInRuntime = new Map();
913
936
  forEachRuntime(runtime, runtime =>
@@ -944,7 +967,12 @@ class ExportInfo {
944
967
  * @returns {boolean} true when something has changed
945
968
  */
946
969
  setUsed(newValue, runtime) {
947
- if (this._usedInRuntime === undefined) {
970
+ if (runtime === undefined) {
971
+ if (this._globalUsed !== newValue) {
972
+ this._globalUsed = newValue;
973
+ return true;
974
+ }
975
+ } else if (this._usedInRuntime === undefined) {
948
976
  if (newValue !== UsageState.Unused) {
949
977
  this._usedInRuntime = new Map();
950
978
  forEachRuntime(runtime, runtime =>
@@ -1023,6 +1051,7 @@ class ExportInfo {
1023
1051
  */
1024
1052
  getUsed(runtime) {
1025
1053
  if (!this._hasUseInRuntimeInfo) return UsageState.NoInfo;
1054
+ if (this._globalUsed !== undefined) return this._globalUsed;
1026
1055
  if (this._usedInRuntime === undefined) {
1027
1056
  return UsageState.Unused;
1028
1057
  } else if (typeof runtime === "string") {
@@ -1062,18 +1091,22 @@ class ExportInfo {
1062
1091
  */
1063
1092
  getUsedName(fallbackName, runtime) {
1064
1093
  if (this._hasUseInRuntimeInfo) {
1065
- if (this._usedInRuntime === undefined) return false;
1066
- if (typeof runtime === "string") {
1067
- if (!this._usedInRuntime.has(runtime)) {
1068
- return false;
1069
- }
1070
- } else if (runtime !== undefined) {
1071
- if (
1072
- Array.from(runtime).every(
1073
- runtime => !this._usedInRuntime.has(runtime)
1074
- )
1075
- ) {
1076
- return false;
1094
+ if (this._globalUsed !== undefined) {
1095
+ if (this._globalUsed === UsageState.Unused) return false;
1096
+ } else {
1097
+ if (this._usedInRuntime === undefined) return false;
1098
+ if (typeof runtime === "string") {
1099
+ if (!this._usedInRuntime.has(runtime)) {
1100
+ return false;
1101
+ }
1102
+ } else if (runtime !== undefined) {
1103
+ if (
1104
+ Array.from(runtime).every(
1105
+ runtime => !this._usedInRuntime.has(runtime)
1106
+ )
1107
+ ) {
1108
+ return false;
1109
+ }
1077
1110
  }
1078
1111
  }
1079
1112
  }
@@ -1282,7 +1315,20 @@ class ExportInfo {
1282
1315
  }
1283
1316
 
1284
1317
  getUsedInfo() {
1285
- if (this._usedInRuntime !== undefined) {
1318
+ if (this._globalUsed !== undefined) {
1319
+ switch (this._globalUsed) {
1320
+ case UsageState.Unused:
1321
+ return "unused";
1322
+ case UsageState.NoInfo:
1323
+ return "no usage info";
1324
+ case UsageState.Unknown:
1325
+ return "maybe used (runtime-defined)";
1326
+ case UsageState.Used:
1327
+ return "used";
1328
+ case UsageState.OnlyPropertiesUsed:
1329
+ return "only properties used";
1330
+ }
1331
+ } else if (this._usedInRuntime !== undefined) {
1286
1332
  /** @type {Map<RuntimeUsageStateType, string[]>} */
1287
1333
  const map = new Map();
1288
1334
  for (const [runtime, used] of this._usedInRuntime) {
@@ -293,7 +293,7 @@ class ExternalModule extends Module {
293
293
  exportsType: undefined
294
294
  };
295
295
  this.buildInfo = {
296
- strict: true
296
+ strict: this.externalType !== "this"
297
297
  };
298
298
  this.buildMeta.exportsType = "dynamic";
299
299
  let canMangle = false;
@@ -412,22 +412,23 @@ class ExternalModule extends Module {
412
412
  chunkGraph
413
413
  );
414
414
 
415
- let sourceString;
415
+ let sourceString = sourceData.expression;
416
+ if (sourceData.iife)
417
+ sourceString = `(function() { return ${sourceString}; }())`;
416
418
  if (concatenationScope) {
417
419
  sourceString = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
418
420
  ConcatenationScope.NAMESPACE_OBJECT_EXPORT
419
- } = ${sourceData.expression};`;
421
+ } = ${sourceString};`;
420
422
  concatenationScope.registerNamespaceExport(
421
423
  ConcatenationScope.NAMESPACE_OBJECT_EXPORT
422
424
  );
423
425
  } else {
424
- sourceString = `module.exports = ${sourceData.expression};`;
426
+ sourceString = `module.exports = ${sourceString};`;
425
427
  }
426
- if (sourceData.iife) sourceString = `(function() { ${sourceString} })();`;
427
428
  if (sourceData.init) sourceString = `${sourceData.init}\n${sourceString}`;
428
429
 
429
430
  const sources = new Map();
430
- if (this.useSourceMap) {
431
+ if (this.useSourceMap || this.useSimpleSourceMap) {
431
432
  sources.set(
432
433
  "javascript",
433
434
  new OriginalSource(sourceString, this.identifier())
@@ -7,13 +7,10 @@
7
7
 
8
8
  const Dependency = require("./Dependency");
9
9
  const { UsageState } = require("./ExportsInfo");
10
+ const ModuleGraphConnection = require("./ModuleGraphConnection");
10
11
  const { STAGE_DEFAULT } = require("./OptimizationStages");
11
12
  const TupleQueue = require("./util/TupleQueue");
12
- const {
13
- getEntryRuntime,
14
- mergeRuntime,
15
- mergeRuntimeOwned
16
- } = require("./util/runtime");
13
+ const { getEntryRuntime, mergeRuntimeOwned } = require("./util/runtime");
17
14
 
18
15
  /** @typedef {import("./Chunk")} Chunk */
19
16
  /** @typedef {import("./ChunkGroup")} ChunkGroup */
@@ -63,9 +60,15 @@ class FlagDependencyUsagePlugin {
63
60
  * @param {Module} module module to process
64
61
  * @param {(string[] | ReferencedExport)[]} usedExports list of used exports
65
62
  * @param {RuntimeSpec} runtime part of which runtime
63
+ * @param {boolean} forceSideEffects always apply side effects
66
64
  * @returns {void}
67
65
  */
68
- const processReferencedModule = (module, usedExports, runtime) => {
66
+ const processReferencedModule = (
67
+ module,
68
+ usedExports,
69
+ runtime,
70
+ forceSideEffects
71
+ ) => {
69
72
  const exportsInfo = moduleGraph.getExportsInfo(module);
70
73
  if (usedExports.length > 0) {
71
74
  if (!module.buildMeta || !module.buildMeta.exportsType) {
@@ -143,10 +146,12 @@ class FlagDependencyUsagePlugin {
143
146
  // This module won't be evaluated in this case
144
147
  // TODO webpack 6 remove this check
145
148
  if (
149
+ !forceSideEffects &&
146
150
  module.factoryMeta !== undefined &&
147
151
  module.factoryMeta.sideEffectFree
148
- )
152
+ ) {
149
153
  return;
154
+ }
150
155
  if (exportsInfo.setUsedForSideEffectsOnly(runtime)) {
151
156
  queue.enqueue(module, runtime);
152
157
  }
@@ -166,7 +171,11 @@ class FlagDependencyUsagePlugin {
166
171
  const queue = [module];
167
172
  for (const block of queue) {
168
173
  for (const b of block.blocks) {
169
- if (b.groupOptions && b.groupOptions.entryOptions) {
174
+ if (
175
+ !this.global &&
176
+ b.groupOptions &&
177
+ b.groupOptions.entryOptions
178
+ ) {
170
179
  processModule(b, b.groupOptions.entryOptions.runtime);
171
180
  } else {
172
181
  queue.push(b);
@@ -174,14 +183,16 @@ class FlagDependencyUsagePlugin {
174
183
  }
175
184
  for (const dep of block.dependencies) {
176
185
  const connection = moduleGraph.getConnection(dep);
177
- if (
178
- !connection ||
179
- !connection.module ||
180
- !connection.isTargetActive(runtime)
181
- ) {
186
+ if (!connection || !connection.module) {
182
187
  continue;
183
188
  }
189
+ const activeState = connection.getActiveState(runtime);
190
+ if (activeState === false) continue;
184
191
  const { module } = connection;
192
+ if (activeState === ModuleGraphConnection.TRANSITIVE_ONLY) {
193
+ processModule(module, runtime);
194
+ continue;
195
+ }
185
196
  const oldReferencedExports = map.get(module);
186
197
  if (oldReferencedExports === EXPORTS_OBJECT_REFERENCED) {
187
198
  continue;
@@ -242,12 +253,18 @@ class FlagDependencyUsagePlugin {
242
253
 
243
254
  for (const [module, referencedExports] of map) {
244
255
  if (Array.isArray(referencedExports)) {
245
- processReferencedModule(module, referencedExports, runtime);
256
+ processReferencedModule(
257
+ module,
258
+ referencedExports,
259
+ runtime,
260
+ false
261
+ );
246
262
  } else {
247
263
  processReferencedModule(
248
264
  module,
249
265
  Array.from(referencedExports.values()),
250
- runtime
266
+ runtime,
267
+ false
251
268
  );
252
269
  }
253
270
  }
@@ -270,8 +287,12 @@ class FlagDependencyUsagePlugin {
270
287
  const processEntryDependency = (dep, runtime) => {
271
288
  const module = moduleGraph.getModule(dep);
272
289
  if (module) {
273
- processReferencedModule(module, NO_EXPORTS_REFERENCED, runtime);
274
- queue.enqueue(module, runtime);
290
+ processReferencedModule(
291
+ module,
292
+ NO_EXPORTS_REFERENCED,
293
+ runtime,
294
+ true
295
+ );
275
296
  }
276
297
  };
277
298
  /** @type {RuntimeSpec} */
@@ -305,31 +326,6 @@ class FlagDependencyUsagePlugin {
305
326
  logger.timeEnd("trace exports usage in graph");
306
327
  }
307
328
  );
308
- if (!this.global) {
309
- compilation.hooks.afterChunks.tap("FlagDependencyUsagePlugin", () => {
310
- /** @type {Map<Chunk, string>} */
311
- const runtimeChunks = new Map();
312
- for (const entrypoint of compilation.entrypoints.values()) {
313
- runtimeChunks.set(
314
- entrypoint.getRuntimeChunk(),
315
- entrypoint.options.runtime
316
- );
317
- }
318
- for (const entrypoint of compilation.asyncEntrypoints) {
319
- runtimeChunks.set(
320
- entrypoint.getRuntimeChunk(),
321
- entrypoint.options.runtime
322
- );
323
- }
324
-
325
- for (const [runtimeChunk, runtimeName] of runtimeChunks) {
326
- const runtime = runtimeName || runtimeChunk.name;
327
- for (const chunk of runtimeChunk.getAllReferencedChunks()) {
328
- chunk.runtime = mergeRuntime(chunk.runtime, runtime);
329
- }
330
- }
331
- });
332
- }
333
329
  });
334
330
  }
335
331
  }