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.
- package/lib/Compiler.js +14 -1
- package/lib/ExternalModule.js +23 -0
- package/lib/ExternalModuleFactoryPlugin.js +1 -1
- package/lib/FlagDependencyUsagePlugin.js +5 -1
- package/lib/NormalModuleFactory.js +13 -2
- package/lib/Template.js +1 -0
- package/lib/WebpackOptionsApply.js +2 -1
- package/lib/asset/AssetGenerator.js +2 -2
- package/lib/cache/PackFileCacheStrategy.js +26 -15
- package/lib/config/defaults.js +1 -0
- package/lib/config/normalization.js +1 -0
- package/lib/container/ContainerPlugin.js +4 -1
- package/lib/container/ModuleFederationPlugin.js +1 -0
- package/lib/dependencies/WorkerPlugin.js +1 -1
- package/lib/esm/ExportWebpackRequireRuntimeModule.js +29 -0
- package/lib/esm/ModuleChunkFormatPlugin.js +91 -11
- package/lib/esm/ModuleChunkLoadingPlugin.js +13 -0
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +46 -37
- package/lib/hmr/lazyCompilationBackend.js +5 -2
- package/lib/json/JsonData.js +41 -0
- package/lib/json/JsonGenerator.js +8 -2
- package/lib/json/JsonParser.js +2 -1
- package/lib/optimize/ConcatenatedModule.js +16 -0
- package/lib/optimize/RuntimeChunkPlugin.js +1 -1
- package/lib/rules/RuleSetCompiler.js +2 -2
- package/lib/serialization/BinaryMiddleware.js +26 -21
- package/lib/serialization/FileMiddleware.js +82 -6
- package/lib/util/internalSerializables.js +1 -0
- package/lib/util/makeSerializable.js +0 -1
- package/package.json +13 -13
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +15 -3
- package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.json +15 -0
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerReferencePlugin.json +2 -1
- package/schemas/plugins/container/ExternalsType.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +17 -1
- 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
|
-
"
|
175
|
+
}(chunkId)).then(installChunk, ${runtimeTemplate.basicFunction(
|
176
|
+
"e",
|
142
177
|
[
|
143
|
-
|
144
|
-
|
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
|
-
)}
|
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
|
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 =
|
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 =
|
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({
|
package/lib/json/JsonParser.js
CHANGED
@@ -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 (
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
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
|
-
|
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"),
|
package/package.json
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
{
|
2
2
|
"name": "webpack",
|
3
|
-
"version": "5.
|
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.
|
10
|
-
"@webassemblyjs/ast": "1.11.
|
11
|
-
"@webassemblyjs/wasm-edit": "1.11.
|
12
|
-
"@webassemblyjs/wasm-parser": "1.11.
|
13
|
-
"acorn": "^8.
|
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.
|
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",
|