webpack 5.100.0 → 5.100.2
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.
- package/lib/Compilation.js +1 -1
- package/lib/Dependency.js +5 -3
- package/lib/IgnorePlugin.js +4 -1
- package/lib/ModuleGraph.js +77 -0
- package/lib/NormalModule.js +5 -1
- package/lib/NormalModuleFactory.js +5 -1
- package/lib/RawModule.js +14 -0
- package/lib/RuntimeTemplate.js +12 -23
- package/lib/WebpackOptionsApply.js +7 -0
- package/lib/asset/AssetGenerator.js +2 -2
- package/lib/async-modules/AsyncModuleHelpers.js +50 -0
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -12
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +5 -29
- package/lib/dependencies/ModuleDependency.js +3 -1
- package/lib/javascript/JavascriptParser.js +10 -5
- package/lib/optimize/SideEffectsFlagPlugin.js +17 -1
- package/lib/rules/RuleSetCompiler.js +13 -2
- package/lib/rules/UseEffectRulePlugin.js +14 -8
- package/lib/stats/DefaultStatsFactoryPlugin.js +1 -0
- package/lib/stats/DefaultStatsPresetPlugin.js +9 -11
- package/lib/stats/StatsFactory.js +2 -1
- package/lib/stats/StatsPrinter.js +3 -5
- package/lib/util/cleverMerge.js +84 -51
- package/lib/util/comparators.js +99 -0
- package/package.json +5 -5
- package/types.d.ts +52 -63
|
@@ -182,7 +182,7 @@ const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => {
|
|
|
182
182
|
/** @typedef {keyof NormalizedStatsOptions} DefaultsKeys */
|
|
183
183
|
/** @typedef {{ [Key in DefaultsKeys]: (options: Partial<NormalizedStatsOptions>, context: CreateStatsOptionsContext, compilation: Compilation) => NormalizedStatsOptions[Key] | RequestShortener }} Defaults */
|
|
184
184
|
|
|
185
|
-
/** @type {
|
|
185
|
+
/** @type {Defaults} */
|
|
186
186
|
const DEFAULTS = {
|
|
187
187
|
context: (options, context, compilation) => compilation.compiler.context,
|
|
188
188
|
requestShortener: (options, context, compilation) =>
|
|
@@ -307,9 +307,9 @@ const normalizeFilter = item => {
|
|
|
307
307
|
};
|
|
308
308
|
|
|
309
309
|
/** @typedef {keyof (KnownNormalizedStatsOptions | StatsOptions)} NormalizerKeys */
|
|
310
|
-
/** @typedef {{ [Key in NormalizerKeys]
|
|
310
|
+
/** @typedef {{ [Key in NormalizerKeys]?: (value: StatsOptions[Key]) => KnownNormalizedStatsOptions[Key] }} Normalizers */
|
|
311
311
|
|
|
312
|
-
/** @type {
|
|
312
|
+
/** @type {Normalizers} */
|
|
313
313
|
const NORMALIZER = {
|
|
314
314
|
excludeModules: value => {
|
|
315
315
|
if (!Array.isArray(value)) {
|
|
@@ -391,18 +391,16 @@ class DefaultStatsPresetPlugin {
|
|
|
391
391
|
compilation.hooks.statsNormalize.tap(PLUGIN_NAME, (options, context) => {
|
|
392
392
|
for (const key of Object.keys(DEFAULTS)) {
|
|
393
393
|
if (options[key] === undefined) {
|
|
394
|
-
options[key] =
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
compilation
|
|
400
|
-
);
|
|
394
|
+
options[key] = DEFAULTS[/** @type {DefaultsKeys} */ (key)](
|
|
395
|
+
options,
|
|
396
|
+
context,
|
|
397
|
+
compilation
|
|
398
|
+
);
|
|
401
399
|
}
|
|
402
400
|
}
|
|
403
401
|
for (const key of Object.keys(NORMALIZER)) {
|
|
404
402
|
options[key] =
|
|
405
|
-
/** @type {
|
|
403
|
+
/** @type {NonNullable<Normalizers[keyof Normalizers]>} */
|
|
406
404
|
(NORMALIZER[/** @type {NormalizerKeys} */ (key)])(options[key]);
|
|
407
405
|
}
|
|
408
406
|
});
|
|
@@ -121,7 +121,8 @@ class StatsFactory {
|
|
|
121
121
|
getItemFactory: new HookMap(() => new SyncBailHook(["item", "context"]))
|
|
122
122
|
});
|
|
123
123
|
const hooks = this.hooks;
|
|
124
|
-
this._caches =
|
|
124
|
+
this._caches =
|
|
125
|
+
/** @type {{ [Key in keyof StatsFactoryHooks]: Map<string, SyncBailHook<EXPECTED_ANY, EXPECTED_ANY>[]> }} */ ({});
|
|
125
126
|
for (const key of Object.keys(hooks)) {
|
|
126
127
|
this._caches[/** @type {keyof StatsFactoryHooks} */ (key)] = new Map();
|
|
127
128
|
}
|
|
@@ -102,9 +102,7 @@ class StatsPrinter {
|
|
|
102
102
|
print: new HookMap(() => new SyncBailHook(["object", "context"])),
|
|
103
103
|
result: new HookMap(() => new SyncWaterfallHook(["result", "context"]))
|
|
104
104
|
});
|
|
105
|
-
/**
|
|
106
|
-
* @type {TODO}
|
|
107
|
-
*/
|
|
105
|
+
/** @type {Map<StatsPrintHooks[keyof StatsPrintHooks], Map<string, import("tapable").Hook<EXPECTED_ANY, EXPECTED_ANY>[]>>} */
|
|
108
106
|
this._levelHookCache = new Map();
|
|
109
107
|
this._inPrint = false;
|
|
110
108
|
}
|
|
@@ -126,7 +124,7 @@ class StatsPrinter {
|
|
|
126
124
|
}
|
|
127
125
|
const cacheEntry = cache.get(type);
|
|
128
126
|
if (cacheEntry !== undefined) {
|
|
129
|
-
return cacheEntry;
|
|
127
|
+
return /** @type {H[]} */ (cacheEntry);
|
|
130
128
|
}
|
|
131
129
|
/** @type {H[]} */
|
|
132
130
|
const hooks = [];
|
|
@@ -146,7 +144,7 @@ class StatsPrinter {
|
|
|
146
144
|
* @private
|
|
147
145
|
* @template {StatsPrintHooks[keyof StatsPrintHooks]} HM
|
|
148
146
|
* @template {HM extends HookMap<infer H> ? H : never} H
|
|
149
|
-
* @template {H extends import("tapable").Hook<
|
|
147
|
+
* @template {H extends import("tapable").Hook<EXPECTED_ANY, infer R> ? R : never} R
|
|
150
148
|
* @param {HM} hookMap hook map
|
|
151
149
|
* @param {string} type type
|
|
152
150
|
* @param {(hooK: H) => R | undefined | void} fn fn
|
package/lib/util/cleverMerge.js
CHANGED
|
@@ -85,32 +85,43 @@ const cachedSetProperty = (obj, property, value) => {
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* @
|
|
89
|
-
* @typedef {Map<string, V | undefined>} ByValues
|
|
88
|
+
* @typedef {Map<string, EXPECTED_ANY>} ByValues
|
|
90
89
|
*/
|
|
91
90
|
|
|
92
91
|
/**
|
|
92
|
+
* @template T
|
|
93
93
|
* @typedef {object} ObjectParsedPropertyEntry
|
|
94
|
-
* @property {
|
|
94
|
+
* @property {T[keyof T] | undefined} base base value
|
|
95
95
|
* @property {string | undefined} byProperty the name of the selector property
|
|
96
|
-
* @property {ByValues
|
|
96
|
+
* @property {ByValues | undefined} byValues value depending on selector property, merged with base
|
|
97
97
|
*/
|
|
98
98
|
|
|
99
99
|
/** @typedef {(function(...EXPECTED_ANY): object) & { [DYNAMIC_INFO]: [DynamicFunction, object] }} DynamicFunction */
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
|
+
* @template {object} T
|
|
103
|
+
* @typedef {Map<keyof T, ObjectParsedPropertyEntry<T>>} ParsedObjectStatic
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @template {object} T
|
|
108
|
+
* @typedef {{ byProperty: string, fn: DynamicFunction }} ParsedObjectDynamic
|
|
109
|
+
*/
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @template {object} T
|
|
102
113
|
* @typedef {object} ParsedObject
|
|
103
|
-
* @property {
|
|
104
|
-
* @property {
|
|
114
|
+
* @property {ParsedObjectStatic<T>} static static properties (key is property name)
|
|
115
|
+
* @property {ParsedObjectDynamic<T> | undefined} dynamic dynamic part
|
|
105
116
|
*/
|
|
106
117
|
|
|
107
|
-
/** @type {WeakMap<EXPECTED_OBJECT, ParsedObject
|
|
118
|
+
/** @type {WeakMap<EXPECTED_OBJECT, ParsedObject<EXPECTED_ANY>>} */
|
|
108
119
|
const parseCache = new WeakMap();
|
|
109
120
|
|
|
110
121
|
/**
|
|
111
122
|
* @template {object} T
|
|
112
123
|
* @param {T} obj the object
|
|
113
|
-
* @returns {ParsedObject} parsed object
|
|
124
|
+
* @returns {ParsedObject<T>} parsed object
|
|
114
125
|
*/
|
|
115
126
|
const cachedParseObject = obj => {
|
|
116
127
|
const entry = parseCache.get(/** @type {EXPECTED_OBJECT} */ (obj));
|
|
@@ -120,18 +131,21 @@ const cachedParseObject = obj => {
|
|
|
120
131
|
return result;
|
|
121
132
|
};
|
|
122
133
|
|
|
134
|
+
/** @typedef {{ [p: string]: { [p: string]: EXPECTED_ANY } } | DynamicFunction} ByObject */
|
|
135
|
+
|
|
123
136
|
/**
|
|
124
137
|
* @template {object} T
|
|
125
|
-
* @template V
|
|
126
138
|
* @param {T} obj the object
|
|
127
|
-
* @returns {ParsedObject} parsed object
|
|
139
|
+
* @returns {ParsedObject<T>} parsed object
|
|
128
140
|
*/
|
|
129
141
|
const parseObject = obj => {
|
|
142
|
+
/** @type {ParsedObjectStatic<T>} */
|
|
130
143
|
const info = new Map();
|
|
144
|
+
/** @type {ParsedObjectDynamic<T> | undefined} */
|
|
131
145
|
let dynamicInfo;
|
|
132
146
|
/**
|
|
133
|
-
* @param {
|
|
134
|
-
* @returns {Partial<ObjectParsedPropertyEntry
|
|
147
|
+
* @param {keyof T} p path
|
|
148
|
+
* @returns {Partial<ObjectParsedPropertyEntry<T>>} object parsed property entry
|
|
135
149
|
*/
|
|
136
150
|
const getInfo = p => {
|
|
137
151
|
const entry = info.get(p);
|
|
@@ -144,37 +158,35 @@ const parseObject = obj => {
|
|
|
144
158
|
info.set(p, newEntry);
|
|
145
159
|
return newEntry;
|
|
146
160
|
};
|
|
147
|
-
for (const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const
|
|
161
|
+
for (const key_ of Object.keys(obj)) {
|
|
162
|
+
const key = /** @type {keyof T} */ (key_);
|
|
163
|
+
if (typeof key === "string" && key.startsWith("by")) {
|
|
164
|
+
const byProperty = key;
|
|
165
|
+
const byObj = /** @type {ByObject} */ (obj[byProperty]);
|
|
151
166
|
if (typeof byObj === "object") {
|
|
152
167
|
for (const byValue of Object.keys(byObj)) {
|
|
153
168
|
const obj = byObj[/** @type {keyof (keyof T)} */ (byValue)];
|
|
154
169
|
for (const key of Object.keys(obj)) {
|
|
155
|
-
const entry = getInfo(key);
|
|
170
|
+
const entry = getInfo(/** @type {keyof T} */ (key));
|
|
156
171
|
if (entry.byProperty === undefined) {
|
|
157
|
-
entry.byProperty =
|
|
172
|
+
entry.byProperty = byProperty;
|
|
158
173
|
entry.byValues = new Map();
|
|
159
174
|
} else if (entry.byProperty !== byProperty) {
|
|
160
175
|
throw new Error(
|
|
161
176
|
`${/** @type {string} */ (byProperty)} and ${entry.byProperty} for a single property is not supported`
|
|
162
177
|
);
|
|
163
178
|
}
|
|
164
|
-
/** @type {ByValues
|
|
165
|
-
(entry.byValues).set(
|
|
166
|
-
byValue,
|
|
167
|
-
obj[/** @type {keyof (keyof T)} */ (key)]
|
|
168
|
-
);
|
|
179
|
+
/** @type {ByValues} */
|
|
180
|
+
(entry.byValues).set(byValue, obj[key]);
|
|
169
181
|
if (byValue === "default") {
|
|
170
182
|
for (const otherByValue of Object.keys(byObj)) {
|
|
171
183
|
if (
|
|
172
184
|
!(
|
|
173
|
-
/** @type {ByValues
|
|
185
|
+
/** @type {ByValues} */
|
|
174
186
|
(entry.byValues).has(otherByValue)
|
|
175
187
|
)
|
|
176
188
|
) {
|
|
177
|
-
/** @type {ByValues
|
|
189
|
+
/** @type {ByValues} */
|
|
178
190
|
(entry.byValues).set(otherByValue, undefined);
|
|
179
191
|
}
|
|
180
192
|
}
|
|
@@ -194,11 +206,11 @@ const parseObject = obj => {
|
|
|
194
206
|
}
|
|
195
207
|
} else {
|
|
196
208
|
const entry = getInfo(key);
|
|
197
|
-
entry.base = obj[
|
|
209
|
+
entry.base = obj[key];
|
|
198
210
|
}
|
|
199
211
|
} else {
|
|
200
212
|
const entry = getInfo(key);
|
|
201
|
-
entry.base = obj[
|
|
213
|
+
entry.base = obj[key];
|
|
202
214
|
}
|
|
203
215
|
}
|
|
204
216
|
return {
|
|
@@ -209,8 +221,8 @@ const parseObject = obj => {
|
|
|
209
221
|
|
|
210
222
|
/**
|
|
211
223
|
* @template {object} T
|
|
212
|
-
* @param {
|
|
213
|
-
* @param {{ byProperty: string, fn:
|
|
224
|
+
* @param {ParsedObjectStatic<T>} info static properties (key is property name)
|
|
225
|
+
* @param {{ byProperty: string, fn: DynamicFunction } | undefined} dynamicInfo dynamic part
|
|
214
226
|
* @returns {T} the object
|
|
215
227
|
*/
|
|
216
228
|
const serializeObject = (info, dynamicInfo) => {
|
|
@@ -221,7 +233,7 @@ const serializeObject = (info, dynamicInfo) => {
|
|
|
221
233
|
const byProperty = /** @type {keyof T} */ (entry.byProperty);
|
|
222
234
|
const byObj = (obj[byProperty] =
|
|
223
235
|
obj[byProperty] || /** @type {TODO} */ ({}));
|
|
224
|
-
for (const byValue of entry.byValues.keys()) {
|
|
236
|
+
for (const byValue of /** @type {ByValues} */ (entry.byValues).keys()) {
|
|
225
237
|
byObj[byValue] = byObj[byValue] || {};
|
|
226
238
|
}
|
|
227
239
|
}
|
|
@@ -236,7 +248,11 @@ const serializeObject = (info, dynamicInfo) => {
|
|
|
236
248
|
const byObj = (obj[byProperty] =
|
|
237
249
|
obj[byProperty] || /** @type {TODO} */ ({}));
|
|
238
250
|
for (const byValue of Object.keys(byObj)) {
|
|
239
|
-
const value = getFromByValues(
|
|
251
|
+
const value = getFromByValues(
|
|
252
|
+
/** @type {ByValues} */
|
|
253
|
+
(entry.byValues),
|
|
254
|
+
byValue
|
|
255
|
+
);
|
|
240
256
|
if (value !== undefined) byObj[byValue][key] = value;
|
|
241
257
|
}
|
|
242
258
|
}
|
|
@@ -317,7 +333,7 @@ const _cleverMerge = (first, second, internalCaching = false) => {
|
|
|
317
333
|
const fnInfo = fn[DYNAMIC_INFO];
|
|
318
334
|
if (fnInfo) {
|
|
319
335
|
second =
|
|
320
|
-
/** @type {
|
|
336
|
+
/** @type {O} */
|
|
321
337
|
(
|
|
322
338
|
internalCaching
|
|
323
339
|
? cachedCleverMerge(fnInfo[1], second)
|
|
@@ -343,10 +359,12 @@ const _cleverMerge = (first, second, internalCaching = false) => {
|
|
|
343
359
|
? cachedParseObject(second)
|
|
344
360
|
: parseObject(second);
|
|
345
361
|
const { static: secondInfo, dynamic: secondDynamicInfo } = secondObject;
|
|
346
|
-
/** @type {Map<string, ObjectParsedPropertyEntry>} */
|
|
347
362
|
const resultInfo = new Map();
|
|
348
363
|
for (const [key, firstEntry] of firstInfo) {
|
|
349
|
-
const secondEntry = secondInfo.get(
|
|
364
|
+
const secondEntry = secondInfo.get(
|
|
365
|
+
/** @type {keyof (T | O)} */
|
|
366
|
+
(key)
|
|
367
|
+
);
|
|
350
368
|
const entry =
|
|
351
369
|
secondEntry !== undefined
|
|
352
370
|
? mergeEntries(firstEntry, secondEntry, internalCaching)
|
|
@@ -354,7 +372,7 @@ const _cleverMerge = (first, second, internalCaching = false) => {
|
|
|
354
372
|
resultInfo.set(key, entry);
|
|
355
373
|
}
|
|
356
374
|
for (const [key, secondEntry] of secondInfo) {
|
|
357
|
-
if (!firstInfo.has(key)) {
|
|
375
|
+
if (!firstInfo.has(/** @type {keyof (T | O)} */ (key))) {
|
|
358
376
|
resultInfo.set(key, secondEntry);
|
|
359
377
|
}
|
|
360
378
|
}
|
|
@@ -362,10 +380,11 @@ const _cleverMerge = (first, second, internalCaching = false) => {
|
|
|
362
380
|
};
|
|
363
381
|
|
|
364
382
|
/**
|
|
365
|
-
* @
|
|
366
|
-
* @param {ObjectParsedPropertyEntry}
|
|
383
|
+
* @template T, O
|
|
384
|
+
* @param {ObjectParsedPropertyEntry<T>} firstEntry a
|
|
385
|
+
* @param {ObjectParsedPropertyEntry<O>} secondEntry b
|
|
367
386
|
* @param {boolean} internalCaching should parsing of objects and nested merges be cached
|
|
368
|
-
* @returns {ObjectParsedPropertyEntry} new entry
|
|
387
|
+
* @returns {ObjectParsedPropertyEntry<TODO>} new entry
|
|
369
388
|
*/
|
|
370
389
|
const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
371
390
|
switch (getValueType(secondEntry.base)) {
|
|
@@ -391,8 +410,14 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
391
410
|
// = first.base + (first.byProperty + second.byProperty)
|
|
392
411
|
// need to merge first and second byValues
|
|
393
412
|
const newByValues = new Map(firstEntry.byValues);
|
|
394
|
-
for (const [key, value] of
|
|
395
|
-
|
|
413
|
+
for (const [key, value] of /** @type {ByValues} */ (
|
|
414
|
+
secondEntry.byValues
|
|
415
|
+
)) {
|
|
416
|
+
const firstValue = getFromByValues(
|
|
417
|
+
/** @type {ByValues} */
|
|
418
|
+
(firstEntry.byValues),
|
|
419
|
+
key
|
|
420
|
+
);
|
|
396
421
|
newByValues.set(
|
|
397
422
|
key,
|
|
398
423
|
mergeSingleValue(firstValue, value, internalCaching)
|
|
@@ -409,11 +434,15 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
409
434
|
// The simple case
|
|
410
435
|
// = (first.base + second.base) + second.byProperty
|
|
411
436
|
return {
|
|
412
|
-
base:
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
437
|
+
base:
|
|
438
|
+
/** @type {T[keyof T] & O[keyof O]} */
|
|
439
|
+
(
|
|
440
|
+
mergeSingleValue(
|
|
441
|
+
firstEntry.base,
|
|
442
|
+
secondEntry.base,
|
|
443
|
+
internalCaching
|
|
444
|
+
)
|
|
445
|
+
),
|
|
417
446
|
byProperty: secondEntry.byProperty,
|
|
418
447
|
byValues: secondEntry.byValues
|
|
419
448
|
};
|
|
@@ -427,10 +456,12 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
427
456
|
);
|
|
428
457
|
}
|
|
429
458
|
if (
|
|
430
|
-
[
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
459
|
+
[.../** @type {ByValues} */ (firstEntry.byValues).values()].every(
|
|
460
|
+
value => {
|
|
461
|
+
const type = getValueType(value);
|
|
462
|
+
return type === VALUE_TYPE_ATOM || type === VALUE_TYPE_DELETE;
|
|
463
|
+
}
|
|
464
|
+
)
|
|
434
465
|
) {
|
|
435
466
|
// = (first.base + second.base) + ((first.byProperty + second.base) + second.byProperty)
|
|
436
467
|
newBase = mergeSingleValue(
|
|
@@ -458,7 +489,9 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
458
489
|
);
|
|
459
490
|
}
|
|
460
491
|
const newByValues = new Map(intermediateByValues);
|
|
461
|
-
for (const [key, value] of
|
|
492
|
+
for (const [key, value] of /** @type {ByValues} */ (
|
|
493
|
+
secondEntry.byValues
|
|
494
|
+
)) {
|
|
462
495
|
const firstValue = getFromByValues(intermediateByValues, key);
|
|
463
496
|
newByValues.set(
|
|
464
497
|
key,
|
|
@@ -476,7 +509,7 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
476
509
|
|
|
477
510
|
/**
|
|
478
511
|
* @template V
|
|
479
|
-
* @param {ByValues
|
|
512
|
+
* @param {ByValues} byValues all values
|
|
480
513
|
* @param {string} key value of the selector
|
|
481
514
|
* @returns {V | undefined} value
|
|
482
515
|
*/
|
package/lib/util/comparators.js
CHANGED
|
@@ -13,9 +13,18 @@ const { compareRuntime } = require("./runtime");
|
|
|
13
13
|
/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
|
|
14
14
|
/** @typedef {import("../ChunkGroup")} ChunkGroup */
|
|
15
15
|
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
|
16
|
+
/** @typedef {import("../Dependency")} Dependency */
|
|
17
|
+
/** @typedef {import("../dependencies/HarmonyImportSideEffectDependency")} HarmonyImportSideEffectDependency */
|
|
18
|
+
/** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
|
|
16
19
|
/** @typedef {import("../Module")} Module */
|
|
17
20
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|
18
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {object} DependencySourceOrder
|
|
24
|
+
* @property {number} main the main source order
|
|
25
|
+
* @property {number} sub the sub source order
|
|
26
|
+
*/
|
|
27
|
+
|
|
19
28
|
/**
|
|
20
29
|
* @template T
|
|
21
30
|
* @typedef {(a: T, b: T) => -1 | 0 | 1} Comparator
|
|
@@ -497,6 +506,95 @@ const compareChunksNatural = chunkGraph => {
|
|
|
497
506
|
);
|
|
498
507
|
};
|
|
499
508
|
|
|
509
|
+
/**
|
|
510
|
+
* For HarmonyImportSideEffectDependency and HarmonyImportSpecifierDependency, we should prioritize import order to match the behavior of running modules directly in a JS engine without a bundler.
|
|
511
|
+
* For other types like ConstDependency, we can instead prioritize usage order.
|
|
512
|
+
* https://github.com/webpack/webpack/pull/19686
|
|
513
|
+
* @param {Dependency[]} dependencies dependencies
|
|
514
|
+
* @param {WeakMap<Dependency, DependencySourceOrder>} dependencySourceOrderMap dependency source order map
|
|
515
|
+
* @returns {void}
|
|
516
|
+
*/
|
|
517
|
+
const sortWithSourceOrder = (dependencies, dependencySourceOrderMap) => {
|
|
518
|
+
/**
|
|
519
|
+
* @param {Dependency} dep dependency
|
|
520
|
+
* @returns {number} source order
|
|
521
|
+
*/
|
|
522
|
+
const getSourceOrder = dep => {
|
|
523
|
+
if (dependencySourceOrderMap.has(dep)) {
|
|
524
|
+
const { main } = /** @type {DependencySourceOrder} */ (
|
|
525
|
+
dependencySourceOrderMap.get(dep)
|
|
526
|
+
);
|
|
527
|
+
return main;
|
|
528
|
+
}
|
|
529
|
+
return /** @type { HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */ (
|
|
530
|
+
dep
|
|
531
|
+
).sourceOrder;
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* If the sourceOrder is a number, it means the dependency needs to be sorted.
|
|
536
|
+
* @param {number | undefined} sourceOrder sourceOrder
|
|
537
|
+
* @returns {boolean} needReSort
|
|
538
|
+
*/
|
|
539
|
+
const needReSort = sourceOrder => {
|
|
540
|
+
if (typeof sourceOrder === "number") {
|
|
541
|
+
return true;
|
|
542
|
+
}
|
|
543
|
+
return false;
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
// Extract dependencies with sourceOrder and sort them
|
|
547
|
+
const withSourceOrder = [];
|
|
548
|
+
|
|
549
|
+
// First pass: collect dependencies with sourceOrder
|
|
550
|
+
for (let i = 0; i < dependencies.length; i++) {
|
|
551
|
+
const dep = dependencies[i];
|
|
552
|
+
const sourceOrder = getSourceOrder(dep);
|
|
553
|
+
|
|
554
|
+
if (needReSort(sourceOrder)) {
|
|
555
|
+
withSourceOrder.push({ dep, sourceOrder, originalIndex: i });
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (withSourceOrder.length <= 1) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Sort dependencies with sourceOrder
|
|
564
|
+
withSourceOrder.sort((a, b) => {
|
|
565
|
+
// Handle both dependencies in map case
|
|
566
|
+
if (
|
|
567
|
+
dependencySourceOrderMap.has(a.dep) &&
|
|
568
|
+
dependencySourceOrderMap.has(b.dep)
|
|
569
|
+
) {
|
|
570
|
+
const { main: mainA, sub: subA } = /** @type {DependencySourceOrder} */ (
|
|
571
|
+
dependencySourceOrderMap.get(a.dep)
|
|
572
|
+
);
|
|
573
|
+
const { main: mainB, sub: subB } = /** @type {DependencySourceOrder} */ (
|
|
574
|
+
dependencySourceOrderMap.get(b.dep)
|
|
575
|
+
);
|
|
576
|
+
if (mainA === mainB) {
|
|
577
|
+
return compareNumbers(subA, subB);
|
|
578
|
+
}
|
|
579
|
+
return compareNumbers(mainA, mainB);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return compareNumbers(a.sourceOrder, b.sourceOrder);
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
// Second pass: build result array
|
|
586
|
+
let sortedIndex = 0;
|
|
587
|
+
for (let i = 0; i < dependencies.length; i++) {
|
|
588
|
+
const dep = dependencies[i];
|
|
589
|
+
const sourceOrder = getSourceOrder(dep);
|
|
590
|
+
|
|
591
|
+
if (needReSort(sourceOrder)) {
|
|
592
|
+
dependencies[i] = withSourceOrder[sortedIndex].dep;
|
|
593
|
+
sortedIndex++;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
|
|
500
598
|
module.exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex;
|
|
501
599
|
/** @type {ParameterizedComparator<ChunkGraph, Chunk>} */
|
|
502
600
|
module.exports.compareChunks =
|
|
@@ -548,3 +646,4 @@ module.exports.compareStringsNumeric = compareStringsNumeric;
|
|
|
548
646
|
module.exports.concatComparators = concatComparators;
|
|
549
647
|
|
|
550
648
|
module.exports.keepOriginalOrder = keepOriginalOrder;
|
|
649
|
+
module.exports.sortWithSourceOrder = sortWithSourceOrder;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webpack",
|
|
3
|
-
"version": "5.100.
|
|
3
|
+
"version": "5.100.2",
|
|
4
4
|
"description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
|
|
5
5
|
"homepage": "https://github.com/webpack/webpack",
|
|
6
6
|
"bugs": "https://github.com/webpack/webpack/issues",
|
|
@@ -112,13 +112,13 @@
|
|
|
112
112
|
"@babel/preset-react": "^7.27.1",
|
|
113
113
|
"@codspeed/tinybench-plugin": "^4.0.1",
|
|
114
114
|
"@eslint/js": "^9.29.0",
|
|
115
|
-
"@eslint/markdown": "^
|
|
115
|
+
"@eslint/markdown": "^7.0.0",
|
|
116
116
|
"@stylistic/eslint-plugin": "^5.0.0",
|
|
117
117
|
"@types/glob-to-regexp": "^0.4.4",
|
|
118
118
|
"@types/graceful-fs": "^4.1.9",
|
|
119
119
|
"@types/jest": "^30.0.0",
|
|
120
120
|
"@types/mime-types": "^2.1.4",
|
|
121
|
-
"@types/node": "^24.0.
|
|
121
|
+
"@types/node": "^24.0.13",
|
|
122
122
|
"@types/xxhashjs": "^0.2.4",
|
|
123
123
|
"assemblyscript": "^0.28.2",
|
|
124
124
|
"babel-loader": "^10.0.0",
|
|
@@ -179,10 +179,10 @@
|
|
|
179
179
|
"strip-ansi": "^6.0.0",
|
|
180
180
|
"style-loader": "^4.0.0",
|
|
181
181
|
"terser": "^5.43.1",
|
|
182
|
-
"three": "^0.
|
|
182
|
+
"three": "^0.178.0",
|
|
183
183
|
"tinybench": "^4.0.1",
|
|
184
184
|
"toml": "^3.0.0",
|
|
185
|
-
"tooling": "webpack/tooling#v1.24.
|
|
185
|
+
"tooling": "webpack/tooling#v1.24.3",
|
|
186
186
|
"ts-loader": "^9.5.1",
|
|
187
187
|
"typescript": "^5.8.2",
|
|
188
188
|
"url-loader": "^4.1.0",
|