webpack 5.53.0 → 5.56.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/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 +586 -143
- package/lib/Compiler.js +13 -4
- package/lib/DefinePlugin.js +13 -8
- 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/NormalModuleFactory.js +8 -43
- package/lib/SourceMapDevToolPlugin.js +7 -3
- package/lib/WebpackOptionsApply.js +19 -1
- package/lib/cache/PackFileCacheStrategy.js +2 -1
- package/lib/cache/getLazyHashedEtag.js +35 -8
- package/lib/config/defaults.js +18 -7
- 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/optimize/ConcatenatedModule.js +25 -4
- package/lib/optimize/InnerGraph.js +22 -2
- package/lib/optimize/ModuleConcatenationPlugin.js +2 -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 +19 -8
- 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/serialization.js +4 -4
- package/package.json +10 -6
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +12 -0
- package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/HashedModuleIdsPlugin.json +20 -2
- package/types.d.ts +205 -20
package/lib/Compilation.js
CHANGED
@@ -25,6 +25,7 @@ const ChunkRenderError = require("./ChunkRenderError");
|
|
25
25
|
const ChunkTemplate = require("./ChunkTemplate");
|
26
26
|
const CodeGenerationError = require("./CodeGenerationError");
|
27
27
|
const CodeGenerationResults = require("./CodeGenerationResults");
|
28
|
+
const Dependency = require("./Dependency");
|
28
29
|
const DependencyTemplates = require("./DependencyTemplates");
|
29
30
|
const Entrypoint = require("./Entrypoint");
|
30
31
|
const ErrorHelpers = require("./ErrorHelpers");
|
@@ -60,6 +61,7 @@ const { equals: arrayEquals } = require("./util/ArrayHelpers");
|
|
60
61
|
const AsyncQueue = require("./util/AsyncQueue");
|
61
62
|
const LazySet = require("./util/LazySet");
|
62
63
|
const { provide } = require("./util/MapHelpers");
|
64
|
+
const WeakTupleMap = require("./util/WeakTupleMap");
|
63
65
|
const { cachedCleverMerge } = require("./util/cleverMerge");
|
64
66
|
const {
|
65
67
|
compareLocations,
|
@@ -91,8 +93,8 @@ const { isSourceEqual } = require("./util/source");
|
|
91
93
|
/** @typedef {import("./CacheFacade")} CacheFacade */
|
92
94
|
/** @typedef {import("./ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */
|
93
95
|
/** @typedef {import("./Compiler")} Compiler */
|
96
|
+
/** @typedef {import("./Compiler").CompilationParams} CompilationParams */
|
94
97
|
/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
|
95
|
-
/** @typedef {import("./Dependency")} Dependency */
|
96
98
|
/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
|
97
99
|
/** @typedef {import("./Dependency").ReferencedExport} ReferencedExport */
|
98
100
|
/** @typedef {import("./DependencyTemplate")} DependencyTemplate */
|
@@ -100,6 +102,7 @@ const { isSourceEqual } = require("./util/source");
|
|
100
102
|
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
|
101
103
|
/** @typedef {import("./ModuleFactory")} ModuleFactory */
|
102
104
|
/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */
|
105
|
+
/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
|
103
106
|
/** @typedef {import("./RequestShortener")} RequestShortener */
|
104
107
|
/** @typedef {import("./RuntimeModule")} RuntimeModule */
|
105
108
|
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry */
|
@@ -124,6 +127,20 @@ const { isSourceEqual } = require("./util/source");
|
|
124
127
|
* @returns {void}
|
125
128
|
*/
|
126
129
|
|
130
|
+
/**
|
131
|
+
* @callback ModuleFactoryResultCallback
|
132
|
+
* @param {WebpackError=} err
|
133
|
+
* @param {ModuleFactoryResult=} result
|
134
|
+
* @returns {void}
|
135
|
+
*/
|
136
|
+
|
137
|
+
/**
|
138
|
+
* @callback ModuleOrFactoryResultCallback
|
139
|
+
* @param {WebpackError=} err
|
140
|
+
* @param {Module | ModuleFactoryResult=} result
|
141
|
+
* @returns {void}
|
142
|
+
*/
|
143
|
+
|
127
144
|
/**
|
128
145
|
* @callback ExecuteModuleCallback
|
129
146
|
* @param {WebpackError=} err
|
@@ -399,12 +416,19 @@ const byLocation = compareSelect(err => err.loc, compareLocations);
|
|
399
416
|
|
400
417
|
const compareErrors = concatComparators(byModule, byLocation, byMessage);
|
401
418
|
|
419
|
+
/** @type {WeakMap<Dependency, Module & { restoreFromUnsafeCache: Function }>} */
|
420
|
+
const unsafeCacheDependencies = new WeakMap();
|
421
|
+
|
422
|
+
/** @type {WeakMap<Module, object>} */
|
423
|
+
const unsafeCacheData = new WeakMap();
|
424
|
+
|
402
425
|
class Compilation {
|
403
426
|
/**
|
404
427
|
* Creates an instance of Compilation.
|
405
428
|
* @param {Compiler} compiler the compiler which created the compilation
|
429
|
+
* @param {CompilationParams} params the compilation parameters
|
406
430
|
*/
|
407
|
-
constructor(compiler) {
|
431
|
+
constructor(compiler, params) {
|
408
432
|
const getNormalModuleLoader = () => deprecatedNormalModuleLoaderHook(this);
|
409
433
|
/** @typedef {{ additionalAssets?: true | Function }} ProcessAssetsAdditionalOptions */
|
410
434
|
/** @type {AsyncSeriesHook<[CompilationAssets], ProcessAssetsAdditionalOptions>} */
|
@@ -852,7 +876,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
852
876
|
this.fileSystemInfo = new FileSystemInfo(this.inputFileSystem, {
|
853
877
|
managedPaths: compiler.managedPaths,
|
854
878
|
immutablePaths: compiler.immutablePaths,
|
855
|
-
logger: this.getLogger("webpack.FileSystemInfo")
|
879
|
+
logger: this.getLogger("webpack.FileSystemInfo"),
|
880
|
+
hashFunction: compiler.options.output.hashFunction
|
856
881
|
});
|
857
882
|
if (compiler.fileTimestamps) {
|
858
883
|
this.fileSystemInfo.addFileTimestamps(compiler.fileTimestamps, true);
|
@@ -878,6 +903,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
878
903
|
/** @type {boolean} */
|
879
904
|
this.profile = (options && options.profile) || false;
|
880
905
|
|
906
|
+
this.params = params;
|
881
907
|
this.mainTemplate = new MainTemplate(this.outputOptions, this);
|
882
908
|
this.chunkTemplate = new ChunkTemplate(this.outputOptions, this);
|
883
909
|
this.runtimeTemplate = new RuntimeTemplate(
|
@@ -891,6 +917,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
891
917
|
};
|
892
918
|
defineRemovedModuleTemplates(this.moduleTemplates);
|
893
919
|
|
920
|
+
/** @type {WeakMap<Module, WeakTupleMap<any, any>> | undefined} */
|
921
|
+
this.moduleMemCaches = undefined;
|
894
922
|
this.moduleGraph = new ModuleGraph();
|
895
923
|
/** @type {ChunkGraph} */
|
896
924
|
this.chunkGraph = undefined;
|
@@ -910,7 +938,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
910
938
|
getKey: module => module.identifier(),
|
911
939
|
processor: this._addModule.bind(this)
|
912
940
|
});
|
913
|
-
/** @type {AsyncQueue<FactorizeModuleOptions, string, Module>} */
|
941
|
+
/** @type {AsyncQueue<FactorizeModuleOptions, string, Module | ModuleFactoryResult>} */
|
914
942
|
this.factorizeQueue = new AsyncQueue({
|
915
943
|
name: "factorize",
|
916
944
|
parent: this.addModuleQueue,
|
@@ -993,6 +1021,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
993
1021
|
this.usedModuleIds = null;
|
994
1022
|
/** @type {boolean} */
|
995
1023
|
this.needAdditionalPass = false;
|
1024
|
+
/** @type {Set<Module>} */
|
1025
|
+
this._restoredUnsafeCacheEntries = new Set();
|
996
1026
|
/** @type {WeakSet<Module>} */
|
997
1027
|
this.builtModules = new WeakSet();
|
998
1028
|
/** @type {WeakSet<Module>} */
|
@@ -1025,6 +1055,11 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1025
1055
|
this._modulesCache = this.getCache("Compilation/modules");
|
1026
1056
|
this._assetsCache = this.getCache("Compilation/assets");
|
1027
1057
|
this._codeGenerationCache = this.getCache("Compilation/codeGeneration");
|
1058
|
+
|
1059
|
+
const unsafeCache = options.module.unsafeCache;
|
1060
|
+
this._unsafeCache = !!unsafeCache;
|
1061
|
+
this._unsafeCachePredicate =
|
1062
|
+
typeof unsafeCache === "function" ? unsafeCache : () => true;
|
1028
1063
|
}
|
1029
1064
|
|
1030
1065
|
getStats() {
|
@@ -1409,12 +1444,44 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1409
1444
|
/** @type {Dependency[]} */
|
1410
1445
|
let listCacheValue;
|
1411
1446
|
|
1447
|
+
const unsafeRestoredModules = new Set();
|
1448
|
+
|
1412
1449
|
/**
|
1413
1450
|
* @param {Dependency} dep dependency
|
1414
1451
|
* @returns {void}
|
1415
1452
|
*/
|
1416
1453
|
const processDependency = dep => {
|
1417
1454
|
this.moduleGraph.setParents(dep, currentBlock, module);
|
1455
|
+
if (this._unsafeCache) {
|
1456
|
+
try {
|
1457
|
+
const cachedModule = unsafeCacheDependencies.get(dep);
|
1458
|
+
if (cachedModule === null) return;
|
1459
|
+
if (cachedModule !== undefined) {
|
1460
|
+
if (!this._restoredUnsafeCacheEntries.has(cachedModule)) {
|
1461
|
+
const data = unsafeCacheData.get(cachedModule);
|
1462
|
+
cachedModule.restoreFromUnsafeCache(
|
1463
|
+
data,
|
1464
|
+
this.params.normalModuleFactory,
|
1465
|
+
this.params
|
1466
|
+
);
|
1467
|
+
this._restoredUnsafeCacheEntries.add(cachedModule);
|
1468
|
+
if (!this.modules.has(cachedModule)) {
|
1469
|
+
this._handleNewModuleFromUnsafeCache(module, dep, cachedModule);
|
1470
|
+
unsafeRestoredModules.add(cachedModule);
|
1471
|
+
return;
|
1472
|
+
}
|
1473
|
+
}
|
1474
|
+
this._handleExistingModuleFromUnsafeCache(
|
1475
|
+
module,
|
1476
|
+
dep,
|
1477
|
+
cachedModule
|
1478
|
+
);
|
1479
|
+
return;
|
1480
|
+
}
|
1481
|
+
} catch (e) {
|
1482
|
+
console.error(e);
|
1483
|
+
}
|
1484
|
+
}
|
1418
1485
|
const resourceIdent = dep.getResourceIdentifier();
|
1419
1486
|
if (resourceIdent !== undefined && resourceIdent !== null) {
|
1420
1487
|
const category = dep.category;
|
@@ -1498,7 +1565,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1498
1565
|
return callback(e);
|
1499
1566
|
}
|
1500
1567
|
|
1501
|
-
if (sortedDependencies.length === 0) {
|
1568
|
+
if (sortedDependencies.length === 0 && unsafeRestoredModules.size === 0) {
|
1502
1569
|
callback();
|
1503
1570
|
return;
|
1504
1571
|
}
|
@@ -1506,27 +1573,78 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1506
1573
|
// This is nested so we need to allow one additional task
|
1507
1574
|
this.processDependenciesQueue.increaseParallelism();
|
1508
1575
|
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
//
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
});
|
1523
|
-
},
|
1524
|
-
err => {
|
1525
|
-
this.processDependenciesQueue.decreaseParallelism();
|
1576
|
+
const processSortedDependency = (item, callback) => {
|
1577
|
+
this.handleModuleCreation(item, err => {
|
1578
|
+
// In V8, the Error objects keep a reference to the functions on the stack. These warnings &
|
1579
|
+
// errors are created inside closures that keep a reference to the Compilation, so errors are
|
1580
|
+
// leaking the Compilation object.
|
1581
|
+
if (err && this.bail) {
|
1582
|
+
// eslint-disable-next-line no-self-assign
|
1583
|
+
err.stack = err.stack;
|
1584
|
+
return callback(err);
|
1585
|
+
}
|
1586
|
+
callback();
|
1587
|
+
});
|
1588
|
+
};
|
1526
1589
|
|
1527
|
-
|
1528
|
-
|
1590
|
+
const processUnsafeRestoredModule = (item, callback) => {
|
1591
|
+
this._handleModuleBuildAndDependencies(module, item, true, callback);
|
1592
|
+
};
|
1593
|
+
|
1594
|
+
const finalCallback = err => {
|
1595
|
+
this.processDependenciesQueue.decreaseParallelism();
|
1596
|
+
|
1597
|
+
return callback(err);
|
1598
|
+
};
|
1599
|
+
|
1600
|
+
if (sortedDependencies.length === 0) {
|
1601
|
+
asyncLib.forEach(
|
1602
|
+
unsafeRestoredModules,
|
1603
|
+
processUnsafeRestoredModule,
|
1604
|
+
finalCallback
|
1605
|
+
);
|
1606
|
+
} else if (unsafeRestoredModules.size === 0) {
|
1607
|
+
asyncLib.forEach(
|
1608
|
+
sortedDependencies,
|
1609
|
+
processSortedDependency,
|
1610
|
+
finalCallback
|
1611
|
+
);
|
1612
|
+
} else {
|
1613
|
+
asyncLib.parallel(
|
1614
|
+
[
|
1615
|
+
cb =>
|
1616
|
+
asyncLib.forEach(
|
1617
|
+
unsafeRestoredModules,
|
1618
|
+
processUnsafeRestoredModule,
|
1619
|
+
cb
|
1620
|
+
),
|
1621
|
+
cb =>
|
1622
|
+
asyncLib.forEach(sortedDependencies, processSortedDependency, cb)
|
1623
|
+
],
|
1624
|
+
finalCallback
|
1625
|
+
);
|
1626
|
+
}
|
1627
|
+
}
|
1628
|
+
|
1629
|
+
_handleNewModuleFromUnsafeCache(originModule, dependency, module) {
|
1630
|
+
const moduleGraph = this.moduleGraph;
|
1631
|
+
|
1632
|
+
moduleGraph.setResolvedModule(originModule, dependency, module);
|
1633
|
+
|
1634
|
+
moduleGraph.setIssuerIfUnset(
|
1635
|
+
module,
|
1636
|
+
originModule !== undefined ? originModule : null
|
1529
1637
|
);
|
1638
|
+
|
1639
|
+
this._modules.set(module.identifier(), module);
|
1640
|
+
this.modules.add(module);
|
1641
|
+
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
1642
|
+
}
|
1643
|
+
|
1644
|
+
_handleExistingModuleFromUnsafeCache(originModule, dependency, module) {
|
1645
|
+
const moduleGraph = this.moduleGraph;
|
1646
|
+
|
1647
|
+
moduleGraph.setResolvedModule(originModule, dependency, module);
|
1530
1648
|
}
|
1531
1649
|
|
1532
1650
|
/**
|
@@ -1566,12 +1684,27 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1566
1684
|
currentProfile,
|
1567
1685
|
factory,
|
1568
1686
|
dependencies,
|
1687
|
+
factoryResult: true,
|
1569
1688
|
originModule,
|
1570
1689
|
contextInfo,
|
1571
1690
|
context
|
1572
1691
|
},
|
1573
|
-
(err,
|
1692
|
+
(err, factoryResult) => {
|
1693
|
+
const applyFactoryResultDependencies = () => {
|
1694
|
+
const { fileDependencies, contextDependencies, missingDependencies } =
|
1695
|
+
factoryResult;
|
1696
|
+
if (fileDependencies) {
|
1697
|
+
this.fileDependencies.addAll(fileDependencies);
|
1698
|
+
}
|
1699
|
+
if (contextDependencies) {
|
1700
|
+
this.contextDependencies.addAll(contextDependencies);
|
1701
|
+
}
|
1702
|
+
if (missingDependencies) {
|
1703
|
+
this.missingDependencies.addAll(missingDependencies);
|
1704
|
+
}
|
1705
|
+
};
|
1574
1706
|
if (err) {
|
1707
|
+
if (factoryResult) applyFactoryResultDependencies();
|
1575
1708
|
if (dependencies.every(d => d.optional)) {
|
1576
1709
|
this.warnings.push(err);
|
1577
1710
|
return callback();
|
@@ -1581,7 +1714,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1581
1714
|
}
|
1582
1715
|
}
|
1583
1716
|
|
1717
|
+
const newModule = factoryResult.module;
|
1718
|
+
|
1584
1719
|
if (!newModule) {
|
1720
|
+
applyFactoryResultDependencies();
|
1585
1721
|
return callback();
|
1586
1722
|
}
|
1587
1723
|
|
@@ -1591,6 +1727,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1591
1727
|
|
1592
1728
|
this.addModule(newModule, (err, module) => {
|
1593
1729
|
if (err) {
|
1730
|
+
applyFactoryResultDependencies();
|
1594
1731
|
if (!err.module) {
|
1595
1732
|
err.module = module;
|
1596
1733
|
}
|
@@ -1599,13 +1736,37 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1599
1736
|
return callback(err);
|
1600
1737
|
}
|
1601
1738
|
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
)
|
1739
|
+
if (
|
1740
|
+
this._unsafeCache &&
|
1741
|
+
factoryResult.cacheable !== false &&
|
1742
|
+
/** @type {any} */ (module).restoreFromUnsafeCache &&
|
1743
|
+
this._unsafeCachePredicate(module)
|
1744
|
+
) {
|
1745
|
+
for (let i = 0; i < dependencies.length; i++) {
|
1746
|
+
const dependency = dependencies[i];
|
1747
|
+
moduleGraph.setResolvedModule(
|
1748
|
+
connectOrigin ? originModule : null,
|
1749
|
+
dependency,
|
1750
|
+
module
|
1751
|
+
);
|
1752
|
+
unsafeCacheDependencies.set(
|
1753
|
+
dependency,
|
1754
|
+
/** @type {any} */ (module)
|
1755
|
+
);
|
1756
|
+
}
|
1757
|
+
if (!unsafeCacheData.has(module)) {
|
1758
|
+
unsafeCacheData.set(module, module.getUnsafeCacheData());
|
1759
|
+
}
|
1760
|
+
} else {
|
1761
|
+
applyFactoryResultDependencies();
|
1762
|
+
for (let i = 0; i < dependencies.length; i++) {
|
1763
|
+
const dependency = dependencies[i];
|
1764
|
+
moduleGraph.setResolvedModule(
|
1765
|
+
connectOrigin ? originModule : null,
|
1766
|
+
dependency,
|
1767
|
+
module
|
1768
|
+
);
|
1769
|
+
}
|
1609
1770
|
}
|
1610
1771
|
|
1611
1772
|
moduleGraph.setIssuerIfUnset(
|
@@ -1623,99 +1784,89 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1623
1784
|
}
|
1624
1785
|
}
|
1625
1786
|
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
creatingModuleDuringBuildSet
|
1637
|
-
);
|
1638
|
-
}
|
1639
|
-
creatingModuleDuringBuildSet.add(originModule);
|
1640
|
-
|
1641
|
-
// When building is blocked by another module
|
1642
|
-
// search for a cycle, cancel the cycle by throwing
|
1643
|
-
// an error (otherwise this would deadlock)
|
1644
|
-
const blockReasons = this.creatingModuleDuringBuild.get(module);
|
1645
|
-
if (blockReasons !== undefined) {
|
1646
|
-
const set = new Set(blockReasons);
|
1647
|
-
for (const item of set) {
|
1648
|
-
const blockReasons = this.creatingModuleDuringBuild.get(item);
|
1649
|
-
if (blockReasons !== undefined) {
|
1650
|
-
for (const m of blockReasons) {
|
1651
|
-
if (m === module) {
|
1652
|
-
return callback(new BuildCycleError(module));
|
1653
|
-
}
|
1654
|
-
set.add(m);
|
1655
|
-
}
|
1656
|
-
}
|
1657
|
-
}
|
1658
|
-
}
|
1659
|
-
}
|
1787
|
+
this._handleModuleBuildAndDependencies(
|
1788
|
+
originModule,
|
1789
|
+
module,
|
1790
|
+
recursive,
|
1791
|
+
callback
|
1792
|
+
);
|
1793
|
+
});
|
1794
|
+
}
|
1795
|
+
);
|
1796
|
+
}
|
1660
1797
|
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1798
|
+
_handleModuleBuildAndDependencies(originModule, module, recursive, callback) {
|
1799
|
+
// Check for cycles when build is trigger inside another build
|
1800
|
+
let creatingModuleDuringBuildSet = undefined;
|
1801
|
+
if (!recursive && this.buildQueue.isProcessing(originModule)) {
|
1802
|
+
// Track build dependency
|
1803
|
+
creatingModuleDuringBuildSet =
|
1804
|
+
this.creatingModuleDuringBuild.get(originModule);
|
1805
|
+
if (creatingModuleDuringBuildSet === undefined) {
|
1806
|
+
creatingModuleDuringBuildSet = new Set();
|
1807
|
+
this.creatingModuleDuringBuild.set(
|
1808
|
+
originModule,
|
1809
|
+
creatingModuleDuringBuildSet
|
1810
|
+
);
|
1811
|
+
}
|
1812
|
+
creatingModuleDuringBuildSet.add(originModule);
|
1813
|
+
|
1814
|
+
// When building is blocked by another module
|
1815
|
+
// search for a cycle, cancel the cycle by throwing
|
1816
|
+
// an error (otherwise this would deadlock)
|
1817
|
+
const blockReasons = this.creatingModuleDuringBuild.get(module);
|
1818
|
+
if (blockReasons !== undefined) {
|
1819
|
+
const set = new Set(blockReasons);
|
1820
|
+
for (const item of set) {
|
1821
|
+
const blockReasons = this.creatingModuleDuringBuild.get(item);
|
1822
|
+
if (blockReasons !== undefined) {
|
1823
|
+
for (const m of blockReasons) {
|
1824
|
+
if (m === module) {
|
1825
|
+
return callback(new BuildCycleError(module));
|
1668
1826
|
}
|
1669
|
-
|
1670
|
-
|
1671
|
-
return callback(err);
|
1827
|
+
set.add(m);
|
1672
1828
|
}
|
1829
|
+
}
|
1830
|
+
}
|
1831
|
+
}
|
1832
|
+
}
|
1673
1833
|
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1834
|
+
this.buildModule(module, err => {
|
1835
|
+
if (creatingModuleDuringBuildSet !== undefined) {
|
1836
|
+
creatingModuleDuringBuildSet.delete(module);
|
1837
|
+
}
|
1838
|
+
if (err) {
|
1839
|
+
if (!err.module) {
|
1840
|
+
err.module = module;
|
1841
|
+
}
|
1842
|
+
this.errors.push(err);
|
1679
1843
|
|
1680
|
-
|
1681
|
-
|
1682
|
-
return callback();
|
1683
|
-
}
|
1844
|
+
return callback(err);
|
1845
|
+
}
|
1684
1846
|
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
callback(null, module);
|
1690
|
-
});
|
1691
|
-
});
|
1692
|
-
});
|
1847
|
+
if (!recursive) {
|
1848
|
+
this.processModuleDependenciesNonRecursive(module);
|
1849
|
+
callback(null, module);
|
1850
|
+
return;
|
1693
1851
|
}
|
1694
|
-
);
|
1695
|
-
}
|
1696
1852
|
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
* @property {Dependency[]} dependencies
|
1702
|
-
* @property {Module | null} originModule
|
1703
|
-
* @property {Partial<ModuleFactoryCreateDataContextInfo>=} contextInfo
|
1704
|
-
* @property {string=} context
|
1705
|
-
*/
|
1853
|
+
// This avoids deadlocks for circular dependencies
|
1854
|
+
if (this.processDependenciesQueue.isProcessing(module)) {
|
1855
|
+
return callback();
|
1856
|
+
}
|
1706
1857
|
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1858
|
+
this.processModuleDependencies(module, err => {
|
1859
|
+
if (err) {
|
1860
|
+
return callback(err);
|
1861
|
+
}
|
1862
|
+
callback(null, module);
|
1863
|
+
});
|
1864
|
+
});
|
1714
1865
|
}
|
1715
1866
|
|
1716
1867
|
/**
|
1717
1868
|
* @param {FactorizeModuleOptions} options options object
|
1718
|
-
* @param {
|
1869
|
+
* @param {ModuleOrFactoryResultCallback} callback callback
|
1719
1870
|
* @returns {void}
|
1720
1871
|
*/
|
1721
1872
|
_factorizeModule(
|
@@ -1724,6 +1875,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1724
1875
|
factory,
|
1725
1876
|
dependencies,
|
1726
1877
|
originModule,
|
1878
|
+
factoryResult,
|
1727
1879
|
contextInfo,
|
1728
1880
|
context
|
1729
1881
|
},
|
@@ -1757,16 +1909,21 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1757
1909
|
module: result
|
1758
1910
|
};
|
1759
1911
|
}
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1912
|
+
if (!factoryResult) {
|
1913
|
+
const {
|
1914
|
+
fileDependencies,
|
1915
|
+
contextDependencies,
|
1916
|
+
missingDependencies
|
1917
|
+
} = result;
|
1918
|
+
if (fileDependencies) {
|
1919
|
+
this.fileDependencies.addAll(fileDependencies);
|
1920
|
+
}
|
1921
|
+
if (contextDependencies) {
|
1922
|
+
this.contextDependencies.addAll(contextDependencies);
|
1923
|
+
}
|
1924
|
+
if (missingDependencies) {
|
1925
|
+
this.missingDependencies.addAll(missingDependencies);
|
1926
|
+
}
|
1770
1927
|
}
|
1771
1928
|
}
|
1772
1929
|
if (err) {
|
@@ -1775,20 +1932,17 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
1775
1932
|
err,
|
1776
1933
|
dependencies.map(d => d.loc).filter(Boolean)[0]
|
1777
1934
|
);
|
1778
|
-
return callback(notFoundError);
|
1935
|
+
return callback(notFoundError, factoryResult ? result : undefined);
|
1779
1936
|
}
|
1780
1937
|
if (!result) {
|
1781
1938
|
return callback();
|
1782
1939
|
}
|
1783
|
-
|
1784
|
-
if (!newModule) {
|
1785
|
-
return callback();
|
1786
|
-
}
|
1940
|
+
|
1787
1941
|
if (currentProfile !== undefined) {
|
1788
1942
|
currentProfile.markFactoryEnd();
|
1789
1943
|
}
|
1790
1944
|
|
1791
|
-
callback(null,
|
1945
|
+
callback(null, factoryResult ? result : result.module);
|
1792
1946
|
}
|
1793
1947
|
);
|
1794
1948
|
}
|
@@ -2011,6 +2165,158 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2011
2165
|
});
|
2012
2166
|
}
|
2013
2167
|
|
2168
|
+
_computeAffectedModules(modules) {
|
2169
|
+
const moduleMemCacheCache = this.compiler.moduleMemCaches;
|
2170
|
+
if (!moduleMemCacheCache) return;
|
2171
|
+
if (!this.moduleMemCaches) {
|
2172
|
+
this.moduleMemCaches = new WeakMap();
|
2173
|
+
this.moduleGraph.setModuleMemCaches(this.moduleMemCaches);
|
2174
|
+
}
|
2175
|
+
const { moduleGraph, moduleMemCaches } = this;
|
2176
|
+
const affectedModules = new Set();
|
2177
|
+
const infectedModules = new Set();
|
2178
|
+
let statNew = 0;
|
2179
|
+
let statChanged = 0;
|
2180
|
+
let statUnchanged = 0;
|
2181
|
+
let statReferencesChanged = 0;
|
2182
|
+
let statWithoutHash = 0;
|
2183
|
+
|
2184
|
+
const computeReferences = module => {
|
2185
|
+
/** @type {WeakMap<Dependency, Module>} */
|
2186
|
+
let references = undefined;
|
2187
|
+
for (const connection of moduleGraph.getOutgoingConnections(module)) {
|
2188
|
+
const d = connection.dependency;
|
2189
|
+
const m = connection.module;
|
2190
|
+
if (!d || !m || unsafeCacheDependencies.has(d)) continue;
|
2191
|
+
if (references === undefined) references = new WeakMap();
|
2192
|
+
references.set(d, m);
|
2193
|
+
}
|
2194
|
+
return references;
|
2195
|
+
};
|
2196
|
+
|
2197
|
+
/**
|
2198
|
+
* @param {Module} module the module
|
2199
|
+
* @param {WeakMap<Dependency, Module>} references references
|
2200
|
+
* @returns {boolean} true, when the references differ
|
2201
|
+
*/
|
2202
|
+
const compareReferences = (module, references) => {
|
2203
|
+
if (references === undefined) return true;
|
2204
|
+
for (const connection of moduleGraph.getOutgoingConnections(module)) {
|
2205
|
+
const d = connection.dependency;
|
2206
|
+
if (!d) continue;
|
2207
|
+
const entry = references.get(d);
|
2208
|
+
if (entry === undefined) continue;
|
2209
|
+
if (entry !== connection.module) return false;
|
2210
|
+
}
|
2211
|
+
return true;
|
2212
|
+
};
|
2213
|
+
|
2214
|
+
for (const module of modules) {
|
2215
|
+
const hash = module.buildInfo && module.buildInfo.hash;
|
2216
|
+
if (typeof hash === "string") {
|
2217
|
+
const cachedMemCache = moduleMemCacheCache.get(module);
|
2218
|
+
if (cachedMemCache === undefined) {
|
2219
|
+
// create a new entry
|
2220
|
+
const memCache = new WeakTupleMap();
|
2221
|
+
moduleMemCacheCache.set(module, {
|
2222
|
+
hash: hash,
|
2223
|
+
references: computeReferences(module),
|
2224
|
+
memCache
|
2225
|
+
});
|
2226
|
+
moduleMemCaches.set(module, memCache);
|
2227
|
+
affectedModules.add(module);
|
2228
|
+
statNew++;
|
2229
|
+
} else if (cachedMemCache.hash !== hash) {
|
2230
|
+
// use a new one
|
2231
|
+
const memCache = new WeakTupleMap();
|
2232
|
+
moduleMemCaches.set(module, memCache);
|
2233
|
+
affectedModules.add(module);
|
2234
|
+
cachedMemCache.hash = hash;
|
2235
|
+
cachedMemCache.references = computeReferences(module);
|
2236
|
+
cachedMemCache.memCache = memCache;
|
2237
|
+
statChanged++;
|
2238
|
+
} else if (!compareReferences(module, cachedMemCache.references)) {
|
2239
|
+
// use a new one
|
2240
|
+
const memCache = new WeakTupleMap();
|
2241
|
+
moduleMemCaches.set(module, memCache);
|
2242
|
+
affectedModules.add(module);
|
2243
|
+
cachedMemCache.references = computeReferences(module);
|
2244
|
+
cachedMemCache.memCache = memCache;
|
2245
|
+
statReferencesChanged++;
|
2246
|
+
} else {
|
2247
|
+
// keep the old mem cache
|
2248
|
+
moduleMemCaches.set(module, cachedMemCache.memCache);
|
2249
|
+
statUnchanged++;
|
2250
|
+
}
|
2251
|
+
} else {
|
2252
|
+
infectedModules.add(module);
|
2253
|
+
statWithoutHash++;
|
2254
|
+
}
|
2255
|
+
}
|
2256
|
+
const reduceAffectType = connections => {
|
2257
|
+
let affected = false;
|
2258
|
+
for (const { dependency } of connections) {
|
2259
|
+
if (!dependency) continue;
|
2260
|
+
const type = dependency.couldAffectReferencingModule();
|
2261
|
+
if (type === Dependency.TRANSITIVE) return Dependency.TRANSITIVE;
|
2262
|
+
if (type === false) continue;
|
2263
|
+
affected = true;
|
2264
|
+
}
|
2265
|
+
return affected;
|
2266
|
+
};
|
2267
|
+
const directOnlyInfectedModules = new Set();
|
2268
|
+
for (const module of infectedModules) {
|
2269
|
+
for (const [
|
2270
|
+
referencingModule,
|
2271
|
+
connections
|
2272
|
+
] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
|
2273
|
+
if (!referencingModule) continue;
|
2274
|
+
if (infectedModules.has(referencingModule)) continue;
|
2275
|
+
const type = reduceAffectType(connections);
|
2276
|
+
if (!type) continue;
|
2277
|
+
if (type === true) {
|
2278
|
+
directOnlyInfectedModules.add(referencingModule);
|
2279
|
+
} else {
|
2280
|
+
infectedModules.add(referencingModule);
|
2281
|
+
}
|
2282
|
+
}
|
2283
|
+
}
|
2284
|
+
for (const module of directOnlyInfectedModules) infectedModules.add(module);
|
2285
|
+
const directOnlyAffectModules = new Set();
|
2286
|
+
for (const module of affectedModules) {
|
2287
|
+
for (const [
|
2288
|
+
referencingModule,
|
2289
|
+
connections
|
2290
|
+
] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
|
2291
|
+
if (!referencingModule) continue;
|
2292
|
+
if (infectedModules.has(referencingModule)) continue;
|
2293
|
+
if (affectedModules.has(referencingModule)) continue;
|
2294
|
+
const type = reduceAffectType(connections);
|
2295
|
+
if (!type) continue;
|
2296
|
+
if (type === true) {
|
2297
|
+
directOnlyAffectModules.add(referencingModule);
|
2298
|
+
} else {
|
2299
|
+
affectedModules.add(referencingModule);
|
2300
|
+
}
|
2301
|
+
const memCache = new WeakTupleMap();
|
2302
|
+
const cache = moduleMemCacheCache.get(referencingModule);
|
2303
|
+
cache.memCache = memCache;
|
2304
|
+
moduleMemCaches.set(referencingModule, memCache);
|
2305
|
+
}
|
2306
|
+
}
|
2307
|
+
for (const module of directOnlyAffectModules) affectedModules.add(module);
|
2308
|
+
this.logger.log(
|
2309
|
+
`${Math.round(
|
2310
|
+
(100 * (affectedModules.size + infectedModules.size)) /
|
2311
|
+
this.modules.size
|
2312
|
+
)}% (${affectedModules.size} affected + ${
|
2313
|
+
infectedModules.size
|
2314
|
+
} infected of ${
|
2315
|
+
this.modules.size
|
2316
|
+
}) modules flagged as affected (${statNew} new modules, ${statChanged} changed, ${statReferencesChanged} references changed, ${statUnchanged} unchanged, ${statWithoutHash} without hash)`
|
2317
|
+
);
|
2318
|
+
}
|
2319
|
+
|
2014
2320
|
finish(callback) {
|
2015
2321
|
this.factorizeQueue.clear();
|
2016
2322
|
if (this.profile) {
|
@@ -2191,17 +2497,29 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2191
2497
|
);
|
2192
2498
|
this.logger.timeEnd("finish module profiles");
|
2193
2499
|
}
|
2500
|
+
this.logger.time("compute affected modules");
|
2501
|
+
this._computeAffectedModules(this.modules);
|
2502
|
+
this.logger.timeEnd("compute affected modules");
|
2194
2503
|
this.logger.time("finish modules");
|
2195
|
-
const { modules } = this;
|
2504
|
+
const { modules, moduleMemCaches } = this;
|
2196
2505
|
this.hooks.finishModules.callAsync(modules, err => {
|
2197
2506
|
this.logger.timeEnd("finish modules");
|
2198
2507
|
if (err) return callback(err);
|
2199
2508
|
|
2200
2509
|
// extract warnings and errors from modules
|
2510
|
+
this.moduleGraph.freeze("dependency errors");
|
2511
|
+
// TODO keep a cacheToken (= {}) for each module in the graph
|
2512
|
+
// create a new one per compilation and flag all updated files
|
2513
|
+
// and parents with it
|
2201
2514
|
this.logger.time("report dependency errors and warnings");
|
2202
|
-
this.moduleGraph.freeze();
|
2203
2515
|
for (const module of modules) {
|
2204
|
-
|
2516
|
+
// TODO only run for modules with changed cacheToken
|
2517
|
+
// global WeakMap<CacheToken, WeakSet<Module>> to keep modules without errors/warnings
|
2518
|
+
const memCache = moduleMemCaches && moduleMemCaches.get(module);
|
2519
|
+
if (memCache && memCache.get("noWarningsOrErrors")) continue;
|
2520
|
+
let hasProblems = this.reportDependencyErrorsAndWarnings(module, [
|
2521
|
+
module
|
2522
|
+
]);
|
2205
2523
|
const errors = module.getErrors();
|
2206
2524
|
if (errors !== undefined) {
|
2207
2525
|
for (const error of errors) {
|
@@ -2209,6 +2527,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2209
2527
|
error.module = module;
|
2210
2528
|
}
|
2211
2529
|
this.errors.push(error);
|
2530
|
+
hasProblems = true;
|
2212
2531
|
}
|
2213
2532
|
}
|
2214
2533
|
const warnings = module.getWarnings();
|
@@ -2218,8 +2537,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2218
2537
|
warning.module = module;
|
2219
2538
|
}
|
2220
2539
|
this.warnings.push(warning);
|
2540
|
+
hasProblems = true;
|
2221
2541
|
}
|
2222
2542
|
}
|
2543
|
+
if (!hasProblems && memCache) memCache.set("noWarningsOrErrors", true);
|
2223
2544
|
}
|
2224
2545
|
this.moduleGraph.unfreeze();
|
2225
2546
|
this.logger.timeEnd("report dependency errors and warnings");
|
@@ -2255,7 +2576,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2255
2576
|
this.addModuleQueue.clear();
|
2256
2577
|
return callback(err);
|
2257
2578
|
};
|
2258
|
-
const chunkGraph = new ChunkGraph(
|
2579
|
+
const chunkGraph = new ChunkGraph(
|
2580
|
+
this.moduleGraph,
|
2581
|
+
this.outputOptions.hashFunction
|
2582
|
+
);
|
2259
2583
|
this.chunkGraph = chunkGraph;
|
2260
2584
|
|
2261
2585
|
for (const module of this.modules) {
|
@@ -2273,7 +2597,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2273
2597
|
|
2274
2598
|
this.logger.time("create chunks");
|
2275
2599
|
this.hooks.beforeChunks.call();
|
2276
|
-
this.moduleGraph.freeze();
|
2600
|
+
this.moduleGraph.freeze("seal");
|
2277
2601
|
/** @type {Map<Entrypoint, Module[]>} */
|
2278
2602
|
const chunkGraphInit = new Map();
|
2279
2603
|
for (const [name, { dependencies, includeDependencies, options }] of this
|
@@ -2573,9 +2897,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2573
2897
|
/**
|
2574
2898
|
* @param {Module} module module to report from
|
2575
2899
|
* @param {DependenciesBlock[]} blocks blocks to report from
|
2576
|
-
* @returns {
|
2900
|
+
* @returns {boolean} true, when it has warnings or errors
|
2577
2901
|
*/
|
2578
2902
|
reportDependencyErrorsAndWarnings(module, blocks) {
|
2903
|
+
let hasProblems = false;
|
2579
2904
|
for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) {
|
2580
2905
|
const block = blocks[indexBlock];
|
2581
2906
|
const dependencies = block.dependencies;
|
@@ -2590,6 +2915,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2590
2915
|
|
2591
2916
|
const warning = new ModuleDependencyWarning(module, w, d.loc);
|
2592
2917
|
this.warnings.push(warning);
|
2918
|
+
hasProblems = true;
|
2593
2919
|
}
|
2594
2920
|
}
|
2595
2921
|
const errors = d.getErrors(this.moduleGraph);
|
@@ -2599,17 +2925,22 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2599
2925
|
|
2600
2926
|
const error = new ModuleDependencyError(module, e, d.loc);
|
2601
2927
|
this.errors.push(error);
|
2928
|
+
hasProblems = true;
|
2602
2929
|
}
|
2603
2930
|
}
|
2604
2931
|
}
|
2605
2932
|
|
2606
|
-
this.reportDependencyErrorsAndWarnings(module, block.blocks)
|
2933
|
+
if (this.reportDependencyErrorsAndWarnings(module, block.blocks))
|
2934
|
+
hasProblems = true;
|
2607
2935
|
}
|
2936
|
+
return hasProblems;
|
2608
2937
|
}
|
2609
2938
|
|
2610
2939
|
codeGeneration(callback) {
|
2611
2940
|
const { chunkGraph } = this;
|
2612
|
-
this.codeGenerationResults = new CodeGenerationResults(
|
2941
|
+
this.codeGenerationResults = new CodeGenerationResults(
|
2942
|
+
this.outputOptions.hashFunction
|
2943
|
+
);
|
2613
2944
|
/** @type {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} */
|
2614
2945
|
const jobs = [];
|
2615
2946
|
for (const module of this.modules) {
|
@@ -2790,12 +3121,35 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2790
3121
|
chunkGraphEntries = this._getChunkGraphEntries()
|
2791
3122
|
} = {}) {
|
2792
3123
|
const context = { chunkGraph, codeGenerationResults };
|
3124
|
+
const { moduleMemCaches } = this;
|
3125
|
+
this.logger.time("runtime requirements.modules");
|
2793
3126
|
const additionalModuleRuntimeRequirements =
|
2794
3127
|
this.hooks.additionalModuleRuntimeRequirements;
|
2795
3128
|
const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
|
2796
3129
|
for (const module of modules) {
|
2797
3130
|
if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
|
3131
|
+
const memCache =
|
3132
|
+
moduleMemCaches &&
|
3133
|
+
// modules with async blocks depend on the chunk graph and can't be cached that way
|
3134
|
+
module.blocks.length === 0 &&
|
3135
|
+
moduleMemCaches.get(module);
|
2798
3136
|
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
3137
|
+
if (memCache) {
|
3138
|
+
const cached = memCache.get(
|
3139
|
+
`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`
|
3140
|
+
);
|
3141
|
+
if (cached !== undefined) {
|
3142
|
+
if (cached !== null) {
|
3143
|
+
chunkGraph.addModuleRuntimeRequirements(
|
3144
|
+
module,
|
3145
|
+
runtime,
|
3146
|
+
cached,
|
3147
|
+
false
|
3148
|
+
);
|
3149
|
+
}
|
3150
|
+
continue;
|
3151
|
+
}
|
3152
|
+
}
|
2799
3153
|
let set;
|
2800
3154
|
const runtimeRequirements =
|
2801
3155
|
codeGenerationResults.getRuntimeRequirements(module, runtime);
|
@@ -2804,6 +3158,12 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2804
3158
|
} else if (additionalModuleRuntimeRequirements.isUsed()) {
|
2805
3159
|
set = new Set();
|
2806
3160
|
} else {
|
3161
|
+
if (memCache) {
|
3162
|
+
memCache.set(
|
3163
|
+
`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
|
3164
|
+
null
|
3165
|
+
);
|
3166
|
+
}
|
2807
3167
|
continue;
|
2808
3168
|
}
|
2809
3169
|
additionalModuleRuntimeRequirements.call(module, set, context);
|
@@ -2812,11 +3172,35 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2812
3172
|
const hook = runtimeRequirementInModule.get(r);
|
2813
3173
|
if (hook !== undefined) hook.call(module, set, context);
|
2814
3174
|
}
|
2815
|
-
|
3175
|
+
if (set.size === 0) {
|
3176
|
+
if (memCache) {
|
3177
|
+
memCache.set(
|
3178
|
+
`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
|
3179
|
+
null
|
3180
|
+
);
|
3181
|
+
}
|
3182
|
+
} else {
|
3183
|
+
if (memCache) {
|
3184
|
+
memCache.set(
|
3185
|
+
`moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
|
3186
|
+
set
|
3187
|
+
);
|
3188
|
+
chunkGraph.addModuleRuntimeRequirements(
|
3189
|
+
module,
|
3190
|
+
runtime,
|
3191
|
+
set,
|
3192
|
+
false
|
3193
|
+
);
|
3194
|
+
} else {
|
3195
|
+
chunkGraph.addModuleRuntimeRequirements(module, runtime, set);
|
3196
|
+
}
|
3197
|
+
}
|
2816
3198
|
}
|
2817
3199
|
}
|
2818
3200
|
}
|
3201
|
+
this.logger.timeEnd("runtime requirements.modules");
|
2819
3202
|
|
3203
|
+
this.logger.time("runtime requirements.chunks");
|
2820
3204
|
for (const chunk of chunks) {
|
2821
3205
|
const set = new Set();
|
2822
3206
|
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
@@ -2834,7 +3218,9 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2834
3218
|
|
2835
3219
|
chunkGraph.addChunkRuntimeRequirements(chunk, set);
|
2836
3220
|
}
|
3221
|
+
this.logger.timeEnd("runtime requirements.chunks");
|
2837
3222
|
|
3223
|
+
this.logger.time("runtime requirements.entries");
|
2838
3224
|
for (const treeEntry of chunkGraphEntries) {
|
2839
3225
|
const set = new Set();
|
2840
3226
|
for (const chunk of treeEntry.getAllReferencedChunks()) {
|
@@ -2857,6 +3243,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2857
3243
|
|
2858
3244
|
chunkGraph.addTreeRuntimeRequirements(treeEntry, set);
|
2859
3245
|
}
|
3246
|
+
this.logger.timeEnd("runtime requirements.entries");
|
2860
3247
|
}
|
2861
3248
|
|
2862
3249
|
// TODO webpack 6 make chunkGraph argument non-optional
|
@@ -3201,12 +3588,31 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
3201
3588
|
|
3202
3589
|
createModuleHashes() {
|
3203
3590
|
let statModulesHashed = 0;
|
3204
|
-
|
3591
|
+
let statModulesFromCache = 0;
|
3592
|
+
const { chunkGraph, runtimeTemplate, moduleMemCaches } = this;
|
3205
3593
|
const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
|
3206
3594
|
for (const module of this.modules) {
|
3595
|
+
const memCache =
|
3596
|
+
moduleMemCaches &&
|
3597
|
+
// modules with async blocks depend on the chunk graph and can't be cached that way
|
3598
|
+
module.blocks.length === 0 &&
|
3599
|
+
moduleMemCaches.get(module);
|
3207
3600
|
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
3601
|
+
if (memCache) {
|
3602
|
+
const digest = memCache.get(`moduleHash-${getRuntimeKey(runtime)}`);
|
3603
|
+
if (digest !== undefined) {
|
3604
|
+
chunkGraph.setModuleHashes(
|
3605
|
+
module,
|
3606
|
+
runtime,
|
3607
|
+
digest,
|
3608
|
+
digest.substr(0, hashDigestLength)
|
3609
|
+
);
|
3610
|
+
statModulesFromCache++;
|
3611
|
+
continue;
|
3612
|
+
}
|
3613
|
+
}
|
3208
3614
|
statModulesHashed++;
|
3209
|
-
this._createModuleHash(
|
3615
|
+
const digest = this._createModuleHash(
|
3210
3616
|
module,
|
3211
3617
|
chunkGraph,
|
3212
3618
|
runtime,
|
@@ -3215,11 +3621,16 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
3215
3621
|
hashDigest,
|
3216
3622
|
hashDigestLength
|
3217
3623
|
);
|
3624
|
+
if (memCache) {
|
3625
|
+
memCache.set(`moduleHash-${getRuntimeKey(runtime)}`, digest);
|
3626
|
+
}
|
3218
3627
|
}
|
3219
3628
|
}
|
3220
3629
|
this.logger.log(
|
3221
|
-
`${statModulesHashed} modules hashed (${
|
3222
|
-
Math.round(
|
3630
|
+
`${statModulesHashed} modules hashed, ${statModulesFromCache} from cache (${
|
3631
|
+
Math.round(
|
3632
|
+
(100 * (statModulesHashed + statModulesFromCache)) / this.modules.size
|
3633
|
+
) / 100
|
3223
3634
|
} variants per module in average)`
|
3224
3635
|
);
|
3225
3636
|
}
|
@@ -4071,7 +4482,10 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4071
4482
|
if (err) return callback(err);
|
4072
4483
|
|
4073
4484
|
// Create new chunk graph, chunk and entrypoint for the build time execution
|
4074
|
-
const chunkGraph = new ChunkGraph(
|
4485
|
+
const chunkGraph = new ChunkGraph(
|
4486
|
+
this.moduleGraph,
|
4487
|
+
this.outputOptions.hashFunction
|
4488
|
+
);
|
4075
4489
|
const runtime = "build time";
|
4076
4490
|
const { hashFunction, hashDigest, hashDigestLength } =
|
4077
4491
|
this.outputOptions;
|
@@ -4114,7 +4528,9 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4114
4528
|
);
|
4115
4529
|
}
|
4116
4530
|
|
4117
|
-
const codeGenerationResults = new CodeGenerationResults(
|
4531
|
+
const codeGenerationResults = new CodeGenerationResults(
|
4532
|
+
this.outputOptions.hashFunction
|
4533
|
+
);
|
4118
4534
|
/** @type {WebpackError[]} */
|
4119
4535
|
const errors = [];
|
4120
4536
|
/**
|
@@ -4418,6 +4834,33 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4418
4834
|
}
|
4419
4835
|
}
|
4420
4836
|
|
4837
|
+
/**
|
4838
|
+
* @typedef {Object} FactorizeModuleOptions
|
4839
|
+
* @property {ModuleProfile} currentProfile
|
4840
|
+
* @property {ModuleFactory} factory
|
4841
|
+
* @property {Dependency[]} dependencies
|
4842
|
+
* @property {boolean=} factoryResult return full ModuleFactoryResult instead of only module
|
4843
|
+
* @property {Module | null} originModule
|
4844
|
+
* @property {Partial<ModuleFactoryCreateDataContextInfo>=} contextInfo
|
4845
|
+
* @property {string=} context
|
4846
|
+
*/
|
4847
|
+
|
4848
|
+
/**
|
4849
|
+
* @param {FactorizeModuleOptions} options options object
|
4850
|
+
* @param {ModuleCallback | ModuleFactoryResultCallback} callback callback
|
4851
|
+
* @returns {void}
|
4852
|
+
*/
|
4853
|
+
|
4854
|
+
// Workaround for typescript as it doesn't support function overloading in jsdoc within a class
|
4855
|
+
Compilation.prototype.factorizeModule = /** @type {{
|
4856
|
+
(options: FactorizeModuleOptions & { factoryResult?: false }, callback: ModuleCallback): void;
|
4857
|
+
(options: FactorizeModuleOptions & { factoryResult: true }, callback: ModuleFactoryResultCallback): void;
|
4858
|
+
}} */ (
|
4859
|
+
function (options, callback) {
|
4860
|
+
this.factorizeQueue.add(options, callback);
|
4861
|
+
}
|
4862
|
+
);
|
4863
|
+
|
4421
4864
|
// Hide from typescript
|
4422
4865
|
const compilationPrototype = Compilation.prototype;
|
4423
4866
|
|