webpack 5.41.1 → 5.44.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 (40) hide show
  1. package/lib/Compiler.js +14 -1
  2. package/lib/ExternalModule.js +23 -0
  3. package/lib/ExternalModuleFactoryPlugin.js +1 -1
  4. package/lib/FlagDependencyUsagePlugin.js +5 -1
  5. package/lib/NormalModuleFactory.js +13 -2
  6. package/lib/Template.js +1 -0
  7. package/lib/WebpackOptionsApply.js +2 -1
  8. package/lib/asset/AssetGenerator.js +2 -2
  9. package/lib/cache/PackFileCacheStrategy.js +26 -15
  10. package/lib/config/defaults.js +1 -0
  11. package/lib/config/normalization.js +1 -0
  12. package/lib/container/ContainerPlugin.js +4 -1
  13. package/lib/container/ModuleFederationPlugin.js +1 -0
  14. package/lib/dependencies/WorkerPlugin.js +1 -1
  15. package/lib/esm/ExportWebpackRequireRuntimeModule.js +29 -0
  16. package/lib/esm/ModuleChunkFormatPlugin.js +91 -11
  17. package/lib/esm/ModuleChunkLoadingPlugin.js +13 -0
  18. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +46 -37
  19. package/lib/hmr/lazyCompilationBackend.js +5 -2
  20. package/lib/json/JsonData.js +41 -0
  21. package/lib/json/JsonGenerator.js +8 -2
  22. package/lib/json/JsonParser.js +2 -1
  23. package/lib/optimize/ConcatenatedModule.js +16 -0
  24. package/lib/optimize/RuntimeChunkPlugin.js +1 -1
  25. package/lib/rules/RuleSetCompiler.js +2 -2
  26. package/lib/serialization/BinaryMiddleware.js +26 -21
  27. package/lib/serialization/FileMiddleware.js +82 -6
  28. package/lib/util/internalSerializables.js +1 -0
  29. package/lib/util/makeSerializable.js +0 -1
  30. package/package.json +13 -13
  31. package/schemas/WebpackOptions.check.js +1 -1
  32. package/schemas/WebpackOptions.json +15 -3
  33. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  34. package/schemas/plugins/container/ContainerPlugin.json +15 -0
  35. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  36. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -1
  37. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  38. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  39. package/schemas/plugins/container/ModuleFederationPlugin.json +17 -1
  40. package/types.d.ts +26 -6
@@ -67,6 +67,9 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
67
67
  } = compilation;
68
68
  const fn = RuntimeGlobals.ensureChunkHandlers;
69
69
  const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
70
+ const withExternalInstallChunk = this._runtimeRequirements.has(
71
+ RuntimeGlobals.externalInstallChunk
72
+ );
70
73
  const withLoading = this._runtimeRequirements.has(
71
74
  RuntimeGlobals.ensureChunkHandlers
72
75
  );
@@ -110,6 +113,38 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
110
113
  ),
111
114
  "};",
112
115
  "",
116
+ withLoading || withExternalInstallChunk
117
+ ? `var installChunk = ${runtimeTemplate.basicFunction("data", [
118
+ runtimeTemplate.destructureObject(
119
+ ["ids", "modules", "runtime"],
120
+ "data"
121
+ ),
122
+ '// add "modules" to the modules object,',
123
+ '// then flag all "ids" as loaded and fire callback',
124
+ "var moduleId, chunkId, i = 0;",
125
+ "for(moduleId in modules) {",
126
+ Template.indent([
127
+ `if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`,
128
+ Template.indent(
129
+ `${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];`
130
+ ),
131
+ "}"
132
+ ]),
133
+ "}",
134
+ "if(runtime) runtime(__webpack_require__);",
135
+ "for(;i < ids.length; i++) {",
136
+ Template.indent([
137
+ "chunkId = ids[i];",
138
+ `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
139
+ Template.indent("installedChunks[chunkId][0]();"),
140
+ "}",
141
+ "installedChunks[ids[i]] = 0;"
142
+ ]),
143
+ "}",
144
+ withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
145
+ ])}`
146
+ : "// no install chunk",
147
+ "",
113
148
  withLoading
114
149
  ? Template.asString([
115
150
  `${fn}.j = ${runtimeTemplate.basicFunction(
@@ -137,45 +172,13 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
137
172
  rootOutputDir
138
173
  )} + ${
139
174
  RuntimeGlobals.getChunkScriptFilename
140
- }(chunkId)).then(${runtimeTemplate.basicFunction(
141
- "data",
175
+ }(chunkId)).then(installChunk, ${runtimeTemplate.basicFunction(
176
+ "e",
142
177
  [
143
- runtimeTemplate.destructureObject(
144
- ["ids", "modules", "runtime"],
145
- "data"
146
- ),
147
- '// add "modules" to the modules object,',
148
- '// then flag all "ids" as loaded and fire callback',
149
- "var moduleId, chunkId, i = 0;",
150
- "for(moduleId in modules) {",
151
- Template.indent([
152
- `if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`,
153
- Template.indent(
154
- `${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];`
155
- ),
156
- "}"
157
- ]),
158
- "}",
159
- "if(runtime) runtime(__webpack_require__);",
160
- "for(;i < ids.length; i++) {",
161
- Template.indent([
162
- "chunkId = ids[i];",
163
- `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
164
- Template.indent(
165
- "installedChunks[chunkId][0]();"
166
- ),
167
- "}",
168
- "installedChunks[ids[i]] = 0;"
169
- ]),
170
- "}",
171
- withOnChunkLoad
172
- ? `${RuntimeGlobals.onChunksLoaded}();`
173
- : ""
178
+ "if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;",
179
+ "throw e;"
174
180
  ]
175
- )}, ${runtimeTemplate.basicFunction("e", [
176
- "if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;",
177
- "throw e;"
178
- ])});`,
181
+ )});`,
179
182
  `var promise = Promise.race([promise, new Promise(${runtimeTemplate.expressionFunction(
180
183
  `installedChunkData = installedChunks[chunkId] = [resolve]`,
181
184
  "resolve"
@@ -193,6 +196,12 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
193
196
  ])
194
197
  : "// no chunk on demand loading",
195
198
  "",
199
+ withExternalInstallChunk
200
+ ? Template.asString([
201
+ `${RuntimeGlobals.externalInstallChunk} = installChunk;`
202
+ ])
203
+ : "// no external install chunk",
204
+ "",
196
205
  withOnChunkLoad
197
206
  ? `${
198
207
  RuntimeGlobals.onChunksLoaded
@@ -20,7 +20,7 @@ module.exports = (compiler, client, callback) => {
20
20
  const activeModules = new Map();
21
21
  const prefix = "/lazy-compilation-using-";
22
22
 
23
- const server = http.createServer((req, res) => {
23
+ const requestListener = (req, res) => {
24
24
  const keys = req.url.slice(prefix.length).split("@");
25
25
  req.socket.on("close", () => {
26
26
  setTimeout(() => {
@@ -51,7 +51,8 @@ module.exports = (compiler, client, callback) => {
51
51
  }
52
52
  }
53
53
  if (moduleActivated && compiler.watching) compiler.watching.invalidate();
54
- });
54
+ };
55
+ const server = http.createServer(requestListener);
55
56
  let isClosing = false;
56
57
  /** @type {Set<import("net").Socket>} */
57
58
  const sockets = new Set();
@@ -78,6 +79,8 @@ module.exports = (compiler, client, callback) => {
78
79
  callback(null, {
79
80
  dispose(callback) {
80
81
  isClosing = true;
82
+ // Removing the listener is a workaround for a memory leak in node.js
83
+ server.off("request", requestListener);
81
84
  server.close(err => {
82
85
  callback(err);
83
86
  });
@@ -0,0 +1,41 @@
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 { register } = require("../util/serialization");
9
+
10
+ class JsonData {
11
+ constructor(data) {
12
+ this._buffer = undefined;
13
+ this._data = undefined;
14
+ if (Buffer.isBuffer(data)) {
15
+ this._buffer = data;
16
+ } else {
17
+ this._data = data;
18
+ }
19
+ }
20
+
21
+ get() {
22
+ if (this._data === undefined && this._buffer !== undefined) {
23
+ this._data = JSON.parse(this._buffer.toString());
24
+ }
25
+ return this._data;
26
+ }
27
+ }
28
+
29
+ register(JsonData, "webpack/lib/json/JsonData", null, {
30
+ serialize(obj, { write }) {
31
+ if (obj._buffer === undefined && obj._data !== undefined) {
32
+ obj._buffer = Buffer.from(JSON.stringify(obj._data));
33
+ }
34
+ write(obj._buffer);
35
+ },
36
+ deserialize({ read }) {
37
+ return new JsonData(read());
38
+ }
39
+ });
40
+
41
+ module.exports = JsonData;
@@ -116,7 +116,10 @@ class JsonGenerator extends Generator {
116
116
  * @returns {number} estimate size of the module
117
117
  */
118
118
  getSize(module, type) {
119
- let data = module.buildInfo.jsonData;
119
+ let data =
120
+ module.buildInfo &&
121
+ module.buildInfo.jsonData &&
122
+ module.buildInfo.jsonData.get();
120
123
  if (!data) return 0;
121
124
  return stringifySafe(data).length + 10;
122
125
  }
@@ -145,7 +148,10 @@ class JsonGenerator extends Generator {
145
148
  concatenationScope
146
149
  }
147
150
  ) {
148
- const data = module.buildInfo.jsonData;
151
+ const data =
152
+ module.buildInfo &&
153
+ module.buildInfo.jsonData &&
154
+ module.buildInfo.jsonData.get();
149
155
  if (data === undefined) {
150
156
  return new RawSource(
151
157
  runtimeTemplate.missingModuleStatement({
@@ -8,6 +8,7 @@
8
8
  const parseJson = require("json-parse-better-errors");
9
9
  const Parser = require("../Parser");
10
10
  const JsonExportsDependency = require("../dependencies/JsonExportsDependency");
11
+ const JsonData = require("./JsonData");
11
12
 
12
13
  /** @typedef {import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions} JsonModulesPluginParserOptions */
13
14
  /** @typedef {import("../Parser").ParserState} ParserState */
@@ -41,7 +42,7 @@ class JsonParser extends Parser {
41
42
  ? source
42
43
  : parseFn(source[0] === "\ufeff" ? source.slice(1) : source);
43
44
 
44
- state.module.buildInfo.jsonData = data;
45
+ state.module.buildInfo.jsonData = new JsonData(data);
45
46
  state.module.buildInfo.strict = true;
46
47
  state.module.buildMeta.exportsType = "default";
47
48
  state.module.buildMeta.defaultObject =
@@ -45,6 +45,7 @@ const {
45
45
  /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
46
46
  /** @typedef {import("../DependencyTemplates")} DependencyTemplates */
47
47
  /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
48
+ /** @template T @typedef {import("../InitFragment")<T>} InitFragment */
48
49
  /** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
49
50
  /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
50
51
  /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
@@ -55,6 +56,7 @@ const {
55
56
  /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
56
57
  /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
57
58
  /** @typedef {import("../WebpackError")} WebpackError */
59
+ /** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
58
60
  /** @typedef {import("../util/Hash")} Hash */
59
61
  /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
60
62
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
@@ -104,6 +106,7 @@ if (!ReferencerClass.prototype.PropertyDefinition) {
104
106
  * @property {Object} ast
105
107
  * @property {Source} internalSource
106
108
  * @property {ReplaceSource} source
109
+ * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
107
110
  * @property {Iterable<string>} runtimeRequirements
108
111
  * @property {Scope} globalScope
109
112
  * @property {Scope} moduleScope
@@ -1508,6 +1511,8 @@ ${defineGetters}`
1508
1511
  }
1509
1512
  }
1510
1513
 
1514
+ const chunkInitFragments = [];
1515
+
1511
1516
  // evaluate modules in order
1512
1517
  for (const rawInfo of modulesWithInfo) {
1513
1518
  let name;
@@ -1521,6 +1526,9 @@ ${defineGetters}`
1521
1526
  )}\n`
1522
1527
  );
1523
1528
  result.add(info.source);
1529
+ if (info.chunkInitFragments) {
1530
+ for (const f of info.chunkInitFragments) chunkInitFragments.push(f);
1531
+ }
1524
1532
  if (info.runtimeRequirements) {
1525
1533
  for (const r of info.runtimeRequirements) {
1526
1534
  runtimeRequirements.add(r);
@@ -1583,9 +1591,14 @@ ${defineGetters}`
1583
1591
  }
1584
1592
  }
1585
1593
 
1594
+ const data = new Map();
1595
+ if (chunkInitFragments.length > 0)
1596
+ data.set("chunkInitFragments", chunkInitFragments);
1597
+
1586
1598
  /** @type {CodeGenerationResult} */
1587
1599
  const resultEntry = {
1588
1600
  sources: new Map([["javascript", new CachedSource(result)]]),
1601
+ data,
1589
1602
  runtimeRequirements
1590
1603
  };
1591
1604
 
@@ -1626,6 +1639,8 @@ ${defineGetters}`
1626
1639
  concatenationScope
1627
1640
  });
1628
1641
  const source = codeGenResult.sources.get("javascript");
1642
+ const data = codeGenResult.data;
1643
+ const chunkInitFragments = data && data.get("chunkInitFragments");
1629
1644
  const code = source.source().toString();
1630
1645
  let ast;
1631
1646
  try {
@@ -1662,6 +1677,7 @@ ${defineGetters}`
1662
1677
  info.ast = ast;
1663
1678
  info.internalSource = source;
1664
1679
  info.source = resultSource;
1680
+ info.chunkInitFragments = chunkInitFragments;
1665
1681
  info.globalScope = globalScope;
1666
1682
  info.moduleScope = moduleScope;
1667
1683
  } catch (err) {
@@ -27,7 +27,7 @@ class RuntimeChunkPlugin {
27
27
  (_, { name: entryName }) => {
28
28
  if (entryName === undefined) return;
29
29
  const data = compilation.entries.get(entryName);
30
- if (!data.options.runtime && !data.options.dependOn) {
30
+ if (data.options.runtime === undefined && !data.options.dependOn) {
31
31
  // Determine runtime chunk name
32
32
  let name = this.options.name;
33
33
  if (typeof name === "function") {
@@ -225,7 +225,7 @@ class RuleSetCompiler {
225
225
  if (typeof condition === "string") {
226
226
  return {
227
227
  matchWhenEmpty: condition.length === 0,
228
- fn: str => str.startsWith(condition)
228
+ fn: str => typeof str === "string" && str.startsWith(condition)
229
229
  };
230
230
  }
231
231
  if (typeof condition === "function") {
@@ -245,7 +245,7 @@ class RuleSetCompiler {
245
245
  if (condition instanceof RegExp) {
246
246
  return {
247
247
  matchWhenEmpty: condition.test(""),
248
- fn: v => condition.test(v)
248
+ fn: v => typeof v === "string" && condition.test(v)
249
249
  };
250
250
  }
251
251
  if (Array.isArray(condition)) {
@@ -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);
@@ -156,6 +156,7 @@ module.exports = {
156
156
  require("../dependencies/WebpackIsIncludedDependency"),
157
157
  "dependencies/WorkerDependency": () =>
158
158
  require("../dependencies/WorkerDependency"),
159
+ "json/JsonData": () => require("../json/JsonData"),
159
160
  "optimize/ConcatenatedModule": () =>
160
161
  require("../optimize/ConcatenatedModule"),
161
162
  DelegatedModule: () => require("../DelegatedModule"),
@@ -9,7 +9,6 @@ const { register } = require("./serialization");
9
9
  class ClassSerializer {
10
10
  constructor(Constructor) {
11
11
  this.Constructor = Constructor;
12
- this.hash = null;
13
12
  }
14
13
 
15
14
  serialize(obj, context) {
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.41.1",
3
+ "version": "5.44.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",
7
7
  "dependencies": {
8
8
  "@types/eslint-scope": "^3.7.0",
9
- "@types/estree": "^0.0.48",
10
- "@webassemblyjs/ast": "1.11.0",
11
- "@webassemblyjs/wasm-edit": "1.11.0",
12
- "@webassemblyjs/wasm-parser": "1.11.0",
13
- "acorn": "^8.2.1",
9
+ "@types/estree": "^0.0.50",
10
+ "@webassemblyjs/ast": "1.11.1",
11
+ "@webassemblyjs/wasm-edit": "1.11.1",
12
+ "@webassemblyjs/wasm-parser": "1.11.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",
17
- "es-module-lexer": "^0.6.0",
17
+ "es-module-lexer": "^0.7.1",
18
18
  "eslint-scope": "5.1.1",
19
19
  "events": "^3.2.0",
20
20
  "glob-to-regexp": "^0.4.1",
@@ -131,10 +131,10 @@
131
131
  ],
132
132
  "scripts": {
133
133
  "setup": "node ./setup/setup.js",
134
- "test": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest",
134
+ "test": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --logHeapUsage",
135
135
  "test:update-snapshots": "yarn jest -u",
136
- "test:integration": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/test/*.test.js\"",
137
- "test:basic": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/te{st/TestCasesNormal,st/StatsTestCases,st/ConfigTestCases}.test.js\"",
136
+ "test:integration": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"<rootDir>/test/*.test.js\"",
137
+ "test:basic": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"<rootDir>/te{st/TestCasesNormal,st/StatsTestCases,st/ConfigTestCases}.test.js\"",
138
138
  "test:unit": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/test/*.unittest.js\"",
139
139
  "travis:integration": "yarn cover:integration --ci $JEST",
140
140
  "travis:basic": "yarn cover:basic --ci $JEST",
@@ -165,9 +165,9 @@
165
165
  "benchmark": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/test/*.benchmark.js\" --runInBand",
166
166
  "cover": "yarn cover:all && yarn cover:report",
167
167
  "cover:clean": "rimraf .nyc_output coverage",
168
- "cover:all": "node --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --coverage",
169
- "cover:basic": "node --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/te{st/TestCasesNormal,st/StatsTestCases,st/ConfigTestCases}.test.js\" --coverage",
170
- "cover:integration": "node --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/test/*.test.js\" --coverage",
168
+ "cover:all": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --coverage",
169
+ "cover:basic": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"<rootDir>/te{st/TestCasesNormal,st/StatsTestCases,st/ConfigTestCases}.test.js\" --coverage",
170
+ "cover:integration": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"<rootDir>/test/*.test.js\" --coverage",
171
171
  "cover:unit": "node --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --testMatch \"<rootDir>/test/*.unittest.js\" --coverage",
172
172
  "cover:types": "node node_modules/tooling/type-coverage",
173
173
  "cover:merge": "nyc merge .nyc_output coverage/coverage-nyc.json && rimraf .nyc_output",