webpack 5.41.1 → 5.42.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/bin/webpack.js CHANGED
File without changes
package/lib/Compiler.js CHANGED
@@ -260,6 +260,8 @@ class Compiler {
260
260
 
261
261
  /** @type {Compilation} */
262
262
  this._lastCompilation = undefined;
263
+ /** @type {NormalModuleFactory} */
264
+ this._lastNormalModuleFactory = undefined;
263
265
 
264
266
  /** @private @type {WeakMap<Source, { sizeOnlySource: SizeOnlySource, writtenTo: Map<string, number> }>} */
265
267
  this._assetEmittingSourceCache = new WeakMap();
@@ -375,6 +377,14 @@ class Compiler {
375
377
  }
376
378
  }
377
379
 
380
+ // TODO webpack 6: solve this in a better way
381
+ _cleanupLastNormalModuleFactory() {
382
+ if (this._lastNormalModuleFactory !== undefined) {
383
+ this._lastNormalModuleFactory.cleanupForCache();
384
+ this._lastNormalModuleFactory = undefined;
385
+ }
386
+ }
387
+
378
388
  /**
379
389
  * @param {WatchOptions} watchOptions the watcher's options
380
390
  * @param {Callback<Stats>} handler signals when the call finishes
@@ -1036,6 +1046,7 @@ ${other}`);
1036
1046
  }
1037
1047
 
1038
1048
  createNormalModuleFactory() {
1049
+ this._cleanupLastNormalModuleFactory();
1039
1050
  const normalModuleFactory = new NormalModuleFactory({
1040
1051
  context: this.options.context,
1041
1052
  fs: this.inputFileSystem,
@@ -1044,6 +1055,7 @@ ${other}`);
1044
1055
  associatedObjectForCache: this.root,
1045
1056
  layers: this.options.experiments.layers
1046
1057
  });
1058
+ this._lastNormalModuleFactory = normalModuleFactory;
1047
1059
  this.hooks.normalModuleFactory.call(normalModuleFactory);
1048
1060
  return normalModuleFactory;
1049
1061
  }
@@ -1122,8 +1134,9 @@ ${other}`);
1122
1134
  if (err) return callback(err);
1123
1135
  // Get rid of reference to last compilation to avoid leaking memory
1124
1136
  // We can't run this._cleanupLastCompilation() as the Stats to this compilation
1125
- // might be still in use. We try to get rid for the reference to the cache instead.
1137
+ // might be still in use. We try to get rid of the reference to the cache instead.
1126
1138
  this._lastCompilation = undefined;
1139
+ this._lastNormalModuleFactory = undefined;
1127
1140
  this.cache.shutdown(callback);
1128
1141
  });
1129
1142
  }
@@ -429,6 +429,11 @@ class ExternalModule extends Module {
429
429
  this.buildInfo.strict = false;
430
430
  break;
431
431
  case "system":
432
+ if (!Array.isArray(request) || request.length === 1) {
433
+ this.buildMeta.exportsType = "namespace";
434
+ canMangle = true;
435
+ }
436
+ break;
432
437
  case "module":
433
438
  if (this.buildInfo.module) {
434
439
  if (!Array.isArray(request) || request.length === 1) {
@@ -13,8 +13,10 @@ const {
13
13
  SyncHook,
14
14
  HookMap
15
15
  } = require("tapable");
16
+ const ChunkGraph = require("./ChunkGraph");
16
17
  const Module = require("./Module");
17
18
  const ModuleFactory = require("./ModuleFactory");
19
+ const ModuleGraph = require("./ModuleGraph");
18
20
  const NormalModule = require("./NormalModule");
19
21
  const BasicEffectRulePlugin = require("./rules/BasicEffectRulePlugin");
20
22
  const BasicMatcherRulePlugin = require("./rules/BasicMatcherRulePlugin");
@@ -257,8 +259,8 @@ class NormalModuleFactory extends ModuleFactory {
257
259
  this.parserCache = new Map();
258
260
  /** @type {Map<string, WeakMap<Object, Generator>>} */
259
261
  this.generatorCache = new Map();
260
- /** @type {WeakSet<Module>} */
261
- this._restoredUnsafeCacheEntries = new WeakSet();
262
+ /** @type {Set<Module>} */
263
+ this._restoredUnsafeCacheEntries = new Set();
262
264
 
263
265
  const cacheParseResource = parseResource.bindCache(
264
266
  associatedObjectForCache
@@ -661,6 +663,14 @@ class NormalModuleFactory extends ModuleFactory {
661
663
  );
662
664
  }
663
665
 
666
+ cleanupForCache() {
667
+ for (const module of this._restoredUnsafeCacheEntries) {
668
+ ChunkGraph.clearChunkGraphForModule(module);
669
+ ModuleGraph.clearModuleGraphForModule(module);
670
+ module.cleanupForCache();
671
+ }
672
+ }
673
+
664
674
  /**
665
675
  * @param {ModuleFactoryCreateData} data data object
666
676
  * @param {function(Error=, ModuleFactoryResult=): void} callback callback
@@ -572,7 +572,8 @@ class WebpackOptionsApply extends OptionsApply {
572
572
  snapshot: options.snapshot,
573
573
  maxAge: cacheOptions.maxAge,
574
574
  profile: cacheOptions.profile,
575
- allowCollectingMemory: cacheOptions.allowCollectingMemory
575
+ allowCollectingMemory: cacheOptions.allowCollectingMemory,
576
+ compression: cacheOptions.compression
576
577
  }),
577
578
  cacheOptions.idleTimeout,
578
579
  cacheOptions.idleTimeoutForInitialStore,
@@ -848,6 +848,7 @@ class PackFileCacheStrategy {
848
848
  * @param {number} options.maxAge max age of cache items
849
849
  * @param {boolean} options.profile track and log detailed timing information for individual cache items
850
850
  * @param {boolean} options.allowCollectingMemory allow to collect unused memory created during deserialization
851
+ * @param {false | "gzip" | "brotli"} options.compression compression used
851
852
  */
852
853
  constructor({
853
854
  compiler,
@@ -859,7 +860,8 @@ class PackFileCacheStrategy {
859
860
  snapshot,
860
861
  maxAge,
861
862
  profile,
862
- allowCollectingMemory
863
+ allowCollectingMemory,
864
+ compression
863
865
  }) {
864
866
  this.fileSerializer = createFileSerializer(fs);
865
867
  this.fileSystemInfo = new FileSystemInfo(fs, {
@@ -875,6 +877,13 @@ class PackFileCacheStrategy {
875
877
  this.maxAge = maxAge;
876
878
  this.profile = profile;
877
879
  this.allowCollectingMemory = allowCollectingMemory;
880
+ this.compression = compression;
881
+ this._extension =
882
+ compression === "brotli"
883
+ ? ".pack.br"
884
+ : compression === "gzip"
885
+ ? ".pack.gz"
886
+ : ".pack";
878
887
  this.snapshot = snapshot;
879
888
  /** @type {Set<string>} */
880
889
  this.buildDependencies = new Set();
@@ -916,8 +925,8 @@ class PackFileCacheStrategy {
916
925
  logger.time("restore cache container");
917
926
  return this.fileSerializer
918
927
  .deserialize(null, {
919
- filename: `${cacheLocation}/index.pack`,
920
- extension: ".pack",
928
+ filename: `${cacheLocation}/index${this._extension}`,
929
+ extension: `${this._extension}`,
921
930
  logger,
922
931
  profile,
923
932
  retainedBuffer: this.allowCollectingMemory
@@ -927,11 +936,13 @@ class PackFileCacheStrategy {
927
936
  .catch(err => {
928
937
  if (err.code !== "ENOENT") {
929
938
  logger.warn(
930
- `Restoring pack failed from ${cacheLocation}.pack: ${err}`
939
+ `Restoring pack failed from ${cacheLocation}${this._extension}: ${err}`
931
940
  );
932
941
  logger.debug(err.stack);
933
942
  } else {
934
- logger.debug(`No pack exists at ${cacheLocation}.pack: ${err}`);
943
+ logger.debug(
944
+ `No pack exists at ${cacheLocation}${this._extension}: ${err}`
945
+ );
935
946
  }
936
947
  return undefined;
937
948
  })
@@ -940,14 +951,14 @@ class PackFileCacheStrategy {
940
951
  if (!packContainer) return undefined;
941
952
  if (!(packContainer instanceof PackContainer)) {
942
953
  logger.warn(
943
- `Restored pack from ${cacheLocation}.pack, but contained content is unexpected.`,
954
+ `Restored pack from ${cacheLocation}${this._extension}, but contained content is unexpected.`,
944
955
  packContainer
945
956
  );
946
957
  return undefined;
947
958
  }
948
959
  if (packContainer.version !== version) {
949
960
  logger.log(
950
- `Restored pack from ${cacheLocation}.pack, but version doesn't match.`
961
+ `Restored pack from ${cacheLocation}${this._extension}, but version doesn't match.`
951
962
  );
952
963
  return undefined;
953
964
  }
@@ -959,14 +970,14 @@ class PackFileCacheStrategy {
959
970
  (err, valid) => {
960
971
  if (err) {
961
972
  logger.log(
962
- `Restored pack from ${cacheLocation}.pack, but checking snapshot of build dependencies errored: ${err}.`
973
+ `Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of build dependencies errored: ${err}.`
963
974
  );
964
975
  logger.debug(err.stack);
965
976
  return resolve(false);
966
977
  }
967
978
  if (!valid) {
968
979
  logger.log(
969
- `Restored pack from ${cacheLocation}.pack, but build dependencies have changed.`
980
+ `Restored pack from ${cacheLocation}${this._extension}, but build dependencies have changed.`
970
981
  );
971
982
  return resolve(false);
972
983
  }
@@ -981,7 +992,7 @@ class PackFileCacheStrategy {
981
992
  (err, valid) => {
982
993
  if (err) {
983
994
  logger.log(
984
- `Restored pack from ${cacheLocation}.pack, but checking snapshot of resolving of build dependencies errored: ${err}.`
995
+ `Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of resolving of build dependencies errored: ${err}.`
985
996
  );
986
997
  logger.debug(err.stack);
987
998
  return resolve(false);
@@ -1001,7 +1012,7 @@ class PackFileCacheStrategy {
1001
1012
  (err, valid) => {
1002
1013
  if (err) {
1003
1014
  logger.log(
1004
- `Restored pack from ${cacheLocation}.pack, but resolving of build dependencies errored: ${err}.`
1015
+ `Restored pack from ${cacheLocation}${this._extension}, but resolving of build dependencies errored: ${err}.`
1005
1016
  );
1006
1017
  logger.debug(err.stack);
1007
1018
  return resolve(false);
@@ -1012,7 +1023,7 @@ class PackFileCacheStrategy {
1012
1023
  return resolve(true);
1013
1024
  }
1014
1025
  logger.log(
1015
- `Restored pack from ${cacheLocation}.pack, but build dependencies resolve to different locations.`
1026
+ `Restored pack from ${cacheLocation}${this._extension}, but build dependencies resolve to different locations.`
1016
1027
  );
1017
1028
  return resolve(false);
1018
1029
  }
@@ -1052,7 +1063,7 @@ class PackFileCacheStrategy {
1052
1063
  })
1053
1064
  .catch(err => {
1054
1065
  this.logger.warn(
1055
- `Restoring pack from ${cacheLocation}.pack failed: ${err}`
1066
+ `Restoring pack from ${cacheLocation}${this._extension} failed: ${err}`
1056
1067
  );
1057
1068
  this.logger.debug(err.stack);
1058
1069
  return new Pack(logger, this.maxAge);
@@ -1236,8 +1247,8 @@ class PackFileCacheStrategy {
1236
1247
  );
1237
1248
  return this.fileSerializer
1238
1249
  .serialize(content, {
1239
- filename: `${this.cacheLocation}/index.pack`,
1240
- extension: ".pack",
1250
+ filename: `${this.cacheLocation}/index${this._extension}`,
1251
+ extension: `${this._extension}`,
1241
1252
  logger: this.logger,
1242
1253
  profile: this.profile
1243
1254
  })
@@ -298,6 +298,7 @@ const applyCacheDefaults = (cache, { name, mode, development }) => {
298
298
  );
299
299
  D(cache, "hashAlgorithm", "md4");
300
300
  D(cache, "store", "pack");
301
+ D(cache, "compression", development ? false : "gzip");
301
302
  D(cache, "profile", false);
302
303
  D(cache, "idleTimeout", 60000);
303
304
  D(cache, "idleTimeoutForInitialStore", 5000);
@@ -137,6 +137,7 @@ const getNormalizedWebpackOptions = config => {
137
137
  cacheDirectory: cache.cacheDirectory,
138
138
  cacheLocation: cache.cacheLocation,
139
139
  hashAlgorithm: cache.hashAlgorithm,
140
+ compression: cache.compression,
140
141
  idleTimeout: cache.idleTimeout,
141
142
  idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore,
142
143
  idleTimeoutAfterLargeChanges: cache.idleTimeoutAfterLargeChanges,
@@ -548,12 +548,7 @@ class BinaryMiddleware extends SerializerMiddleware {
548
548
  const isInCurrentBuffer = n => {
549
549
  return currentIsBuffer && n + currentPosition <= currentBuffer.length;
550
550
  };
551
- /**
552
- * Reads n bytes
553
- * @param {number} n amount of bytes to read
554
- * @returns {Buffer} buffer with bytes
555
- */
556
- const read = n => {
551
+ const ensureBuffer = () => {
557
552
  if (!currentIsBuffer) {
558
553
  throw new Error(
559
554
  currentBuffer === null
@@ -561,9 +556,31 @@ class BinaryMiddleware extends SerializerMiddleware {
561
556
  : "Unexpected lazy element in stream"
562
557
  );
563
558
  }
559
+ };
560
+ /**
561
+ * Reads n bytes
562
+ * @param {number} n amount of bytes to read
563
+ * @returns {Buffer} buffer with bytes
564
+ */
565
+ const read = n => {
566
+ ensureBuffer();
564
567
  const rem = currentBuffer.length - currentPosition;
565
568
  if (rem < n) {
566
- return Buffer.concat([read(rem), read(n - rem)]);
569
+ const buffers = [read(rem)];
570
+ n -= rem;
571
+ ensureBuffer();
572
+ while (currentBuffer.length < n) {
573
+ const b = /** @type {Buffer} */ (currentBuffer);
574
+ buffers.push(b);
575
+ n -= b.length;
576
+ currentDataItem++;
577
+ currentBuffer =
578
+ currentDataItem < data.length ? data[currentDataItem] : null;
579
+ currentIsBuffer = Buffer.isBuffer(currentBuffer);
580
+ ensureBuffer();
581
+ }
582
+ buffers.push(read(n));
583
+ return Buffer.concat(buffers);
567
584
  }
568
585
  const b = /** @type {Buffer} */ (currentBuffer);
569
586
  const res = Buffer.from(b.buffer, b.byteOffset + currentPosition, n);
@@ -577,13 +594,7 @@ class BinaryMiddleware extends SerializerMiddleware {
577
594
  * @returns {Buffer} buffer with bytes
578
595
  */
579
596
  const readUpTo = n => {
580
- if (!currentIsBuffer) {
581
- throw new Error(
582
- currentBuffer === null
583
- ? "Unexpected end of stream"
584
- : "Unexpected lazy element in stream"
585
- );
586
- }
597
+ ensureBuffer();
587
598
  const rem = currentBuffer.length - currentPosition;
588
599
  if (rem < n) {
589
600
  n = rem;
@@ -595,13 +606,7 @@ class BinaryMiddleware extends SerializerMiddleware {
595
606
  return res;
596
607
  };
597
608
  const readU8 = () => {
598
- if (!currentIsBuffer) {
599
- throw new Error(
600
- currentBuffer === null
601
- ? "Unexpected end of stream"
602
- : "Unexpected lazy element in stream"
603
- );
604
- }
609
+ ensureBuffer();
605
610
  /**
606
611
  * There is no need to check remaining buffer size here
607
612
  * since {@link checkOverflow} guarantees at least one byte remaining
@@ -5,6 +5,14 @@
5
5
  "use strict";
6
6
 
7
7
  const { constants } = require("buffer");
8
+ const { pipeline } = require("stream");
9
+ const {
10
+ createBrotliCompress,
11
+ createBrotliDecompress,
12
+ createGzip,
13
+ createGunzip,
14
+ constants: zConstants
15
+ } = require("zlib");
8
16
  const createHash = require("../util/createHash");
9
17
  const { dirname, join, mkdirp } = require("../util/fs");
10
18
  const memoize = require("../util/memoize");
@@ -37,6 +45,9 @@ const hashForName = buffers => {
37
45
  return /** @type {string} */ (hash.digest("hex"));
38
46
  };
39
47
 
48
+ const COMPRESSION_CHUNK_SIZE = 100 * 1024 * 1024;
49
+ const DECOMPRESSION_CHUNK_SIZE = 100 * 1024 * 1024;
50
+
40
51
  const writeUInt64LE = Buffer.prototype.writeBigUInt64LE
41
52
  ? (buf, value, offset) => {
42
53
  buf.writeBigUInt64LE(BigInt(value), offset);
@@ -69,7 +80,7 @@ const readUInt64LE = Buffer.prototype.readBigUInt64LE
69
80
  * @param {FileMiddleware} middleware this
70
81
  * @param {BufferSerializableType[] | Promise<BufferSerializableType[]>} data data to be serialized
71
82
  * @param {string | boolean} name file base name
72
- * @param {function(string | false, Buffer[]): Promise} writeFile writes a file
83
+ * @param {function(string | false, Buffer[]): Promise<void>} writeFile writes a file
73
84
  * @returns {Promise<SerializeResult>} resulting file pointer and promise
74
85
  */
75
86
  const serialize = async (middleware, data, name, writeFile) => {
@@ -399,11 +410,37 @@ class FileMiddleware extends SerializerMiddleware {
399
410
  ? join(this.fs, filename, `../${name}${extension}`)
400
411
  : filename;
401
412
  await new Promise((resolve, reject) => {
402
- const stream = this.fs.createWriteStream(file + "_");
413
+ let stream = this.fs.createWriteStream(file + "_");
414
+ let compression;
415
+ if (file.endsWith(".gz")) {
416
+ compression = createGzip({
417
+ chunkSize: COMPRESSION_CHUNK_SIZE,
418
+ level: zConstants.Z_BEST_SPEED
419
+ });
420
+ } else if (file.endsWith(".br")) {
421
+ compression = createBrotliCompress({
422
+ chunkSize: COMPRESSION_CHUNK_SIZE,
423
+ params: {
424
+ [zConstants.BROTLI_PARAM_MODE]: zConstants.BROTLI_MODE_TEXT,
425
+ [zConstants.BROTLI_PARAM_QUALITY]: 2,
426
+ [zConstants.BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING]: true,
427
+ [zConstants.BROTLI_PARAM_SIZE_HINT]: content.reduce(
428
+ (size, b) => size + b.length,
429
+ 0
430
+ )
431
+ }
432
+ });
433
+ }
434
+ if (compression) {
435
+ pipeline(compression, stream, reject);
436
+ stream = compression;
437
+ stream.on("finish", () => resolve());
438
+ } else {
439
+ stream.on("error", err => reject(err));
440
+ stream.on("finish", () => resolve());
441
+ }
403
442
  for (const b of content) stream.write(b);
404
443
  stream.end();
405
- stream.on("error", err => reject(err));
406
- stream.on("finish", () => resolve());
407
444
  });
408
445
  if (name) allWrittenFiles.add(file);
409
446
  };
@@ -470,6 +507,34 @@ class FileMiddleware extends SerializerMiddleware {
470
507
  let currentBuffer;
471
508
  let currentBufferUsed;
472
509
  const buf = [];
510
+ let decompression;
511
+ if (file.endsWith(".gz")) {
512
+ decompression = createGunzip({
513
+ chunkSize: DECOMPRESSION_CHUNK_SIZE
514
+ });
515
+ } else if (file.endsWith(".br")) {
516
+ decompression = createBrotliDecompress({
517
+ chunkSize: DECOMPRESSION_CHUNK_SIZE
518
+ });
519
+ }
520
+ if (decompression) {
521
+ let newResolve, newReject;
522
+ resolve(
523
+ Promise.all([
524
+ new Promise((rs, rj) => {
525
+ newResolve = rs;
526
+ newReject = rj;
527
+ }),
528
+ new Promise((resolve, reject) => {
529
+ decompression.on("data", chunk => buf.push(chunk));
530
+ decompression.on("end", () => resolve());
531
+ decompression.on("error", err => reject(err));
532
+ })
533
+ ]).then(() => buf)
534
+ );
535
+ resolve = newResolve;
536
+ reject = newReject;
537
+ }
473
538
  this.fs.open(file, "r", (err, fd) => {
474
539
  if (err) {
475
540
  reject(err);
@@ -478,7 +543,11 @@ class FileMiddleware extends SerializerMiddleware {
478
543
  const read = () => {
479
544
  if (currentBuffer === undefined) {
480
545
  currentBuffer = Buffer.allocUnsafeSlow(
481
- Math.min(constants.MAX_LENGTH, remaining)
546
+ Math.min(
547
+ constants.MAX_LENGTH,
548
+ remaining,
549
+ decompression ? DECOMPRESSION_CHUNK_SIZE : Infinity
550
+ )
482
551
  );
483
552
  currentBufferUsed = 0;
484
553
  }
@@ -509,9 +578,16 @@ class FileMiddleware extends SerializerMiddleware {
509
578
  currentBufferUsed += bytesRead;
510
579
  remaining -= bytesRead;
511
580
  if (currentBufferUsed === currentBuffer.length) {
512
- buf.push(currentBuffer);
581
+ if (decompression) {
582
+ decompression.write(currentBuffer);
583
+ } else {
584
+ buf.push(currentBuffer);
585
+ }
513
586
  currentBuffer = undefined;
514
587
  if (remaining === 0) {
588
+ if (decompression) {
589
+ decompression.end();
590
+ }
515
591
  this.fs.close(fd, err => {
516
592
  if (err) {
517
593
  reject(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.41.1",
3
+ "version": "5.42.0",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
6
6
  "license": "MIT",
@@ -10,7 +10,7 @@
10
10
  "@webassemblyjs/ast": "1.11.0",
11
11
  "@webassemblyjs/wasm-edit": "1.11.0",
12
12
  "@webassemblyjs/wasm-parser": "1.11.0",
13
- "acorn": "^8.2.1",
13
+ "acorn": "^8.4.1",
14
14
  "browserslist": "^4.14.5",
15
15
  "chrome-trace-event": "^1.0.2",
16
16
  "enhanced-resolve": "^5.8.0",