webpack 5.52.0 → 5.55.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 +0 -0
- package/lib/AsyncDependenciesBlock.js +9 -2
- package/lib/CacheFacade.js +10 -3
- package/lib/ChunkGraph.js +19 -8
- package/lib/CodeGenerationResults.js +7 -2
- package/lib/Compilation.js +549 -144
- package/lib/Compiler.js +12 -4
- package/lib/Dependency.js +11 -0
- package/lib/DependencyTemplates.js +8 -2
- package/lib/EvalDevToolModulePlugin.js +2 -1
- package/lib/EvalSourceMapDevToolPlugin.js +2 -1
- package/lib/ExternalModule.js +18 -9
- package/lib/FileSystemInfo.js +101 -170
- package/lib/FlagDependencyExportsPlugin.js +25 -16
- package/lib/JavascriptMetaInfoPlugin.js +6 -1
- package/lib/ModuleFactory.js +1 -0
- package/lib/ModuleFilenameHelpers.js +21 -7
- package/lib/ModuleGraph.js +90 -21
- package/lib/NodeStuffInWebError.js +34 -0
- package/lib/NodeStuffPlugin.js +59 -16
- package/lib/NormalModuleFactory.js +8 -43
- package/lib/SourceMapDevToolPlugin.js +7 -3
- package/lib/WebpackOptionsApply.js +19 -1
- package/lib/cache/PackFileCacheStrategy.js +183 -53
- package/lib/cache/getLazyHashedEtag.js +35 -8
- package/lib/config/defaults.js +32 -12
- package/lib/dependencies/CachedConstDependency.js +4 -3
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -9
- package/lib/dependencies/CommonJsFullRequireDependency.js +11 -9
- package/lib/dependencies/ConstDependency.js +12 -4
- package/lib/dependencies/ContextDependency.js +8 -0
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +179 -163
- package/lib/dependencies/HarmonyImportDependency.js +4 -1
- package/lib/dependencies/JsonExportsDependency.js +7 -1
- package/lib/dependencies/ModuleDecoratorDependency.js +5 -2
- package/lib/dependencies/ModuleDependency.js +8 -0
- package/lib/dependencies/NullDependency.js +8 -4
- package/lib/dependencies/ProvidedDependency.js +6 -2
- package/lib/dependencies/PureExpressionDependency.js +5 -1
- package/lib/dependencies/RuntimeRequirementsDependency.js +5 -1
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +9 -0
- package/lib/ids/IdHelpers.js +21 -8
- package/lib/ids/NamedChunkIdsPlugin.js +3 -0
- package/lib/ids/NamedModuleIdsPlugin.js +3 -1
- package/lib/index.js +6 -0
- package/lib/javascript/BasicEvaluatedExpression.js +3 -0
- package/lib/javascript/JavascriptParser.js +22 -4
- package/lib/javascript/JavascriptParserHelpers.js +0 -2
- package/lib/node/NodeTargetPlugin.js +1 -0
- package/lib/optimize/ConcatenatedModule.js +25 -4
- package/lib/optimize/InnerGraph.js +22 -2
- package/lib/optimize/ModuleConcatenationPlugin.js +2 -1
- package/lib/runtime/RelativeUrlRuntimeModule.js +1 -1
- package/lib/schemes/HttpUriPlugin.js +1 -2
- package/lib/serialization/BinaryMiddleware.js +11 -2
- package/lib/serialization/FileMiddleware.js +24 -7
- package/lib/serialization/ObjectMiddleware.js +23 -12
- package/lib/util/WeakTupleMap.js +95 -92
- package/lib/util/createHash.js +10 -0
- package/lib/util/hash/BatchedHash.js +65 -0
- package/lib/util/hash/xxhash64.js +154 -0
- package/lib/util/internalSerializables.js +1 -0
- package/lib/util/serialization.js +10 -6
- package/package.json +11 -7
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +19 -3
- package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/HashedModuleIdsPlugin.json +20 -2
- package/schemas/plugins/IgnorePlugin.check.js +1 -1
- package/schemas/plugins/IgnorePlugin.json +4 -2
- package/types.d.ts +211 -25
@@ -76,7 +76,9 @@ makeSerializable(
|
|
76
76
|
|
77
77
|
const MIN_CONTENT_SIZE = 1024 * 1024; // 1 MB
|
78
78
|
const CONTENT_COUNT_TO_MERGE = 10;
|
79
|
+
const MIN_ITEMS_IN_FRESH_PACK = 100;
|
79
80
|
const MAX_ITEMS_IN_FRESH_PACK = 50000;
|
81
|
+
const MAX_TIME_IN_FRESH_PACK = 1 * 60 * 1000; // 1 min
|
80
82
|
|
81
83
|
class PackItemInfo {
|
82
84
|
/**
|
@@ -99,6 +101,7 @@ class Pack {
|
|
99
101
|
this.itemInfo = new Map();
|
100
102
|
/** @type {string[]} */
|
101
103
|
this.requests = [];
|
104
|
+
this.requestsTimeout = undefined;
|
102
105
|
/** @type {Map<string, PackItemInfo>} */
|
103
106
|
this.freshContent = new Map();
|
104
107
|
/** @type {(undefined | PackContent)[]} */
|
@@ -108,6 +111,24 @@ class Pack {
|
|
108
111
|
this.maxAge = maxAge;
|
109
112
|
}
|
110
113
|
|
114
|
+
_addRequest(identifier) {
|
115
|
+
this.requests.push(identifier);
|
116
|
+
if (this.requestsTimeout === undefined) {
|
117
|
+
this.requestsTimeout = setTimeout(() => {
|
118
|
+
this.requests.push(undefined);
|
119
|
+
this.requestsTimeout = undefined;
|
120
|
+
}, MAX_TIME_IN_FRESH_PACK);
|
121
|
+
if (this.requestsTimeout.unref) this.requestsTimeout.unref();
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
stopCapturingRequests() {
|
126
|
+
if (this.requestsTimeout !== undefined) {
|
127
|
+
clearTimeout(this.requestsTimeout);
|
128
|
+
this.requestsTimeout = undefined;
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
111
132
|
/**
|
112
133
|
* @param {string} identifier unique name for the resource
|
113
134
|
* @param {string | null} etag etag of the resource
|
@@ -115,7 +136,7 @@ class Pack {
|
|
115
136
|
*/
|
116
137
|
get(identifier, etag) {
|
117
138
|
const info = this.itemInfo.get(identifier);
|
118
|
-
this.
|
139
|
+
this._addRequest(identifier);
|
119
140
|
if (info === undefined) {
|
120
141
|
return undefined;
|
121
142
|
}
|
@@ -147,12 +168,12 @@ class Pack {
|
|
147
168
|
if (info === undefined) {
|
148
169
|
const newInfo = new PackItemInfo(identifier, etag, data);
|
149
170
|
this.itemInfo.set(identifier, newInfo);
|
150
|
-
this.
|
171
|
+
this._addRequest(identifier);
|
151
172
|
this.freshContent.set(identifier, newInfo);
|
152
173
|
} else {
|
153
174
|
const loc = info.location;
|
154
175
|
if (loc >= 0) {
|
155
|
-
this.
|
176
|
+
this._addRequest(identifier);
|
156
177
|
this.freshContent.set(identifier, info);
|
157
178
|
const content = this.content[loc];
|
158
179
|
content.delete(identifier);
|
@@ -220,27 +241,39 @@ class Pack {
|
|
220
241
|
}
|
221
242
|
|
222
243
|
_persistFreshContent() {
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
);
|
227
|
-
const
|
228
|
-
|
229
|
-
|
244
|
+
const itemsCount = this.freshContent.size;
|
245
|
+
if (itemsCount > 0) {
|
246
|
+
const packCount = Math.ceil(itemsCount / MAX_ITEMS_IN_FRESH_PACK);
|
247
|
+
const itemsPerPack = Math.ceil(itemsCount / packCount);
|
248
|
+
const packs = [];
|
249
|
+
let i = 0;
|
250
|
+
let ignoreNextTimeTick = false;
|
251
|
+
const createNextPack = () => {
|
230
252
|
const loc = this._findLocation();
|
231
253
|
this.content[loc] = null; // reserve
|
232
|
-
|
254
|
+
const pack = {
|
233
255
|
/** @type {Set<string>} */
|
234
256
|
items: new Set(),
|
235
257
|
/** @type {Map<string, any>} */
|
236
258
|
map: new Map(),
|
237
259
|
loc
|
238
260
|
};
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
let
|
261
|
+
packs.push(pack);
|
262
|
+
return pack;
|
263
|
+
};
|
264
|
+
let pack = createNextPack();
|
265
|
+
if (this.requestsTimeout !== undefined)
|
266
|
+
clearTimeout(this.requestsTimeout);
|
243
267
|
for (const identifier of this.requests) {
|
268
|
+
if (identifier === undefined) {
|
269
|
+
if (ignoreNextTimeTick) {
|
270
|
+
ignoreNextTimeTick = false;
|
271
|
+
} else if (pack.items.size >= MIN_ITEMS_IN_FRESH_PACK) {
|
272
|
+
i = 0;
|
273
|
+
pack = createNextPack();
|
274
|
+
}
|
275
|
+
continue;
|
276
|
+
}
|
244
277
|
const info = this.freshContent.get(identifier);
|
245
278
|
if (info === undefined) continue;
|
246
279
|
pack.items.add(identifier);
|
@@ -250,9 +283,11 @@ class Pack {
|
|
250
283
|
this.freshContent.delete(identifier);
|
251
284
|
if (++i > itemsPerPack) {
|
252
285
|
i = 0;
|
253
|
-
pack =
|
286
|
+
pack = createNextPack();
|
287
|
+
ignoreNextTimeTick = true;
|
254
288
|
}
|
255
289
|
}
|
290
|
+
this.requests.length = 0;
|
256
291
|
for (const pack of packs) {
|
257
292
|
this.content[pack.loc] = new PackContent(
|
258
293
|
pack.items,
|
@@ -260,6 +295,15 @@ class Pack {
|
|
260
295
|
new PackContentItems(pack.map)
|
261
296
|
);
|
262
297
|
}
|
298
|
+
this.logger.log(
|
299
|
+
`${itemsCount} fresh items in cache put into pack ${
|
300
|
+
packs.length > 1
|
301
|
+
? packs
|
302
|
+
.map(pack => `${pack.loc} (${pack.items.size} items)`)
|
303
|
+
.join(", ")
|
304
|
+
: packs[0].loc
|
305
|
+
}`
|
306
|
+
);
|
263
307
|
}
|
264
308
|
}
|
265
309
|
|
@@ -332,7 +376,9 @@ class Pack {
|
|
332
376
|
addToMergedMap.push(async map => {
|
333
377
|
// unpack existing content
|
334
378
|
// after that values are accessible in .content
|
335
|
-
await content.unpack(
|
379
|
+
await content.unpack(
|
380
|
+
"it should be merged with other small pack contents"
|
381
|
+
);
|
336
382
|
for (const [identifier, value] of content.content) {
|
337
383
|
map.set(identifier, value);
|
338
384
|
}
|
@@ -392,7 +438,9 @@ class Pack {
|
|
392
438
|
usedItems,
|
393
439
|
new Set(usedItems),
|
394
440
|
async () => {
|
395
|
-
await content.unpack(
|
441
|
+
await content.unpack(
|
442
|
+
"it should be splitted into used and unused items"
|
443
|
+
);
|
396
444
|
const map = new Map();
|
397
445
|
for (const identifier of usedItems) {
|
398
446
|
map.set(identifier, content.content.get(identifier));
|
@@ -417,7 +465,9 @@ class Pack {
|
|
417
465
|
unusedItems,
|
418
466
|
usedOfUnusedItems,
|
419
467
|
async () => {
|
420
|
-
await content.unpack(
|
468
|
+
await content.unpack(
|
469
|
+
"it should be splitted into used and unused items"
|
470
|
+
);
|
421
471
|
const map = new Map();
|
422
472
|
for (const identifier of unusedItems) {
|
423
473
|
map.set(identifier, content.content.get(identifier));
|
@@ -466,7 +516,9 @@ class Pack {
|
|
466
516
|
this.content[loc] =
|
467
517
|
items.size > 0
|
468
518
|
? new PackContent(items, usedItems, async () => {
|
469
|
-
await content.unpack(
|
519
|
+
await content.unpack(
|
520
|
+
"it contains old items that should be garbage collected"
|
521
|
+
);
|
470
522
|
const map = new Map();
|
471
523
|
for (const identifier of items) {
|
472
524
|
map.set(identifier, content.content.get(identifier));
|
@@ -496,7 +548,7 @@ class Pack {
|
|
496
548
|
const content = this.content[i];
|
497
549
|
if (content !== undefined) {
|
498
550
|
write(content.items);
|
499
|
-
|
551
|
+
content.writeLazy(lazy => writeSeparate(lazy, { name: `${i}` }));
|
500
552
|
} else {
|
501
553
|
write(undefined); // undefined marks an empty content slot
|
502
554
|
}
|
@@ -669,6 +721,25 @@ makeSerializable(
|
|
669
721
|
);
|
670
722
|
|
671
723
|
class PackContent {
|
724
|
+
/*
|
725
|
+
This class can be in these states:
|
726
|
+
| this.lazy | this.content | this.outdated | state
|
727
|
+
A1 | undefined | Map | false | fresh content
|
728
|
+
A2 | undefined | Map | true | (will not happen)
|
729
|
+
B1 | lazy () => {} | undefined | false | not deserialized
|
730
|
+
B2 | lazy () => {} | undefined | true | not deserialized, but some items has been removed
|
731
|
+
C1 | lazy* () => {} | Map | false | deserialized
|
732
|
+
C2 | lazy* () => {} | Map | true | deserialized, and some items has been removed
|
733
|
+
|
734
|
+
this.used is a subset of this.items.
|
735
|
+
this.items is a subset of this.content.keys() resp. this.lazy().map.keys()
|
736
|
+
When this.outdated === false, this.items === this.content.keys() resp. this.lazy().map.keys()
|
737
|
+
When this.outdated === true, this.items should be used to recreated this.lazy/this.content.
|
738
|
+
When this.lazy and this.content is set, they contain the same data.
|
739
|
+
this.get must only be called with a valid item from this.items.
|
740
|
+
In state C this.lazy is unMemoized
|
741
|
+
*/
|
742
|
+
|
672
743
|
/**
|
673
744
|
* @param {Set<string>} items keys
|
674
745
|
* @param {Set<string>} usedItems used keys
|
@@ -678,7 +749,7 @@ class PackContent {
|
|
678
749
|
*/
|
679
750
|
constructor(items, usedItems, dataOrFn, logger, lazyName) {
|
680
751
|
this.items = items;
|
681
|
-
/** @type {function(): Promise<PackContentItems> | PackContentItems
|
752
|
+
/** @type {function(): Promise<PackContentItems> | PackContentItems} */
|
682
753
|
this.lazy = typeof dataOrFn === "function" ? dataOrFn : undefined;
|
683
754
|
/** @type {Map<string, any>} */
|
684
755
|
this.content = typeof dataOrFn === "function" ? undefined : dataOrFn.map;
|
@@ -693,6 +764,8 @@ class PackContent {
|
|
693
764
|
if (this.content) {
|
694
765
|
return this.content.get(identifier);
|
695
766
|
}
|
767
|
+
|
768
|
+
// We are in state B
|
696
769
|
const { lazyName } = this;
|
697
770
|
let timeMessage;
|
698
771
|
if (lazyName) {
|
@@ -715,6 +788,7 @@ class PackContent {
|
|
715
788
|
if (timeMessage) {
|
716
789
|
this.logger.timeEnd(timeMessage);
|
717
790
|
}
|
791
|
+
// Move to state C
|
718
792
|
this.content = map;
|
719
793
|
this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy);
|
720
794
|
return map.get(identifier);
|
@@ -724,6 +798,7 @@ class PackContent {
|
|
724
798
|
if (timeMessage) {
|
725
799
|
this.logger.timeEnd(timeMessage);
|
726
800
|
}
|
801
|
+
// Move to state C
|
727
802
|
this.content = map;
|
728
803
|
this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy);
|
729
804
|
return map.get(identifier);
|
@@ -731,10 +806,13 @@ class PackContent {
|
|
731
806
|
}
|
732
807
|
|
733
808
|
/**
|
809
|
+
* @param {string} reason explanation why unpack is necessary
|
734
810
|
* @returns {void | Promise} maybe a promise if lazy
|
735
811
|
*/
|
736
|
-
unpack() {
|
812
|
+
unpack(reason) {
|
737
813
|
if (this.content) return;
|
814
|
+
|
815
|
+
// Move from state B to C
|
738
816
|
if (this.lazy) {
|
739
817
|
const { lazyName } = this;
|
740
818
|
let timeMessage;
|
@@ -744,6 +822,11 @@ class PackContent {
|
|
744
822
|
timeMessage = `unpack cache content ${lazyName} (${formatSize(
|
745
823
|
this.getSize()
|
746
824
|
)})`;
|
825
|
+
this.logger.log(
|
826
|
+
`starting to unpack cache content ${lazyName} (${formatSize(
|
827
|
+
this.getSize()
|
828
|
+
)}) because ${reason}`
|
829
|
+
);
|
747
830
|
this.logger.time(timeMessage);
|
748
831
|
}
|
749
832
|
const value = this.lazy();
|
@@ -782,48 +865,93 @@ class PackContent {
|
|
782
865
|
}
|
783
866
|
|
784
867
|
/**
|
785
|
-
* @
|
868
|
+
* @template T
|
869
|
+
* @param {function(any): function(): Promise<PackContentItems> | PackContentItems} write write function
|
870
|
+
* @returns {void}
|
786
871
|
*/
|
787
|
-
|
788
|
-
if (!this.outdated && this.lazy)
|
872
|
+
writeLazy(write) {
|
873
|
+
if (!this.outdated && this.lazy) {
|
874
|
+
// State B1 or C1
|
875
|
+
// this.lazy is still the valid deserialized version
|
876
|
+
write(this.lazy);
|
877
|
+
return;
|
878
|
+
}
|
789
879
|
if (!this.outdated && this.content) {
|
880
|
+
// State A1
|
790
881
|
const map = new Map(this.content);
|
791
|
-
|
882
|
+
// Move to state C1
|
883
|
+
this.lazy = SerializerMiddleware.unMemoizeLazy(
|
884
|
+
write(() => new PackContentItems(map))
|
885
|
+
);
|
886
|
+
return;
|
792
887
|
}
|
793
|
-
this.outdated = false;
|
794
888
|
if (this.content) {
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
889
|
+
// State A2 or C2
|
890
|
+
/** @type {Map<string, any>} */
|
891
|
+
const map = new Map();
|
892
|
+
for (const item of this.items) {
|
893
|
+
map.set(item, this.content.get(item));
|
894
|
+
}
|
895
|
+
// Move to state C1
|
896
|
+
this.outdated = false;
|
897
|
+
this.content = map;
|
898
|
+
this.lazy = SerializerMiddleware.unMemoizeLazy(
|
899
|
+
write(() => new PackContentItems(map))
|
900
|
+
);
|
901
|
+
return;
|
803
902
|
}
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
903
|
+
// State B2
|
904
|
+
const { lazyName } = this;
|
905
|
+
let timeMessage;
|
906
|
+
if (lazyName) {
|
907
|
+
// only log once
|
908
|
+
this.lazyName = undefined;
|
909
|
+
timeMessage = `unpack cache content ${lazyName} (${formatSize(
|
910
|
+
this.getSize()
|
911
|
+
)})`;
|
912
|
+
this.logger.log(
|
913
|
+
`starting to unpack cache content ${lazyName} (${formatSize(
|
914
|
+
this.getSize()
|
915
|
+
)}) because it's outdated and need to be serialized`
|
916
|
+
);
|
917
|
+
this.logger.time(timeMessage);
|
918
|
+
}
|
919
|
+
const value = this.lazy();
|
920
|
+
this.outdated = false;
|
921
|
+
if (value instanceof Promise) {
|
922
|
+
// Move to state B1
|
923
|
+
this.lazy = write(() =>
|
924
|
+
value.then(data => {
|
925
|
+
if (timeMessage) {
|
926
|
+
this.logger.timeEnd(timeMessage);
|
927
|
+
}
|
809
928
|
const oldMap = data.map;
|
810
929
|
/** @type {Map<string, any>} */
|
811
930
|
const map = new Map();
|
812
931
|
for (const item of this.items) {
|
813
932
|
map.set(item, oldMap.get(item));
|
814
933
|
}
|
934
|
+
// Move to state C1 (or maybe C2)
|
935
|
+
this.content = map;
|
936
|
+
this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy);
|
937
|
+
|
815
938
|
return new PackContentItems(map);
|
816
|
-
})
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
map.set(item, oldMap.get(item));
|
823
|
-
}
|
824
|
-
return new PackContentItems(map);
|
939
|
+
})
|
940
|
+
);
|
941
|
+
} else {
|
942
|
+
// Move to state C1
|
943
|
+
if (timeMessage) {
|
944
|
+
this.logger.timeEnd(timeMessage);
|
825
945
|
}
|
826
|
-
|
946
|
+
const oldMap = value.map;
|
947
|
+
/** @type {Map<string, any>} */
|
948
|
+
const map = new Map();
|
949
|
+
for (const item of this.items) {
|
950
|
+
map.set(item, oldMap.get(item));
|
951
|
+
}
|
952
|
+
this.content = map;
|
953
|
+
this.lazy = write(() => new PackContentItems(map));
|
954
|
+
}
|
827
955
|
}
|
828
956
|
}
|
829
957
|
|
@@ -867,7 +995,8 @@ class PackFileCacheStrategy {
|
|
867
995
|
this.fileSystemInfo = new FileSystemInfo(fs, {
|
868
996
|
managedPaths: snapshot.managedPaths,
|
869
997
|
immutablePaths: snapshot.immutablePaths,
|
870
|
-
logger: logger.getChildLogger("webpack.FileSystemInfo")
|
998
|
+
logger: logger.getChildLogger("webpack.FileSystemInfo"),
|
999
|
+
hashFunction: compiler.options.output.hashFunction
|
871
1000
|
});
|
872
1001
|
this.compiler = compiler;
|
873
1002
|
this.context = context;
|
@@ -1110,10 +1239,11 @@ class PackFileCacheStrategy {
|
|
1110
1239
|
const packPromise = this.packPromise;
|
1111
1240
|
if (packPromise === undefined) return Promise.resolve();
|
1112
1241
|
const reportProgress = ProgressPlugin.getReporter(this.compiler);
|
1113
|
-
this.packPromise = undefined;
|
1114
1242
|
return (this.storePromise = packPromise
|
1115
1243
|
.then(pack => {
|
1244
|
+
pack.stopCapturingRequests();
|
1116
1245
|
if (!pack.invalid) return;
|
1246
|
+
this.packPromise = undefined;
|
1117
1247
|
this.logger.log(`Storing pack...`);
|
1118
1248
|
let promise;
|
1119
1249
|
const newBuildDependencies = new Set();
|
@@ -8,6 +8,7 @@
|
|
8
8
|
const createHash = require("../util/createHash");
|
9
9
|
|
10
10
|
/** @typedef {import("../util/Hash")} Hash */
|
11
|
+
/** @typedef {typeof import("../util/Hash")} HashConstructor */
|
11
12
|
|
12
13
|
/**
|
13
14
|
* @typedef {Object} HashableObject
|
@@ -17,10 +18,12 @@ const createHash = require("../util/createHash");
|
|
17
18
|
class LazyHashedEtag {
|
18
19
|
/**
|
19
20
|
* @param {HashableObject} obj object with updateHash method
|
21
|
+
* @param {string | HashConstructor} hashFunction the hash function to use
|
20
22
|
*/
|
21
|
-
constructor(obj) {
|
23
|
+
constructor(obj, hashFunction = "md4") {
|
22
24
|
this._obj = obj;
|
23
25
|
this._hash = undefined;
|
26
|
+
this._hashFunction = hashFunction;
|
24
27
|
}
|
25
28
|
|
26
29
|
/**
|
@@ -28,7 +31,7 @@ class LazyHashedEtag {
|
|
28
31
|
*/
|
29
32
|
toString() {
|
30
33
|
if (this._hash === undefined) {
|
31
|
-
const hash = createHash(
|
34
|
+
const hash = createHash(this._hashFunction);
|
32
35
|
this._obj.updateHash(hash);
|
33
36
|
this._hash = /** @type {string} */ (hash.digest("base64"));
|
34
37
|
}
|
@@ -36,18 +39,42 @@ class LazyHashedEtag {
|
|
36
39
|
}
|
37
40
|
}
|
38
41
|
|
39
|
-
/** @type {WeakMap<HashableObject, LazyHashedEtag
|
40
|
-
const
|
42
|
+
/** @type {Map<string | HashConstructor, WeakMap<HashableObject, LazyHashedEtag>>} */
|
43
|
+
const mapStrings = new Map();
|
44
|
+
|
45
|
+
/** @type {WeakMap<HashConstructor, WeakMap<HashableObject, LazyHashedEtag>>} */
|
46
|
+
const mapObjects = new WeakMap();
|
41
47
|
|
42
48
|
/**
|
43
49
|
* @param {HashableObject} obj object with updateHash method
|
50
|
+
* @param {string | HashConstructor} hashFunction the hash function to use
|
44
51
|
* @returns {LazyHashedEtag} etag
|
45
52
|
*/
|
46
|
-
const getter = obj => {
|
47
|
-
|
53
|
+
const getter = (obj, hashFunction = "md4") => {
|
54
|
+
let innerMap;
|
55
|
+
if (typeof hashFunction === "string") {
|
56
|
+
innerMap = mapStrings.get(hashFunction);
|
57
|
+
if (innerMap === undefined) {
|
58
|
+
const newHash = new LazyHashedEtag(obj, hashFunction);
|
59
|
+
innerMap = new WeakMap();
|
60
|
+
innerMap.set(obj, newHash);
|
61
|
+
mapStrings.set(hashFunction, innerMap);
|
62
|
+
return newHash;
|
63
|
+
}
|
64
|
+
} else {
|
65
|
+
innerMap = mapObjects.get(hashFunction);
|
66
|
+
if (innerMap === undefined) {
|
67
|
+
const newHash = new LazyHashedEtag(obj, hashFunction);
|
68
|
+
innerMap = new WeakMap();
|
69
|
+
innerMap.set(obj, newHash);
|
70
|
+
mapObjects.set(hashFunction, innerMap);
|
71
|
+
return newHash;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
const hash = innerMap.get(obj);
|
48
75
|
if (hash !== undefined) return hash;
|
49
|
-
const newHash = new LazyHashedEtag(obj);
|
50
|
-
|
76
|
+
const newHash = new LazyHashedEtag(obj, hashFunction);
|
77
|
+
innerMap.set(obj, newHash);
|
51
78
|
return newHash;
|
52
79
|
};
|
53
80
|
|
package/lib/config/defaults.js
CHANGED
@@ -159,20 +159,21 @@ const applyWebpackOptionsDefaults = options => {
|
|
159
159
|
D(options, "recordsInputPath", false);
|
160
160
|
D(options, "recordsOutputPath", false);
|
161
161
|
|
162
|
+
applyExperimentsDefaults(options.experiments, { production, development });
|
163
|
+
|
162
164
|
F(options, "cache", () =>
|
163
165
|
development ? { type: /** @type {"memory"} */ ("memory") } : false
|
164
166
|
);
|
165
167
|
applyCacheDefaults(options.cache, {
|
166
168
|
name: name || "default",
|
167
169
|
mode: mode || "production",
|
168
|
-
development
|
170
|
+
development,
|
171
|
+
cacheUnaffected: options.experiments.cacheUnaffected
|
169
172
|
});
|
170
173
|
const cache = !!options.cache;
|
171
174
|
|
172
175
|
applySnapshotDefaults(options.snapshot, { production });
|
173
176
|
|
174
|
-
applyExperimentsDefaults(options.experiments, { production, development });
|
175
|
-
|
176
177
|
applyModuleDefaults(options.module, {
|
177
178
|
cache,
|
178
179
|
syncWebAssembly: options.experiments.syncWebAssembly,
|
@@ -190,7 +191,8 @@ const applyWebpackOptionsDefaults = options => {
|
|
190
191
|
outputModule: options.experiments.outputModule,
|
191
192
|
development,
|
192
193
|
entry: options.entry,
|
193
|
-
module: options.module
|
194
|
+
module: options.module,
|
195
|
+
futureDefaults: options.experiments.futureDefaults
|
194
196
|
});
|
195
197
|
|
196
198
|
applyExternalsPresetsDefaults(options.externalsPresets, {
|
@@ -211,7 +213,10 @@ const applyWebpackOptionsDefaults = options => {
|
|
211
213
|
: "var";
|
212
214
|
});
|
213
215
|
|
214
|
-
applyNodeDefaults(options.node, {
|
216
|
+
applyNodeDefaults(options.node, {
|
217
|
+
futureDefaults: options.experiments.futureDefaults,
|
218
|
+
targetProperties
|
219
|
+
});
|
215
220
|
|
216
221
|
F(options, "performance", () =>
|
217
222
|
production &&
|
@@ -262,6 +267,8 @@ const applyExperimentsDefaults = (experiments, { production, development }) => {
|
|
262
267
|
D(experiments, "layers", false);
|
263
268
|
D(experiments, "lazyCompilation", false);
|
264
269
|
D(experiments, "buildHttp", false);
|
270
|
+
D(experiments, "futureDefaults", false);
|
271
|
+
D(experiments, "cacheUnaffected", experiments.futureDefaults);
|
265
272
|
|
266
273
|
if (typeof experiments.buildHttp === "object") {
|
267
274
|
D(experiments.buildHttp, "frozen", production);
|
@@ -275,9 +282,13 @@ const applyExperimentsDefaults = (experiments, { production, development }) => {
|
|
275
282
|
* @param {string} options.name name
|
276
283
|
* @param {string} options.mode mode
|
277
284
|
* @param {boolean} options.development is development mode
|
285
|
+
* @param {boolean} options.cacheUnaffected the cacheUnaffected experiment is enabled
|
278
286
|
* @returns {void}
|
279
287
|
*/
|
280
|
-
const applyCacheDefaults = (
|
288
|
+
const applyCacheDefaults = (
|
289
|
+
cache,
|
290
|
+
{ name, mode, development, cacheUnaffected }
|
291
|
+
) => {
|
281
292
|
if (cache === false) return;
|
282
293
|
switch (cache.type) {
|
283
294
|
case "filesystem":
|
@@ -321,12 +332,14 @@ const applyCacheDefaults = (cache, { name, mode, development }) => {
|
|
321
332
|
D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
|
322
333
|
D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
|
323
334
|
D(cache, "allowCollectingMemory", development);
|
335
|
+
D(cache, "memoryCacheUnaffected", development && cacheUnaffected);
|
324
336
|
D(cache.buildDependencies, "defaultWebpack", [
|
325
337
|
path.resolve(__dirname, "..") + path.sep
|
326
338
|
]);
|
327
339
|
break;
|
328
340
|
case "memory":
|
329
341
|
D(cache, "maxGenerations", Infinity);
|
342
|
+
D(cache, "cacheUnaffected", development && cacheUnaffected);
|
330
343
|
break;
|
331
344
|
}
|
332
345
|
};
|
@@ -576,6 +589,7 @@ const applyModuleDefaults = (
|
|
576
589
|
* @param {boolean} options.development is development mode
|
577
590
|
* @param {Entry} options.entry entry option
|
578
591
|
* @param {ModuleOptions} options.module module option
|
592
|
+
* @param {boolean} options.futureDefaults is future defaults enabled
|
579
593
|
* @returns {void}
|
580
594
|
*/
|
581
595
|
const applyOutputDefaults = (
|
@@ -587,7 +601,8 @@ const applyOutputDefaults = (
|
|
587
601
|
outputModule,
|
588
602
|
development,
|
589
603
|
entry,
|
590
|
-
module
|
604
|
+
module,
|
605
|
+
futureDefaults
|
591
606
|
}
|
592
607
|
) => {
|
593
608
|
/**
|
@@ -784,7 +799,7 @@ const applyOutputDefaults = (
|
|
784
799
|
: ""
|
785
800
|
);
|
786
801
|
D(output, "chunkLoadTimeout", 120000);
|
787
|
-
D(output, "hashFunction", "md4");
|
802
|
+
D(output, "hashFunction", futureDefaults ? "xxhash64" : "md4");
|
788
803
|
D(output, "hashDigest", "hex");
|
789
804
|
D(output, "hashDigestLength", 20);
|
790
805
|
D(output, "strictModuleExceptionHandling", false);
|
@@ -943,21 +958,26 @@ const applyLoaderDefaults = (loader, { targetProperties }) => {
|
|
943
958
|
* @param {WebpackNode} node options
|
944
959
|
* @param {Object} options options
|
945
960
|
* @param {TargetProperties | false} options.targetProperties target properties
|
961
|
+
* @param {boolean} options.futureDefaults is future defaults enabled
|
946
962
|
* @returns {void}
|
947
963
|
*/
|
948
|
-
const applyNodeDefaults = (node, { targetProperties }) => {
|
964
|
+
const applyNodeDefaults = (node, { futureDefaults, targetProperties }) => {
|
949
965
|
if (node === false) return;
|
966
|
+
|
950
967
|
F(node, "global", () => {
|
951
968
|
if (targetProperties && targetProperties.global) return false;
|
952
|
-
|
969
|
+
// TODO webpack 6 should always default to false
|
970
|
+
return futureDefaults ? "warn" : true;
|
953
971
|
});
|
954
972
|
F(node, "__filename", () => {
|
955
973
|
if (targetProperties && targetProperties.node) return "eval-only";
|
956
|
-
|
974
|
+
// TODO webpack 6 should always default to false
|
975
|
+
return futureDefaults ? "warn-mock" : "mock";
|
957
976
|
});
|
958
977
|
F(node, "__dirname", () => {
|
959
978
|
if (targetProperties && targetProperties.node) return "eval-only";
|
960
|
-
|
979
|
+
// TODO webpack 6 should always default to false
|
980
|
+
return futureDefaults ? "warn-mock" : "mock";
|
961
981
|
});
|
962
982
|
};
|
963
983
|
|
@@ -27,6 +27,7 @@ class CachedConstDependency extends NullDependency {
|
|
27
27
|
this.expression = expression;
|
28
28
|
this.range = range;
|
29
29
|
this.identifier = identifier;
|
30
|
+
this._hashUpdate = undefined;
|
30
31
|
}
|
31
32
|
|
32
33
|
/**
|
@@ -36,9 +37,9 @@ class CachedConstDependency extends NullDependency {
|
|
36
37
|
* @returns {void}
|
37
38
|
*/
|
38
39
|
updateHash(hash, context) {
|
39
|
-
|
40
|
-
|
41
|
-
hash.update(this.
|
40
|
+
if (this._hashUpdate === undefined)
|
41
|
+
this._hashUpdate = "" + this.identifier + this.range + this.expression;
|
42
|
+
hash.update(this._hashUpdate);
|
42
43
|
}
|
43
44
|
|
44
45
|
serialize(context) {
|