webpack 5.35.0 → 5.36.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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/lib/ChunkGraph.js +113 -30
- package/lib/Compilation.js +71 -41
- package/lib/Compiler.js +25 -11
- package/lib/ContextModuleFactory.js +4 -3
- package/lib/Dependency.js +74 -4
- package/lib/FlagDependencyExportsPlugin.js +38 -37
- package/lib/InitFragment.js +21 -6
- package/lib/ModuleGraph.js +19 -53
- package/lib/NormalModuleFactory.js +27 -23
- package/lib/WebpackOptionsApply.js +1 -0
- package/lib/buildChunkGraph.js +7 -2
- package/lib/cache/PackFileCacheStrategy.js +65 -4
- package/lib/config/defaults.js +2 -1
- package/lib/config/normalization.js +1 -0
- package/lib/dependencies/HarmonyExportInitFragment.js +47 -0
- package/lib/dependencies/NullDependency.js +0 -8
- package/lib/dependencies/WorkerPlugin.js +18 -3
- package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +7 -0
- package/lib/javascript/JavascriptModulesPlugin.js +6 -2
- package/lib/javascript/JavascriptParser.js +39 -31
- package/lib/library/AmdLibraryPlugin.js +2 -1
- package/lib/optimize/InnerGraphPlugin.js +8 -9
- package/lib/util/AsyncQueue.js +6 -1
- package/lib/util/comparators.js +22 -16
- package/lib/util/smartGrouping.js +76 -40
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +4 -2
- package/package.json +5 -5
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +4 -0
- package/types.d.ts +101 -7
package/lib/ChunkGraph.js
CHANGED
@@ -10,7 +10,6 @@ const Entrypoint = require("./Entrypoint");
|
|
10
10
|
const ModuleGraphConnection = require("./ModuleGraphConnection");
|
11
11
|
const { first } = require("./util/SetHelpers");
|
12
12
|
const SortableSet = require("./util/SortableSet");
|
13
|
-
const StringXor = require("./util/StringXor");
|
14
13
|
const {
|
15
14
|
compareModulesById,
|
16
15
|
compareIterables,
|
@@ -40,6 +39,8 @@ const {
|
|
40
39
|
/** @type {ReadonlySet<string>} */
|
41
40
|
const EMPTY_SET = new Set();
|
42
41
|
|
42
|
+
const ZERO_BIG_INT = BigInt(0);
|
43
|
+
|
43
44
|
const compareModuleIterables = compareIterables(compareModulesByIdentifier);
|
44
45
|
|
45
46
|
/** @typedef {(c: Chunk, chunkGraph: ChunkGraph) => boolean} ChunkFilterPredicate */
|
@@ -1373,8 +1374,41 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
|
|
1373
1374
|
return runtimeRequirements === undefined ? EMPTY_SET : runtimeRequirements;
|
1374
1375
|
}
|
1375
1376
|
|
1377
|
+
/**
|
1378
|
+
* @param {Module} module the module
|
1379
|
+
* @param {RuntimeSpec} runtime the runtime
|
1380
|
+
* @param {boolean} withConnections include connections
|
1381
|
+
* @returns {string} hash
|
1382
|
+
*/
|
1376
1383
|
getModuleGraphHash(module, runtime, withConnections = true) {
|
1377
1384
|
const cgm = this._getChunkGraphModule(module);
|
1385
|
+
return withConnections
|
1386
|
+
? this._getModuleGraphHashWithConnections(cgm, module, runtime)
|
1387
|
+
: this._getModuleGraphHashBigInt(cgm, module, runtime).toString(16);
|
1388
|
+
}
|
1389
|
+
|
1390
|
+
/**
|
1391
|
+
* @param {Module} module the module
|
1392
|
+
* @param {RuntimeSpec} runtime the runtime
|
1393
|
+
* @param {boolean} withConnections include connections
|
1394
|
+
* @returns {bigint} hash
|
1395
|
+
*/
|
1396
|
+
getModuleGraphHashBigInt(module, runtime, withConnections = true) {
|
1397
|
+
const cgm = this._getChunkGraphModule(module);
|
1398
|
+
return withConnections
|
1399
|
+
? BigInt(
|
1400
|
+
`0x${this._getModuleGraphHashWithConnections(cgm, module, runtime)}`
|
1401
|
+
)
|
1402
|
+
: this._getModuleGraphHashBigInt(cgm, module, runtime);
|
1403
|
+
}
|
1404
|
+
|
1405
|
+
/**
|
1406
|
+
* @param {ChunkGraphModule} cgm the ChunkGraphModule
|
1407
|
+
* @param {Module} module the module
|
1408
|
+
* @param {RuntimeSpec} runtime the runtime
|
1409
|
+
* @returns {bigint} hash as big int
|
1410
|
+
*/
|
1411
|
+
_getModuleGraphHashBigInt(cgm, module, runtime) {
|
1378
1412
|
if (cgm.graphHashes === undefined) {
|
1379
1413
|
cgm.graphHashes = new RuntimeSpecMap();
|
1380
1414
|
}
|
@@ -1383,38 +1417,72 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
|
|
1383
1417
|
hash.update(`${cgm.id}`);
|
1384
1418
|
hash.update(`${this.moduleGraph.isAsync(module)}`);
|
1385
1419
|
this.moduleGraph.getExportsInfo(module).updateHash(hash, runtime);
|
1386
|
-
return /** @type {string} */ (hash.digest("hex"));
|
1420
|
+
return BigInt(`0x${/** @type {string} */ (hash.digest("hex"))}`);
|
1387
1421
|
});
|
1388
|
-
|
1422
|
+
return graphHash;
|
1423
|
+
}
|
1424
|
+
|
1425
|
+
/**
|
1426
|
+
* @param {ChunkGraphModule} cgm the ChunkGraphModule
|
1427
|
+
* @param {Module} module the module
|
1428
|
+
* @param {RuntimeSpec} runtime the runtime
|
1429
|
+
* @returns {string} hash
|
1430
|
+
*/
|
1431
|
+
_getModuleGraphHashWithConnections(cgm, module, runtime) {
|
1389
1432
|
if (cgm.graphHashesWithConnections === undefined) {
|
1390
1433
|
cgm.graphHashesWithConnections = new RuntimeSpecMap();
|
1391
1434
|
}
|
1392
1435
|
const activeStateToString = state => {
|
1393
|
-
if (state === false) return "
|
1394
|
-
if (state === true) return "
|
1395
|
-
if (state === ModuleGraphConnection.TRANSITIVE_ONLY) return "
|
1436
|
+
if (state === false) return "F";
|
1437
|
+
if (state === true) return "T";
|
1438
|
+
if (state === ModuleGraphConnection.TRANSITIVE_ONLY) return "O";
|
1396
1439
|
throw new Error("Not implemented active state");
|
1397
1440
|
};
|
1398
1441
|
const strict = module.buildMeta && module.buildMeta.strictHarmonyModule;
|
1399
1442
|
return cgm.graphHashesWithConnections.provide(runtime, () => {
|
1443
|
+
const graphHash = this._getModuleGraphHashBigInt(
|
1444
|
+
cgm,
|
1445
|
+
module,
|
1446
|
+
runtime
|
1447
|
+
).toString(16);
|
1400
1448
|
const connections = this.moduleGraph.getOutgoingConnections(module);
|
1449
|
+
/** @type {Set<Module>} */
|
1450
|
+
const activeNamespaceModules = new Set();
|
1401
1451
|
/** @type {Map<string, Module | Set<Module>>} */
|
1402
1452
|
const connectedModules = new Map();
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1453
|
+
const processConnection = (connection, stateInfo) => {
|
1454
|
+
const module = connection.module;
|
1455
|
+
stateInfo += module.getExportsType(this.moduleGraph, strict);
|
1456
|
+
// cspell:word Tnamespace
|
1457
|
+
if (stateInfo === "Tnamespace") activeNamespaceModules.add(module);
|
1458
|
+
else {
|
1459
|
+
const oldModule = connectedModules.get(stateInfo);
|
1460
|
+
if (oldModule === undefined) {
|
1461
|
+
connectedModules.set(stateInfo, module);
|
1462
|
+
} else if (oldModule instanceof Set) {
|
1463
|
+
oldModule.add(module);
|
1464
|
+
} else if (oldModule !== module) {
|
1465
|
+
connectedModules.set(stateInfo, new Set([oldModule, module]));
|
1466
|
+
}
|
1467
|
+
}
|
1468
|
+
};
|
1469
|
+
if (runtime === undefined || typeof runtime === "string") {
|
1470
|
+
for (const connection of connections) {
|
1406
1471
|
const state = connection.getActiveState(runtime);
|
1407
1472
|
if (state === false) continue;
|
1408
|
-
|
1409
|
-
}
|
1473
|
+
processConnection(connection, state === true ? "T" : "O");
|
1474
|
+
}
|
1475
|
+
} else {
|
1476
|
+
// cspell:word Tnamespace
|
1477
|
+
for (const connection of connections) {
|
1410
1478
|
const states = new Set();
|
1411
|
-
stateInfo = "";
|
1479
|
+
let stateInfo = "";
|
1412
1480
|
forEachRuntime(
|
1413
1481
|
runtime,
|
1414
1482
|
runtime => {
|
1415
1483
|
const state = connection.getActiveState(runtime);
|
1416
1484
|
states.add(state);
|
1417
|
-
stateInfo +=
|
1485
|
+
stateInfo += activeStateToString(state) + runtime;
|
1418
1486
|
},
|
1419
1487
|
true
|
1420
1488
|
);
|
@@ -1423,34 +1491,49 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
|
|
1423
1491
|
if (state === false) continue;
|
1424
1492
|
stateInfo = activeStateToString(state);
|
1425
1493
|
}
|
1426
|
-
|
1427
|
-
const module = connection.module;
|
1428
|
-
stateInfo += module.getExportsType(this.moduleGraph, strict);
|
1429
|
-
const oldModule = connectedModules.get(stateInfo);
|
1430
|
-
if (oldModule === undefined) {
|
1431
|
-
connectedModules.set(stateInfo, module);
|
1432
|
-
} else if (oldModule instanceof Set) {
|
1433
|
-
oldModule.add(module);
|
1434
|
-
} else if (oldModule !== module) {
|
1435
|
-
connectedModules.set(stateInfo, new Set([oldModule, module]));
|
1494
|
+
processConnection(connection, stateInfo);
|
1436
1495
|
}
|
1437
1496
|
}
|
1438
|
-
|
1497
|
+
// cspell:word Tnamespace
|
1498
|
+
if (activeNamespaceModules.size === 0 && connectedModules.size === 0)
|
1499
|
+
return graphHash;
|
1439
1500
|
const connectedModulesInOrder =
|
1440
1501
|
connectedModules.size > 1
|
1441
1502
|
? Array.from(connectedModules).sort(([a], [b]) => (a < b ? -1 : 1))
|
1442
1503
|
: connectedModules;
|
1443
1504
|
const hash = createHash("md4");
|
1505
|
+
const addModuleToHash = module => {
|
1506
|
+
hash.update(
|
1507
|
+
this._getModuleGraphHashBigInt(
|
1508
|
+
this._getChunkGraphModule(module),
|
1509
|
+
module,
|
1510
|
+
runtime
|
1511
|
+
).toString(16)
|
1512
|
+
);
|
1513
|
+
};
|
1514
|
+
const addModulesToHash = modules => {
|
1515
|
+
let xor = ZERO_BIG_INT;
|
1516
|
+
for (const m of modules) {
|
1517
|
+
xor =
|
1518
|
+
xor ^
|
1519
|
+
this._getModuleGraphHashBigInt(
|
1520
|
+
this._getChunkGraphModule(m),
|
1521
|
+
m,
|
1522
|
+
runtime
|
1523
|
+
);
|
1524
|
+
}
|
1525
|
+
hash.update(xor.toString(16));
|
1526
|
+
};
|
1527
|
+
if (activeNamespaceModules.size === 1)
|
1528
|
+
addModuleToHash(activeNamespaceModules.values().next().value);
|
1529
|
+
else if (activeNamespaceModules.size > 1)
|
1530
|
+
addModulesToHash(activeNamespaceModules);
|
1444
1531
|
for (const [stateInfo, modules] of connectedModulesInOrder) {
|
1445
1532
|
hash.update(stateInfo);
|
1446
1533
|
if (modules instanceof Set) {
|
1447
|
-
|
1448
|
-
for (const m of modules) {
|
1449
|
-
xor.add(this.getModuleGraphHash(m, runtime, false));
|
1450
|
-
}
|
1451
|
-
xor.updateHash(hash);
|
1534
|
+
addModulesToHash(modules);
|
1452
1535
|
} else {
|
1453
|
-
|
1536
|
+
addModuleToHash(modules);
|
1454
1537
|
}
|
1455
1538
|
}
|
1456
1539
|
hash.update(graphHash);
|
package/lib/Compilation.js
CHANGED
@@ -1375,84 +1375,114 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1375
1375
|
* @returns {void}
|
1376
1376
|
*/
|
1377
1377
|
_processModuleDependencies(module, callback) {
|
1378
|
-
const dependencies = new Map();
|
1379
|
-
|
1380
1378
|
/**
|
1381
1379
|
* @type {Array<{factory: ModuleFactory, dependencies: Dependency[], originModule: Module|null}>}
|
1382
1380
|
*/
|
1383
1381
|
const sortedDependencies = [];
|
1384
1382
|
|
1385
|
-
|
1383
|
+
/** @type {DependenciesBlock} */
|
1384
|
+
let currentBlock;
|
1386
1385
|
|
1386
|
+
/** @type {Map<ModuleFactory, Map<string, Dependency[]>>} */
|
1387
|
+
let dependencies;
|
1388
|
+
/** @type {DepConstructor} */
|
1387
1389
|
let factoryCacheKey;
|
1390
|
+
/** @type {ModuleFactory} */
|
1391
|
+
let factoryCacheKey2;
|
1392
|
+
/** @type {Map<string, Dependency[]>} */
|
1388
1393
|
let factoryCacheValue;
|
1389
|
-
|
1390
|
-
let
|
1394
|
+
/** @type {string} */
|
1395
|
+
let listCacheKey1;
|
1396
|
+
/** @type {string} */
|
1397
|
+
let listCacheKey2;
|
1398
|
+
/** @type {Dependency[]} */
|
1391
1399
|
let listCacheValue;
|
1392
1400
|
|
1401
|
+
/**
|
1402
|
+
* @param {Dependency} dep dependency
|
1403
|
+
* @returns {void}
|
1404
|
+
*/
|
1393
1405
|
const processDependency = dep => {
|
1394
1406
|
this.moduleGraph.setParents(dep, currentBlock, module);
|
1395
1407
|
const resourceIdent = dep.getResourceIdentifier();
|
1396
|
-
if (resourceIdent) {
|
1397
|
-
// Here webpack is using heuristic that assumes
|
1398
|
-
// mostly esm dependencies would be used
|
1399
|
-
// so we don't allocate extra string for them
|
1408
|
+
if (resourceIdent !== undefined && resourceIdent !== null) {
|
1400
1409
|
const category = dep.category;
|
1401
|
-
const
|
1402
|
-
category === esmDependencyCategory
|
1403
|
-
? resourceIdent
|
1404
|
-
: `${category}${resourceIdent}`;
|
1405
|
-
const constructor = dep.constructor;
|
1406
|
-
let innerMap;
|
1407
|
-
let factory;
|
1410
|
+
const constructor = /** @type {DepConstructor} */ (dep.constructor);
|
1408
1411
|
if (factoryCacheKey === constructor) {
|
1409
|
-
|
1410
|
-
if (
|
1412
|
+
// Fast path 1: same constructor as prev item
|
1413
|
+
if (listCacheKey1 === category && listCacheKey2 === resourceIdent) {
|
1414
|
+
// Super fast path 1: also same resource
|
1411
1415
|
listCacheValue.push(dep);
|
1412
1416
|
return;
|
1413
1417
|
}
|
1414
1418
|
} else {
|
1415
|
-
factory = this.dependencyFactories.get(
|
1419
|
+
const factory = this.dependencyFactories.get(constructor);
|
1416
1420
|
if (factory === undefined) {
|
1417
1421
|
throw new Error(
|
1418
|
-
`No module factory available for dependency type: ${
|
1422
|
+
`No module factory available for dependency type: ${constructor.name}`
|
1419
1423
|
);
|
1420
1424
|
}
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1425
|
+
if (factoryCacheKey2 === factory) {
|
1426
|
+
// Fast path 2: same factory as prev item
|
1427
|
+
factoryCacheKey = constructor;
|
1428
|
+
if (listCacheKey1 === category && listCacheKey2 === resourceIdent) {
|
1429
|
+
// Super fast path 2: also same resource
|
1430
|
+
listCacheValue.push(dep);
|
1431
|
+
return;
|
1432
|
+
}
|
1433
|
+
} else {
|
1434
|
+
// Slow path
|
1435
|
+
if (factoryCacheKey2 !== undefined) {
|
1436
|
+
// Archive last cache entry
|
1437
|
+
if (dependencies === undefined) dependencies = new Map();
|
1438
|
+
dependencies.set(factoryCacheKey2, factoryCacheValue);
|
1439
|
+
factoryCacheValue = dependencies.get(factory);
|
1440
|
+
if (factoryCacheValue === undefined) {
|
1441
|
+
factoryCacheValue = new Map();
|
1442
|
+
}
|
1443
|
+
} else {
|
1444
|
+
factoryCacheValue = new Map();
|
1445
|
+
}
|
1446
|
+
factoryCacheKey = constructor;
|
1447
|
+
factoryCacheKey2 = factory;
|
1424
1448
|
}
|
1425
|
-
factoryCacheKey = constructor;
|
1426
|
-
factoryCacheValue = innerMap;
|
1427
|
-
factoryCacheValue2 = factory;
|
1428
1449
|
}
|
1429
|
-
|
1450
|
+
// Here webpack is using heuristic that assumes
|
1451
|
+
// mostly esm dependencies would be used
|
1452
|
+
// so we don't allocate extra string for them
|
1453
|
+
const cacheKey =
|
1454
|
+
category === esmDependencyCategory
|
1455
|
+
? resourceIdent
|
1456
|
+
: `${category}${resourceIdent}`;
|
1457
|
+
let list = factoryCacheValue.get(cacheKey);
|
1430
1458
|
if (list === undefined) {
|
1431
|
-
|
1459
|
+
factoryCacheValue.set(cacheKey, (list = []));
|
1432
1460
|
sortedDependencies.push({
|
1433
|
-
factory:
|
1461
|
+
factory: factoryCacheKey2,
|
1434
1462
|
dependencies: list,
|
1435
1463
|
originModule: module
|
1436
1464
|
});
|
1437
1465
|
}
|
1438
1466
|
list.push(dep);
|
1439
|
-
|
1467
|
+
listCacheKey1 = category;
|
1468
|
+
listCacheKey2 = resourceIdent;
|
1440
1469
|
listCacheValue = list;
|
1441
1470
|
}
|
1442
1471
|
};
|
1443
1472
|
|
1444
|
-
const processDependenciesBlock = block => {
|
1445
|
-
if (block.dependencies) {
|
1446
|
-
currentBlock = block;
|
1447
|
-
for (const dep of block.dependencies) processDependency(dep);
|
1448
|
-
}
|
1449
|
-
if (block.blocks) {
|
1450
|
-
for (const b of block.blocks) processDependenciesBlock(b);
|
1451
|
-
}
|
1452
|
-
};
|
1453
|
-
|
1454
1473
|
try {
|
1455
|
-
|
1474
|
+
/** @type {DependenciesBlock[]} */
|
1475
|
+
const queue = [module];
|
1476
|
+
do {
|
1477
|
+
const block = queue.pop();
|
1478
|
+
if (block.dependencies) {
|
1479
|
+
currentBlock = block;
|
1480
|
+
for (const dep of block.dependencies) processDependency(dep);
|
1481
|
+
}
|
1482
|
+
if (block.blocks) {
|
1483
|
+
for (const b of block.blocks) queue.push(b);
|
1484
|
+
}
|
1485
|
+
} while (queue.length !== 0);
|
1456
1486
|
} catch (e) {
|
1457
1487
|
return callback(e);
|
1458
1488
|
}
|
package/lib/Compiler.js
CHANGED
@@ -263,6 +263,8 @@ class Compiler {
|
|
263
263
|
this._assetEmittingSourceCache = new WeakMap();
|
264
264
|
/** @private @type {Map<string, number>} */
|
265
265
|
this._assetEmittingWrittenFiles = new Map();
|
266
|
+
/** @private @type {Set<string>} */
|
267
|
+
this._assetEmittingPreviousFiles = new Set();
|
266
268
|
}
|
267
269
|
|
268
270
|
/**
|
@@ -556,6 +558,8 @@ class Compiler {
|
|
556
558
|
compilation.assets = { ...compilation.assets };
|
557
559
|
/** @type {Map<string, { path: string, source: Source, size: number, waiting: { cacheEntry: any, file: string }[] }>} */
|
558
560
|
const caseInsensitiveMap = new Map();
|
561
|
+
/** @type {Set<string>} */
|
562
|
+
const allTargetPaths = new Set();
|
559
563
|
asyncLib.forEachLimit(
|
560
564
|
assets,
|
561
565
|
15,
|
@@ -583,6 +587,7 @@ class Compiler {
|
|
583
587
|
outputPath,
|
584
588
|
targetFile
|
585
589
|
);
|
590
|
+
allTargetPaths.add(targetPath);
|
586
591
|
|
587
592
|
// check if the target file has already been written by this Compiler
|
588
593
|
const targetFileGeneration = this._assetEmittingWrittenFiles.get(
|
@@ -775,18 +780,22 @@ ${other}`);
|
|
775
780
|
// check if the Source has been written to this target file
|
776
781
|
const writtenGeneration = cacheEntry.writtenTo.get(targetPath);
|
777
782
|
if (writtenGeneration === targetFileGeneration) {
|
778
|
-
// if yes, we skip writing the file
|
779
|
-
//
|
780
|
-
// (we assume one doesn't
|
783
|
+
// if yes, we may skip writing the file
|
784
|
+
// if it's already there
|
785
|
+
// (we assume one doesn't modify files while the Compiler is running, other then removing them)
|
781
786
|
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
}
|
787
|
+
if (this._assetEmittingPreviousFiles.has(targetPath)) {
|
788
|
+
// We assume that assets from the last compilation say intact on disk (they are not removed)
|
789
|
+
compilation.updateAsset(file, cacheEntry.sizeOnlySource, {
|
790
|
+
size: cacheEntry.sizeOnlySource.size()
|
791
|
+
});
|
788
792
|
|
789
|
-
|
793
|
+
return callback();
|
794
|
+
} else {
|
795
|
+
// Settings immutable will make it accept file content without comparing when file exist
|
796
|
+
immutable = true;
|
797
|
+
}
|
798
|
+
} else if (!immutable) {
|
790
799
|
if (checkSimilarFile()) return;
|
791
800
|
// We wrote to this file before which has very likely a different content
|
792
801
|
// skip comparing and assume content is different for performance
|
@@ -822,7 +831,12 @@ ${other}`);
|
|
822
831
|
err => {
|
823
832
|
// Clear map to free up memory
|
824
833
|
caseInsensitiveMap.clear();
|
825
|
-
if (err)
|
834
|
+
if (err) {
|
835
|
+
this._assetEmittingPreviousFiles.clear();
|
836
|
+
return callback(err);
|
837
|
+
}
|
838
|
+
|
839
|
+
this._assetEmittingPreviousFiles = allTargetPaths;
|
826
840
|
|
827
841
|
this.hooks.afterEmit.callAsync(compilation, err => {
|
828
842
|
if (err) return callback(err);
|
@@ -10,6 +10,7 @@ const { AsyncSeriesWaterfallHook, SyncWaterfallHook } = require("tapable");
|
|
10
10
|
const ContextModule = require("./ContextModule");
|
11
11
|
const ModuleFactory = require("./ModuleFactory");
|
12
12
|
const ContextElementDependency = require("./dependencies/ContextElementDependency");
|
13
|
+
const LazySet = require("./util/LazySet");
|
13
14
|
const { cachedSetProperty } = require("./util/cleverMerge");
|
14
15
|
const { createFakeHook } = require("./util/deprecation");
|
15
16
|
const { join } = require("./util/fs");
|
@@ -87,9 +88,9 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
|
|
87
88
|
const dependencies = data.dependencies;
|
88
89
|
const resolveOptions = data.resolveOptions;
|
89
90
|
const dependency = /** @type {ContextDependency} */ (dependencies[0]);
|
90
|
-
const fileDependencies = new
|
91
|
-
const missingDependencies = new
|
92
|
-
const contextDependencies = new
|
91
|
+
const fileDependencies = new LazySet();
|
92
|
+
const missingDependencies = new LazySet();
|
93
|
+
const contextDependencies = new LazySet();
|
93
94
|
this.hooks.beforeResolve.callAsync(
|
94
95
|
{
|
95
96
|
context: context,
|
package/lib/Dependency.js
CHANGED
@@ -9,6 +9,7 @@ const memoize = require("./util/memoize");
|
|
9
9
|
|
10
10
|
/** @typedef {import("webpack-sources").Source} Source */
|
11
11
|
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
12
|
+
/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
|
12
13
|
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
|
13
14
|
/** @typedef {import("./Module")} Module */
|
14
15
|
/** @typedef {import("./ModuleGraph")} ModuleGraph */
|
@@ -84,14 +85,23 @@ const getIgnoredModule = memoize(() => {
|
|
84
85
|
|
85
86
|
class Dependency {
|
86
87
|
constructor() {
|
88
|
+
/** @type {Module} */
|
89
|
+
this._parentModule = undefined;
|
90
|
+
/** @type {DependenciesBlock} */
|
91
|
+
this._parentDependenciesBlock = undefined;
|
87
92
|
// TODO check if this can be moved into ModuleDependency
|
88
93
|
/** @type {boolean} */
|
89
94
|
this.weak = false;
|
90
95
|
// TODO check if this can be moved into ModuleDependency
|
91
96
|
/** @type {boolean} */
|
92
97
|
this.optional = false;
|
93
|
-
|
94
|
-
this.
|
98
|
+
this._locSL = 0;
|
99
|
+
this._locSC = 0;
|
100
|
+
this._locEL = 0;
|
101
|
+
this._locEC = 0;
|
102
|
+
this._locI = undefined;
|
103
|
+
this._locN = undefined;
|
104
|
+
this._loc = undefined;
|
95
105
|
}
|
96
106
|
|
97
107
|
/**
|
@@ -108,6 +118,56 @@ class Dependency {
|
|
108
118
|
return "unknown";
|
109
119
|
}
|
110
120
|
|
121
|
+
/**
|
122
|
+
* @returns {DependencyLocation} location
|
123
|
+
*/
|
124
|
+
get loc() {
|
125
|
+
if (this._loc !== undefined) return this._loc;
|
126
|
+
/** @type {SyntheticDependencyLocation & RealDependencyLocation} */
|
127
|
+
const loc = {};
|
128
|
+
if (this._locSL > 0) {
|
129
|
+
loc.start = { line: this._locSL, column: this._locSC };
|
130
|
+
}
|
131
|
+
if (this._locEL > 0) {
|
132
|
+
loc.end = { line: this._locEL, column: this._locEC };
|
133
|
+
}
|
134
|
+
if (this._locN !== undefined) {
|
135
|
+
loc.name = this._locN;
|
136
|
+
}
|
137
|
+
if (this._locI !== undefined) {
|
138
|
+
loc.index = this._locI;
|
139
|
+
}
|
140
|
+
return (this._loc = loc);
|
141
|
+
}
|
142
|
+
|
143
|
+
set loc(loc) {
|
144
|
+
if ("start" in loc && typeof loc.start === "object") {
|
145
|
+
this._locSL = loc.start.line || 0;
|
146
|
+
this._locSC = loc.start.column || 0;
|
147
|
+
} else {
|
148
|
+
this._locSL = 0;
|
149
|
+
this._locSC = 0;
|
150
|
+
}
|
151
|
+
if ("end" in loc && typeof loc.end === "object") {
|
152
|
+
this._locEL = loc.end.line || 0;
|
153
|
+
this._locEC = loc.end.column || 0;
|
154
|
+
} else {
|
155
|
+
this._locEL = 0;
|
156
|
+
this._locEC = 0;
|
157
|
+
}
|
158
|
+
if ("index" in loc) {
|
159
|
+
this._locI = loc.index;
|
160
|
+
} else {
|
161
|
+
this._locI = undefined;
|
162
|
+
}
|
163
|
+
if ("name" in loc) {
|
164
|
+
this._locN = loc.name;
|
165
|
+
} else {
|
166
|
+
this._locN = undefined;
|
167
|
+
}
|
168
|
+
this._loc = loc;
|
169
|
+
}
|
170
|
+
|
111
171
|
/**
|
112
172
|
* @returns {string | null} an identifier to merge equal requests
|
113
173
|
*/
|
@@ -207,13 +267,23 @@ class Dependency {
|
|
207
267
|
serialize({ write }) {
|
208
268
|
write(this.weak);
|
209
269
|
write(this.optional);
|
210
|
-
write(this.
|
270
|
+
write(this._locSL);
|
271
|
+
write(this._locSC);
|
272
|
+
write(this._locEL);
|
273
|
+
write(this._locEC);
|
274
|
+
write(this._locI);
|
275
|
+
write(this._locN);
|
211
276
|
}
|
212
277
|
|
213
278
|
deserialize({ read }) {
|
214
279
|
this.weak = read();
|
215
280
|
this.optional = read();
|
216
|
-
this.
|
281
|
+
this._locSL = read();
|
282
|
+
this._locSC = read();
|
283
|
+
this._locEL = read();
|
284
|
+
this._locEC = read();
|
285
|
+
this._locI = read();
|
286
|
+
this._locN = read();
|
217
287
|
}
|
218
288
|
}
|
219
289
|
|
@@ -35,6 +35,7 @@ class FlagDependencyExportsPlugin {
|
|
35
35
|
"webpack.FlagDependencyExportsPlugin"
|
36
36
|
);
|
37
37
|
let statRestoredFromCache = 0;
|
38
|
+
let statNoExports = 0;
|
38
39
|
let statFlaggedUncached = 0;
|
39
40
|
let statNotCached = 0;
|
40
41
|
let statQueueItemsProcessed = 0;
|
@@ -47,6 +48,16 @@ class FlagDependencyExportsPlugin {
|
|
47
48
|
asyncLib.each(
|
48
49
|
modules,
|
49
50
|
(module, callback) => {
|
51
|
+
const exportsInfo = moduleGraph.getExportsInfo(module);
|
52
|
+
if (!module.buildMeta || !module.buildMeta.exportsType) {
|
53
|
+
if (exportsInfo.otherExportsInfo.provided !== null) {
|
54
|
+
// It's a module without declared exports
|
55
|
+
statNoExports++;
|
56
|
+
exportsInfo.setHasProvideInfo();
|
57
|
+
exportsInfo.setUnknownExportsProvided();
|
58
|
+
return callback();
|
59
|
+
}
|
60
|
+
}
|
50
61
|
if (
|
51
62
|
module.buildInfo.cacheable !== true ||
|
52
63
|
typeof module.buildInfo.hash !== "string"
|
@@ -54,7 +65,7 @@ class FlagDependencyExportsPlugin {
|
|
54
65
|
statFlaggedUncached++;
|
55
66
|
// Enqueue uncacheable module for determining the exports
|
56
67
|
queue.enqueue(module);
|
57
|
-
|
68
|
+
exportsInfo.setHasProvideInfo();
|
58
69
|
return callback();
|
59
70
|
}
|
60
71
|
cache.get(
|
@@ -72,7 +83,7 @@ class FlagDependencyExportsPlugin {
|
|
72
83
|
statNotCached++;
|
73
84
|
// Without cached info enqueue module for determining the exports
|
74
85
|
queue.enqueue(module);
|
75
|
-
|
86
|
+
exportsInfo.setHasProvideInfo();
|
76
87
|
}
|
77
88
|
callback();
|
78
89
|
}
|
@@ -300,49 +311,39 @@ class FlagDependencyExportsPlugin {
|
|
300
311
|
statQueueItemsProcessed++;
|
301
312
|
|
302
313
|
exportsInfo = moduleGraph.getExportsInfo(module);
|
303
|
-
if (!module.buildMeta || !module.buildMeta.exportsType) {
|
304
|
-
if (exportsInfo.otherExportsInfo.provided !== null) {
|
305
|
-
// It's a module without declared exports
|
306
|
-
exportsInfo.setUnknownExportsProvided();
|
307
|
-
modulesToStore.add(module);
|
308
|
-
notifyDependencies();
|
309
|
-
}
|
310
|
-
} else {
|
311
|
-
// It's a module with declared exports
|
312
|
-
|
313
|
-
cacheable = true;
|
314
|
-
changed = false;
|
315
|
-
|
316
|
-
exportsSpecsFromDependencies.clear();
|
317
|
-
moduleGraph.freeze();
|
318
|
-
processDependenciesBlock(module);
|
319
|
-
moduleGraph.unfreeze();
|
320
|
-
for (const [
|
321
|
-
dep,
|
322
|
-
exportsSpec
|
323
|
-
] of exportsSpecsFromDependencies) {
|
324
|
-
processExportsSpec(dep, exportsSpec);
|
325
|
-
}
|
326
314
|
|
327
|
-
|
328
|
-
|
329
|
-
|
315
|
+
cacheable = true;
|
316
|
+
changed = false;
|
317
|
+
|
318
|
+
exportsSpecsFromDependencies.clear();
|
319
|
+
moduleGraph.freeze();
|
320
|
+
processDependenciesBlock(module);
|
321
|
+
moduleGraph.unfreeze();
|
322
|
+
for (const [
|
323
|
+
dep,
|
324
|
+
exportsSpec
|
325
|
+
] of exportsSpecsFromDependencies) {
|
326
|
+
processExportsSpec(dep, exportsSpec);
|
327
|
+
}
|
330
328
|
|
331
|
-
|
332
|
-
|
333
|
-
|
329
|
+
if (cacheable) {
|
330
|
+
modulesToStore.add(module);
|
331
|
+
}
|
332
|
+
|
333
|
+
if (changed) {
|
334
|
+
notifyDependencies();
|
334
335
|
}
|
335
336
|
}
|
336
337
|
logger.timeEnd("figure out provided exports");
|
337
338
|
|
338
339
|
logger.log(
|
339
340
|
`${Math.round(
|
340
|
-
100
|
341
|
-
(
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
)}% of exports of modules have been determined (${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${
|
341
|
+
(100 * (statFlaggedUncached + statNotCached)) /
|
342
|
+
(statRestoredFromCache +
|
343
|
+
statNotCached +
|
344
|
+
statFlaggedUncached +
|
345
|
+
statNoExports)
|
346
|
+
)}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${
|
346
347
|
statQueueItemsProcessed -
|
347
348
|
statNotCached -
|
348
349
|
statFlaggedUncached
|