webpack 5.27.2 → 5.31.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.

package/lib/Compiler.js CHANGED
@@ -1101,6 +1101,10 @@ ${other}`);
1101
1101
  close(callback) {
1102
1102
  this.hooks.shutdown.callAsync(err => {
1103
1103
  if (err) return callback(err);
1104
+ // Get rid of reference to last compilation to avoid leaking memory
1105
+ // We can't run this._cleanupLastCompilation() as the Stats to this compilation
1106
+ // might be still in use. We try to get rid for the reference to the cache instead.
1107
+ this._lastCompilation = undefined;
1104
1108
  this.cache.shutdown(callback);
1105
1109
  });
1106
1110
  }
package/lib/Dependency.js CHANGED
@@ -55,6 +55,7 @@ const memoize = require("./util/memoize");
55
55
  * @property {(string | ExportSpec)[]=} exports nested exports
56
56
  * @property {ModuleGraphConnection=} from when reexported: from which module
57
57
  * @property {string[] | null=} export when reexported: from which export
58
+ * @property {number=} priority when reexported: with which priority
58
59
  * @property {boolean=} hidden export is not visible, because another export blends over it
59
60
  */
60
61
 
@@ -64,6 +65,7 @@ const memoize = require("./util/memoize");
64
65
  * @property {Set<string>=} excludeExports when exports = true, list of unaffected exports
65
66
  * @property {Set<string>=} hideExports list of maybe prior exposed, but now hidden exports
66
67
  * @property {ModuleGraphConnection=} from when reexported: from which module
68
+ * @property {number=} priority when reexported: with which priority
67
69
  * @property {boolean=} canMangle can the export be renamed (defaults to true)
68
70
  * @property {boolean=} terminalBinding are the exports terminal bindings that should be checked for export star conflicts
69
71
  * @property {Module[]=} dependencies module on which the result depends on
@@ -215,7 +217,9 @@ class Dependency {
215
217
  }
216
218
  }
217
219
 
220
+ /** @type {string[][]} */
218
221
  Dependency.NO_EXPORTS_REFERENCED = [];
222
+ /** @type {string[][]} */
219
223
  Dependency.EXPORTS_OBJECT_REFERENCED = [[]];
220
224
 
221
225
  Object.defineProperty(Dependency.prototype, "module", {
@@ -269,13 +269,15 @@ class ExportsInfo {
269
269
  * @param {Set<string>=} excludeExports list of unaffected exports
270
270
  * @param {any=} targetKey use this as key for the target
271
271
  * @param {ModuleGraphConnection=} targetModule set this module as target
272
+ * @param {number=} priority priority
272
273
  * @returns {boolean} true, if this call changed something
273
274
  */
274
275
  setUnknownExportsProvided(
275
276
  canMangle,
276
277
  excludeExports,
277
278
  targetKey,
278
- targetModule
279
+ targetModule,
280
+ priority
279
281
  ) {
280
282
  let changed = false;
281
283
  if (excludeExports) {
@@ -295,7 +297,7 @@ class ExportsInfo {
295
297
  changed = true;
296
298
  }
297
299
  if (targetKey) {
298
- exportInfo.setTarget(targetKey, targetModule, [exportInfo.name]);
300
+ exportInfo.setTarget(targetKey, targetModule, [exportInfo.name], -1);
299
301
  }
300
302
  }
301
303
  if (this._redirectTo !== undefined) {
@@ -304,7 +306,8 @@ class ExportsInfo {
304
306
  canMangle,
305
307
  excludeExports,
306
308
  targetKey,
307
- targetModule
309
+ targetModule,
310
+ priority
308
311
  )
309
312
  ) {
310
313
  changed = true;
@@ -322,7 +325,12 @@ class ExportsInfo {
322
325
  changed = true;
323
326
  }
324
327
  if (targetKey) {
325
- this._otherExportsInfo.setTarget(targetKey, targetModule, undefined);
328
+ this._otherExportsInfo.setTarget(
329
+ targetKey,
330
+ targetModule,
331
+ undefined,
332
+ priority
333
+ );
326
334
  }
327
335
  }
328
336
  return changed;
@@ -819,17 +827,20 @@ class ExportInfo {
819
827
  this.exportsInfoOwned = false;
820
828
  /** @type {ExportsInfo=} */
821
829
  this.exportsInfo = undefined;
822
- /** @type {Map<any, { connection: ModuleGraphConnection, export: string[] } | null>=} */
830
+ /** @type {Map<any, { connection: ModuleGraphConnection | null, export: string[], priority: number }>=} */
823
831
  this._target = undefined;
824
832
  if (initFrom && initFrom._target) {
825
833
  this._target = new Map();
826
834
  for (const [key, value] of initFrom._target) {
827
- this._target.set(
828
- key,
829
- value ? { connection: value.connection, export: [name] } : null
830
- );
835
+ this._target.set(key, {
836
+ connection: value.connection,
837
+ export: value.export || [name],
838
+ priority: value.priority
839
+ });
831
840
  }
832
841
  }
842
+ /** @type {Map<any, { connection: ModuleGraphConnection | null, export: string[], priority: number }>=} */
843
+ this._maxTarget = undefined;
833
844
  }
834
845
 
835
846
  // TODO webpack 5 remove
@@ -1023,46 +1034,45 @@ class ExportInfo {
1023
1034
  */
1024
1035
  unsetTarget(key) {
1025
1036
  if (!this._target) return false;
1026
- return this._target.delete(key);
1037
+ if (this._target.delete(key)) {
1038
+ this._maxTarget = undefined;
1039
+ return true;
1040
+ }
1041
+ return false;
1027
1042
  }
1028
1043
 
1029
1044
  /**
1030
1045
  * @param {any} key the key
1031
- * @param {ModuleGraphConnection=} connection the target module if a single one
1046
+ * @param {ModuleGraphConnection} connection the target module if a single one
1032
1047
  * @param {string[]=} exportName the exported name
1048
+ * @param {number=} priority priority
1033
1049
  * @returns {boolean} true, if something has changed
1034
1050
  */
1035
- setTarget(key, connection, exportName) {
1051
+ setTarget(key, connection, exportName, priority = 0) {
1036
1052
  if (exportName) exportName = [...exportName];
1037
1053
  if (!this._target) {
1038
1054
  this._target = new Map();
1039
- this._target.set(
1040
- key,
1041
- connection ? { connection, export: exportName } : null
1042
- );
1055
+ this._target.set(key, { connection, export: exportName, priority });
1043
1056
  return true;
1044
1057
  }
1045
1058
  const oldTarget = this._target.get(key);
1046
1059
  if (!oldTarget) {
1047
1060
  if (oldTarget === null && !connection) return false;
1048
- this._target.set(
1049
- key,
1050
- connection ? { connection, export: exportName } : null
1051
- );
1052
- return true;
1053
- }
1054
- if (!connection) {
1055
- this._target.set(key, null);
1061
+ this._target.set(key, { connection, export: exportName, priority });
1062
+ this._maxTarget = undefined;
1056
1063
  return true;
1057
1064
  }
1058
1065
  if (
1059
1066
  oldTarget.connection !== connection ||
1067
+ oldTarget.priority !== priority ||
1060
1068
  (exportName
1061
1069
  ? !oldTarget.export || !equals(oldTarget.export, exportName)
1062
1070
  : oldTarget.export)
1063
1071
  ) {
1064
1072
  oldTarget.connection = connection;
1065
1073
  oldTarget.export = exportName;
1074
+ oldTarget.priority = priority;
1075
+ this._maxTarget = undefined;
1066
1076
  return true;
1067
1077
  }
1068
1078
  return false;
@@ -1171,6 +1181,29 @@ class ExportInfo {
1171
1181
  return !this.terminalBinding && this._target && this._target.size > 0;
1172
1182
  }
1173
1183
 
1184
+ _getMaxTarget() {
1185
+ if (this._maxTarget !== undefined) return this._maxTarget;
1186
+ if (this._target.size <= 1) return (this._maxTarget = this._target);
1187
+ let maxPriority = -Infinity;
1188
+ let minPriority = Infinity;
1189
+ for (const { priority } of this._target.values()) {
1190
+ if (maxPriority < priority) maxPriority = priority;
1191
+ if (minPriority > priority) minPriority = priority;
1192
+ }
1193
+ // This should be very common
1194
+ if (maxPriority === minPriority) return (this._maxTarget = this._target);
1195
+
1196
+ // This is an edge case
1197
+ const map = new Map();
1198
+ for (const [key, value] of this._target) {
1199
+ if (maxPriority === value.priority) {
1200
+ map.set(key, value);
1201
+ }
1202
+ }
1203
+ this._maxTarget = map;
1204
+ return map;
1205
+ }
1206
+
1174
1207
  /**
1175
1208
  * @param {ModuleGraph} moduleGraph the module graph
1176
1209
  * @param {function(Module): boolean} validTargetModuleFilter a valid target module
@@ -1188,7 +1221,7 @@ class ExportInfo {
1188
1221
  */
1189
1222
  _findTarget(moduleGraph, validTargetModuleFilter, alreadyVisited) {
1190
1223
  if (!this._target || this._target.size === 0) return undefined;
1191
- let rawTarget = this._target.values().next().value;
1224
+ let rawTarget = this._getMaxTarget().values().next().value;
1192
1225
  if (!rawTarget) return undefined;
1193
1226
  /** @type {{ module: Module, export: string[] | undefined }} */
1194
1227
  let target = {
@@ -1296,7 +1329,7 @@ class ExportInfo {
1296
1329
  if (alreadyVisited && alreadyVisited.has(this)) return CIRCULAR;
1297
1330
  const newAlreadyVisited = new Set(alreadyVisited);
1298
1331
  newAlreadyVisited.add(this);
1299
- const values = this._target.values();
1332
+ const values = this._getMaxTarget().values();
1300
1333
  const target = resolveTarget(values.next().value, newAlreadyVisited);
1301
1334
  if (target === CIRCULAR) return CIRCULAR;
1302
1335
  if (target === null) return undefined;
@@ -1324,7 +1357,7 @@ class ExportInfo {
1324
1357
  const target = this._getTarget(moduleGraph, resolveTargetFilter, undefined);
1325
1358
  if (target === CIRCULAR) return undefined;
1326
1359
  if (!target) return undefined;
1327
- const originalTarget = this._target.values().next().value;
1360
+ const originalTarget = this._getMaxTarget().values().next().value;
1328
1361
  if (
1329
1362
  originalTarget.connection === target.connection &&
1330
1363
  originalTarget.export === target.export
@@ -1336,7 +1369,8 @@ class ExportInfo {
1336
1369
  connection: updateOriginalConnection
1337
1370
  ? updateOriginalConnection(target)
1338
1371
  : target.connection,
1339
- export: target.export
1372
+ export: target.export,
1373
+ priority: 0
1340
1374
  });
1341
1375
  return target;
1342
1376
  }