webpack 5.52.0 → 5.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/bin/webpack.js +0 -0
- package/lib/AsyncDependenciesBlock.js +9 -2
- package/lib/CacheFacade.js +10 -3
- package/lib/ChunkGraph.js +19 -8
- package/lib/CodeGenerationResults.js +7 -2
- package/lib/Compilation.js +549 -144
- package/lib/Compiler.js +12 -4
- package/lib/Dependency.js +11 -0
- package/lib/DependencyTemplates.js +8 -2
- package/lib/EvalDevToolModulePlugin.js +2 -1
- package/lib/EvalSourceMapDevToolPlugin.js +2 -1
- package/lib/ExternalModule.js +18 -9
- package/lib/FileSystemInfo.js +101 -170
- package/lib/FlagDependencyExportsPlugin.js +25 -16
- package/lib/JavascriptMetaInfoPlugin.js +6 -1
- package/lib/ModuleFactory.js +1 -0
- package/lib/ModuleFilenameHelpers.js +21 -7
- package/lib/ModuleGraph.js +90 -21
- package/lib/NodeStuffInWebError.js +34 -0
- package/lib/NodeStuffPlugin.js +59 -16
- package/lib/NormalModuleFactory.js +8 -43
- package/lib/SourceMapDevToolPlugin.js +7 -3
- package/lib/WebpackOptionsApply.js +19 -1
- package/lib/cache/PackFileCacheStrategy.js +183 -53
- package/lib/cache/getLazyHashedEtag.js +35 -8
- package/lib/config/defaults.js +32 -12
- package/lib/dependencies/CachedConstDependency.js +4 -3
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -9
- package/lib/dependencies/CommonJsFullRequireDependency.js +11 -9
- package/lib/dependencies/ConstDependency.js +12 -4
- package/lib/dependencies/ContextDependency.js +8 -0
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +179 -163
- package/lib/dependencies/HarmonyImportDependency.js +4 -1
- package/lib/dependencies/JsonExportsDependency.js +7 -1
- package/lib/dependencies/ModuleDecoratorDependency.js +5 -2
- package/lib/dependencies/ModuleDependency.js +8 -0
- package/lib/dependencies/NullDependency.js +8 -4
- package/lib/dependencies/ProvidedDependency.js +6 -2
- package/lib/dependencies/PureExpressionDependency.js +5 -1
- package/lib/dependencies/RuntimeRequirementsDependency.js +5 -1
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +9 -0
- package/lib/ids/IdHelpers.js +21 -8
- package/lib/ids/NamedChunkIdsPlugin.js +3 -0
- package/lib/ids/NamedModuleIdsPlugin.js +3 -1
- package/lib/index.js +6 -0
- package/lib/javascript/BasicEvaluatedExpression.js +3 -0
- package/lib/javascript/JavascriptParser.js +22 -4
- package/lib/javascript/JavascriptParserHelpers.js +0 -2
- package/lib/node/NodeTargetPlugin.js +1 -0
- package/lib/optimize/ConcatenatedModule.js +25 -4
- package/lib/optimize/InnerGraph.js +22 -2
- package/lib/optimize/ModuleConcatenationPlugin.js +2 -1
- package/lib/runtime/RelativeUrlRuntimeModule.js +1 -1
- package/lib/schemes/HttpUriPlugin.js +1 -2
- package/lib/serialization/BinaryMiddleware.js +11 -2
- package/lib/serialization/FileMiddleware.js +24 -7
- package/lib/serialization/ObjectMiddleware.js +23 -12
- package/lib/util/WeakTupleMap.js +95 -92
- package/lib/util/createHash.js +10 -0
- package/lib/util/hash/BatchedHash.js +65 -0
- package/lib/util/hash/xxhash64.js +154 -0
- package/lib/util/internalSerializables.js +1 -0
- package/lib/util/serialization.js +10 -6
- package/package.json +11 -7
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +19 -3
- package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/HashedModuleIdsPlugin.json +20 -2
- package/schemas/plugins/IgnorePlugin.check.js +1 -1
- package/schemas/plugins/IgnorePlugin.json +4 -2
- package/types.d.ts +211 -25
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,
|
@@ -76,7 +78,7 @@ const {
|
|
76
78
|
createFakeHook
|
77
79
|
} = require("./util/deprecation");
|
78
80
|
const processAsyncTree = require("./util/processAsyncTree");
|
79
|
-
const { getRuntimeKey } = require("./util/runtime");
|
81
|
+
const { getRuntimeKey, RuntimeSpecMap } = require("./util/runtime");
|
80
82
|
const { isSourceEqual } = require("./util/source");
|
81
83
|
|
82
84
|
/** @template T @typedef {import("tapable").AsArray<T>} AsArray<T> */
|
@@ -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,120 @@ 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 statWithoutHash = 0;
|
2182
|
+
for (const module of modules) {
|
2183
|
+
const hash = module.buildInfo && module.buildInfo.hash;
|
2184
|
+
if (typeof hash === "string") {
|
2185
|
+
const cachedMemCache = moduleMemCacheCache.get(module);
|
2186
|
+
if (cachedMemCache === undefined) {
|
2187
|
+
// create a new entry
|
2188
|
+
const memCache = new WeakTupleMap();
|
2189
|
+
moduleMemCacheCache.set(module, {
|
2190
|
+
hash: hash,
|
2191
|
+
memCache
|
2192
|
+
});
|
2193
|
+
moduleMemCaches.set(module, memCache);
|
2194
|
+
affectedModules.add(module);
|
2195
|
+
statNew++;
|
2196
|
+
} else if (cachedMemCache.hash === hash) {
|
2197
|
+
// keep the old mem cache
|
2198
|
+
moduleMemCaches.set(module, cachedMemCache.memCache);
|
2199
|
+
statUnchanged++;
|
2200
|
+
} else {
|
2201
|
+
// use a new one
|
2202
|
+
const memCache = new WeakTupleMap();
|
2203
|
+
moduleMemCacheCache.set(module, {
|
2204
|
+
hash: hash,
|
2205
|
+
memCache
|
2206
|
+
});
|
2207
|
+
moduleMemCaches.set(module, memCache);
|
2208
|
+
affectedModules.add(module);
|
2209
|
+
cachedMemCache.hash = hash;
|
2210
|
+
cachedMemCache.memCache = memCache;
|
2211
|
+
statChanged++;
|
2212
|
+
}
|
2213
|
+
} else {
|
2214
|
+
infectedModules.add(module);
|
2215
|
+
statWithoutHash++;
|
2216
|
+
}
|
2217
|
+
}
|
2218
|
+
const reduceAffectType = connections => {
|
2219
|
+
let affected = false;
|
2220
|
+
for (const { dependency } of connections) {
|
2221
|
+
if (!dependency) continue;
|
2222
|
+
const type = dependency.couldAffectReferencingModule();
|
2223
|
+
if (type === Dependency.TRANSITIVE) return Dependency.TRANSITIVE;
|
2224
|
+
if (type === false) continue;
|
2225
|
+
affected = true;
|
2226
|
+
}
|
2227
|
+
return affected;
|
2228
|
+
};
|
2229
|
+
const directOnlyInfectedModules = new Set();
|
2230
|
+
for (const module of infectedModules) {
|
2231
|
+
for (const [
|
2232
|
+
referencingModule,
|
2233
|
+
connections
|
2234
|
+
] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
|
2235
|
+
if (!referencingModule) continue;
|
2236
|
+
if (infectedModules.has(referencingModule)) continue;
|
2237
|
+
const type = reduceAffectType(connections);
|
2238
|
+
if (!type) continue;
|
2239
|
+
if (type === true) {
|
2240
|
+
directOnlyInfectedModules.add(referencingModule);
|
2241
|
+
} else {
|
2242
|
+
infectedModules.add(referencingModule);
|
2243
|
+
}
|
2244
|
+
}
|
2245
|
+
}
|
2246
|
+
for (const module of directOnlyInfectedModules) infectedModules.add(module);
|
2247
|
+
const directOnlyAffectModules = new Set();
|
2248
|
+
for (const module of affectedModules) {
|
2249
|
+
for (const [
|
2250
|
+
referencingModule,
|
2251
|
+
connections
|
2252
|
+
] of moduleGraph.getIncomingConnectionsByOriginModule(module)) {
|
2253
|
+
if (!referencingModule) continue;
|
2254
|
+
if (infectedModules.has(referencingModule)) continue;
|
2255
|
+
if (affectedModules.has(referencingModule)) continue;
|
2256
|
+
const type = reduceAffectType(connections);
|
2257
|
+
if (!type) continue;
|
2258
|
+
if (type === true) {
|
2259
|
+
directOnlyAffectModules.add(referencingModule);
|
2260
|
+
} else {
|
2261
|
+
affectedModules.add(referencingModule);
|
2262
|
+
}
|
2263
|
+
const memCache = new WeakTupleMap();
|
2264
|
+
const cache = moduleMemCacheCache.get(module);
|
2265
|
+
cache.memCache = memCache;
|
2266
|
+
moduleMemCaches.set(referencingModule, memCache);
|
2267
|
+
}
|
2268
|
+
}
|
2269
|
+
for (const module of directOnlyAffectModules) affectedModules.add(module);
|
2270
|
+
this.logger.log(
|
2271
|
+
`${Math.round(
|
2272
|
+
(100 * (affectedModules.size + infectedModules.size)) /
|
2273
|
+
this.modules.size
|
2274
|
+
)}% (${affectedModules.size} affected + ${
|
2275
|
+
infectedModules.size
|
2276
|
+
} infected of ${
|
2277
|
+
this.modules.size
|
2278
|
+
}) modules flagged as affected (${statNew} new modules, ${statChanged} changed, ${statUnchanged} unchanged, ${statWithoutHash} without hash)`
|
2279
|
+
);
|
2280
|
+
}
|
2281
|
+
|
2014
2282
|
finish(callback) {
|
2015
2283
|
this.factorizeQueue.clear();
|
2016
2284
|
if (this.profile) {
|
@@ -2191,17 +2459,29 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2191
2459
|
);
|
2192
2460
|
this.logger.timeEnd("finish module profiles");
|
2193
2461
|
}
|
2462
|
+
this.logger.time("compute affected modules");
|
2463
|
+
this._computeAffectedModules(this.modules);
|
2464
|
+
this.logger.timeEnd("compute affected modules");
|
2194
2465
|
this.logger.time("finish modules");
|
2195
|
-
const { modules } = this;
|
2466
|
+
const { modules, moduleMemCaches } = this;
|
2196
2467
|
this.hooks.finishModules.callAsync(modules, err => {
|
2197
2468
|
this.logger.timeEnd("finish modules");
|
2198
2469
|
if (err) return callback(err);
|
2199
2470
|
|
2200
2471
|
// extract warnings and errors from modules
|
2472
|
+
this.moduleGraph.freeze("dependency errors");
|
2473
|
+
// TODO keep a cacheToken (= {}) for each module in the graph
|
2474
|
+
// create a new one per compilation and flag all updated files
|
2475
|
+
// and parents with it
|
2201
2476
|
this.logger.time("report dependency errors and warnings");
|
2202
|
-
this.moduleGraph.freeze();
|
2203
2477
|
for (const module of modules) {
|
2204
|
-
|
2478
|
+
// TODO only run for modules with changed cacheToken
|
2479
|
+
// global WeakMap<CacheToken, WeakSet<Module>> to keep modules without errors/warnings
|
2480
|
+
const memCache = moduleMemCaches && moduleMemCaches.get(module);
|
2481
|
+
if (memCache && memCache.get("noWarningsOrErrors")) continue;
|
2482
|
+
let hasProblems = this.reportDependencyErrorsAndWarnings(module, [
|
2483
|
+
module
|
2484
|
+
]);
|
2205
2485
|
const errors = module.getErrors();
|
2206
2486
|
if (errors !== undefined) {
|
2207
2487
|
for (const error of errors) {
|
@@ -2209,6 +2489,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2209
2489
|
error.module = module;
|
2210
2490
|
}
|
2211
2491
|
this.errors.push(error);
|
2492
|
+
hasProblems = true;
|
2212
2493
|
}
|
2213
2494
|
}
|
2214
2495
|
const warnings = module.getWarnings();
|
@@ -2218,8 +2499,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2218
2499
|
warning.module = module;
|
2219
2500
|
}
|
2220
2501
|
this.warnings.push(warning);
|
2502
|
+
hasProblems = true;
|
2221
2503
|
}
|
2222
2504
|
}
|
2505
|
+
if (!hasProblems && memCache) memCache.set("noWarningsOrErrors", true);
|
2223
2506
|
}
|
2224
2507
|
this.moduleGraph.unfreeze();
|
2225
2508
|
this.logger.timeEnd("report dependency errors and warnings");
|
@@ -2255,7 +2538,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2255
2538
|
this.addModuleQueue.clear();
|
2256
2539
|
return callback(err);
|
2257
2540
|
};
|
2258
|
-
const chunkGraph = new ChunkGraph(
|
2541
|
+
const chunkGraph = new ChunkGraph(
|
2542
|
+
this.moduleGraph,
|
2543
|
+
this.outputOptions.hashFunction
|
2544
|
+
);
|
2259
2545
|
this.chunkGraph = chunkGraph;
|
2260
2546
|
|
2261
2547
|
for (const module of this.modules) {
|
@@ -2273,7 +2559,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|
2273
2559
|
|
2274
2560
|
this.logger.time("create chunks");
|
2275
2561
|
this.hooks.beforeChunks.call();
|
2276
|
-
this.moduleGraph.freeze();
|
2562
|
+
this.moduleGraph.freeze("seal");
|
2277
2563
|
/** @type {Map<Entrypoint, Module[]>} */
|
2278
2564
|
const chunkGraphInit = new Map();
|
2279
2565
|
for (const [name, { dependencies, includeDependencies, options }] of this
|
@@ -2573,9 +2859,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2573
2859
|
/**
|
2574
2860
|
* @param {Module} module module to report from
|
2575
2861
|
* @param {DependenciesBlock[]} blocks blocks to report from
|
2576
|
-
* @returns {
|
2862
|
+
* @returns {boolean} true, when it has warnings or errors
|
2577
2863
|
*/
|
2578
2864
|
reportDependencyErrorsAndWarnings(module, blocks) {
|
2865
|
+
let hasProblems = false;
|
2579
2866
|
for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) {
|
2580
2867
|
const block = blocks[indexBlock];
|
2581
2868
|
const dependencies = block.dependencies;
|
@@ -2590,6 +2877,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2590
2877
|
|
2591
2878
|
const warning = new ModuleDependencyWarning(module, w, d.loc);
|
2592
2879
|
this.warnings.push(warning);
|
2880
|
+
hasProblems = true;
|
2593
2881
|
}
|
2594
2882
|
}
|
2595
2883
|
const errors = d.getErrors(this.moduleGraph);
|
@@ -2599,17 +2887,22 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2599
2887
|
|
2600
2888
|
const error = new ModuleDependencyError(module, e, d.loc);
|
2601
2889
|
this.errors.push(error);
|
2890
|
+
hasProblems = true;
|
2602
2891
|
}
|
2603
2892
|
}
|
2604
2893
|
}
|
2605
2894
|
|
2606
|
-
this.reportDependencyErrorsAndWarnings(module, block.blocks)
|
2895
|
+
if (this.reportDependencyErrorsAndWarnings(module, block.blocks))
|
2896
|
+
hasProblems = true;
|
2607
2897
|
}
|
2898
|
+
return hasProblems;
|
2608
2899
|
}
|
2609
2900
|
|
2610
2901
|
codeGeneration(callback) {
|
2611
2902
|
const { chunkGraph } = this;
|
2612
|
-
this.codeGenerationResults = new CodeGenerationResults(
|
2903
|
+
this.codeGenerationResults = new CodeGenerationResults(
|
2904
|
+
this.outputOptions.hashFunction
|
2905
|
+
);
|
2613
2906
|
/** @type {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} */
|
2614
2907
|
const jobs = [];
|
2615
2908
|
for (const module of this.modules) {
|
@@ -2790,12 +3083,40 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2790
3083
|
chunkGraphEntries = this._getChunkGraphEntries()
|
2791
3084
|
} = {}) {
|
2792
3085
|
const context = { chunkGraph, codeGenerationResults };
|
3086
|
+
const { moduleMemCaches } = this;
|
3087
|
+
this.logger.time("runtime requirements.modules");
|
2793
3088
|
const additionalModuleRuntimeRequirements =
|
2794
3089
|
this.hooks.additionalModuleRuntimeRequirements;
|
2795
3090
|
const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
|
2796
3091
|
for (const module of modules) {
|
2797
3092
|
if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
|
3093
|
+
const memCache =
|
3094
|
+
moduleMemCaches &&
|
3095
|
+
// modules with async blocks depend on the chunk graph and can't be cached that way
|
3096
|
+
module.blocks.length === 0 &&
|
3097
|
+
moduleMemCaches.get(module);
|
3098
|
+
/** @type {RuntimeSpecMap<Set<string>>} */
|
3099
|
+
const moduleRuntimeRequirementsMemCache =
|
3100
|
+
memCache &&
|
3101
|
+
memCache.provide(
|
3102
|
+
"moduleRuntimeRequirements",
|
3103
|
+
() => new RuntimeSpecMap()
|
3104
|
+
);
|
2798
3105
|
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
3106
|
+
if (moduleRuntimeRequirementsMemCache) {
|
3107
|
+
const cached = moduleRuntimeRequirementsMemCache.get(runtime);
|
3108
|
+
if (cached !== undefined) {
|
3109
|
+
if (cached !== null) {
|
3110
|
+
chunkGraph.addModuleRuntimeRequirements(
|
3111
|
+
module,
|
3112
|
+
runtime,
|
3113
|
+
cached,
|
3114
|
+
false
|
3115
|
+
);
|
3116
|
+
}
|
3117
|
+
continue;
|
3118
|
+
}
|
3119
|
+
}
|
2799
3120
|
let set;
|
2800
3121
|
const runtimeRequirements =
|
2801
3122
|
codeGenerationResults.getRuntimeRequirements(module, runtime);
|
@@ -2804,6 +3125,9 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2804
3125
|
} else if (additionalModuleRuntimeRequirements.isUsed()) {
|
2805
3126
|
set = new Set();
|
2806
3127
|
} else {
|
3128
|
+
if (moduleRuntimeRequirementsMemCache) {
|
3129
|
+
moduleRuntimeRequirementsMemCache.set(runtime, null);
|
3130
|
+
}
|
2807
3131
|
continue;
|
2808
3132
|
}
|
2809
3133
|
additionalModuleRuntimeRequirements.call(module, set, context);
|
@@ -2812,11 +3136,29 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2812
3136
|
const hook = runtimeRequirementInModule.get(r);
|
2813
3137
|
if (hook !== undefined) hook.call(module, set, context);
|
2814
3138
|
}
|
2815
|
-
|
3139
|
+
if (set.size === 0) {
|
3140
|
+
if (moduleRuntimeRequirementsMemCache) {
|
3141
|
+
moduleRuntimeRequirementsMemCache.set(runtime, null);
|
3142
|
+
}
|
3143
|
+
} else {
|
3144
|
+
if (moduleRuntimeRequirementsMemCache) {
|
3145
|
+
moduleRuntimeRequirementsMemCache.set(runtime, set);
|
3146
|
+
chunkGraph.addModuleRuntimeRequirements(
|
3147
|
+
module,
|
3148
|
+
runtime,
|
3149
|
+
set,
|
3150
|
+
false
|
3151
|
+
);
|
3152
|
+
} else {
|
3153
|
+
chunkGraph.addModuleRuntimeRequirements(module, runtime, set);
|
3154
|
+
}
|
3155
|
+
}
|
2816
3156
|
}
|
2817
3157
|
}
|
2818
3158
|
}
|
3159
|
+
this.logger.timeEnd("runtime requirements.modules");
|
2819
3160
|
|
3161
|
+
this.logger.time("runtime requirements.chunks");
|
2820
3162
|
for (const chunk of chunks) {
|
2821
3163
|
const set = new Set();
|
2822
3164
|
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
@@ -2834,7 +3176,9 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2834
3176
|
|
2835
3177
|
chunkGraph.addChunkRuntimeRequirements(chunk, set);
|
2836
3178
|
}
|
3179
|
+
this.logger.timeEnd("runtime requirements.chunks");
|
2837
3180
|
|
3181
|
+
this.logger.time("runtime requirements.entries");
|
2838
3182
|
for (const treeEntry of chunkGraphEntries) {
|
2839
3183
|
const set = new Set();
|
2840
3184
|
for (const chunk of treeEntry.getAllReferencedChunks()) {
|
@@ -2857,6 +3201,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
2857
3201
|
|
2858
3202
|
chunkGraph.addTreeRuntimeRequirements(treeEntry, set);
|
2859
3203
|
}
|
3204
|
+
this.logger.timeEnd("runtime requirements.entries");
|
2860
3205
|
}
|
2861
3206
|
|
2862
3207
|
// TODO webpack 6 make chunkGraph argument non-optional
|
@@ -3201,12 +3546,35 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
3201
3546
|
|
3202
3547
|
createModuleHashes() {
|
3203
3548
|
let statModulesHashed = 0;
|
3204
|
-
|
3549
|
+
let statModulesFromCache = 0;
|
3550
|
+
const { chunkGraph, runtimeTemplate, moduleMemCaches } = this;
|
3205
3551
|
const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
|
3206
3552
|
for (const module of this.modules) {
|
3553
|
+
const memCache =
|
3554
|
+
moduleMemCaches &&
|
3555
|
+
// modules with async blocks depend on the chunk graph and can't be cached that way
|
3556
|
+
module.blocks.length === 0 &&
|
3557
|
+
moduleMemCaches.get(module);
|
3558
|
+
/** @type {RuntimeSpecMap<string>} */
|
3559
|
+
const moduleHashesMemCache =
|
3560
|
+
memCache &&
|
3561
|
+
memCache.provide("moduleHashes", () => new RuntimeSpecMap());
|
3207
3562
|
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
3563
|
+
if (moduleHashesMemCache) {
|
3564
|
+
const digest = moduleHashesMemCache.get(runtime);
|
3565
|
+
if (digest !== undefined) {
|
3566
|
+
chunkGraph.setModuleHashes(
|
3567
|
+
module,
|
3568
|
+
runtime,
|
3569
|
+
digest,
|
3570
|
+
digest.substr(0, hashDigestLength)
|
3571
|
+
);
|
3572
|
+
statModulesFromCache++;
|
3573
|
+
continue;
|
3574
|
+
}
|
3575
|
+
}
|
3208
3576
|
statModulesHashed++;
|
3209
|
-
this._createModuleHash(
|
3577
|
+
const digest = this._createModuleHash(
|
3210
3578
|
module,
|
3211
3579
|
chunkGraph,
|
3212
3580
|
runtime,
|
@@ -3215,11 +3583,16 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|
3215
3583
|
hashDigest,
|
3216
3584
|
hashDigestLength
|
3217
3585
|
);
|
3586
|
+
if (moduleHashesMemCache) {
|
3587
|
+
moduleHashesMemCache.set(runtime, digest);
|
3588
|
+
}
|
3218
3589
|
}
|
3219
3590
|
}
|
3220
3591
|
this.logger.log(
|
3221
|
-
`${statModulesHashed} modules hashed (${
|
3222
|
-
Math.round(
|
3592
|
+
`${statModulesHashed} modules hashed, ${statModulesFromCache} from cache (${
|
3593
|
+
Math.round(
|
3594
|
+
(100 * (statModulesHashed + statModulesFromCache)) / this.modules.size
|
3595
|
+
) / 100
|
3223
3596
|
} variants per module in average)`
|
3224
3597
|
);
|
3225
3598
|
}
|
@@ -4071,7 +4444,10 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4071
4444
|
if (err) return callback(err);
|
4072
4445
|
|
4073
4446
|
// Create new chunk graph, chunk and entrypoint for the build time execution
|
4074
|
-
const chunkGraph = new ChunkGraph(
|
4447
|
+
const chunkGraph = new ChunkGraph(
|
4448
|
+
this.moduleGraph,
|
4449
|
+
this.outputOptions.hashFunction
|
4450
|
+
);
|
4075
4451
|
const runtime = "build time";
|
4076
4452
|
const { hashFunction, hashDigest, hashDigestLength } =
|
4077
4453
|
this.outputOptions;
|
@@ -4114,7 +4490,9 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4114
4490
|
);
|
4115
4491
|
}
|
4116
4492
|
|
4117
|
-
const codeGenerationResults = new CodeGenerationResults(
|
4493
|
+
const codeGenerationResults = new CodeGenerationResults(
|
4494
|
+
this.outputOptions.hashFunction
|
4495
|
+
);
|
4118
4496
|
/** @type {WebpackError[]} */
|
4119
4497
|
const errors = [];
|
4120
4498
|
/**
|
@@ -4418,6 +4796,33 @@ This prevents using hashes of each other and should be avoided.`);
|
|
4418
4796
|
}
|
4419
4797
|
}
|
4420
4798
|
|
4799
|
+
/**
|
4800
|
+
* @typedef {Object} FactorizeModuleOptions
|
4801
|
+
* @property {ModuleProfile} currentProfile
|
4802
|
+
* @property {ModuleFactory} factory
|
4803
|
+
* @property {Dependency[]} dependencies
|
4804
|
+
* @property {boolean=} factoryResult return full ModuleFactoryResult instead of only module
|
4805
|
+
* @property {Module | null} originModule
|
4806
|
+
* @property {Partial<ModuleFactoryCreateDataContextInfo>=} contextInfo
|
4807
|
+
* @property {string=} context
|
4808
|
+
*/
|
4809
|
+
|
4810
|
+
/**
|
4811
|
+
* @param {FactorizeModuleOptions} options options object
|
4812
|
+
* @param {ModuleCallback | ModuleFactoryResultCallback} callback callback
|
4813
|
+
* @returns {void}
|
4814
|
+
*/
|
4815
|
+
|
4816
|
+
// Workaround for typescript as it doesn't support function overloading in jsdoc within a class
|
4817
|
+
Compilation.prototype.factorizeModule = /** @type {{
|
4818
|
+
(options: FactorizeModuleOptions & { factoryResult?: false }, callback: ModuleCallback): void;
|
4819
|
+
(options: FactorizeModuleOptions & { factoryResult: true }, callback: ModuleFactoryResultCallback): void;
|
4820
|
+
}} */ (
|
4821
|
+
function (options, callback) {
|
4822
|
+
this.factorizeQueue.add(options, callback);
|
4823
|
+
}
|
4824
|
+
);
|
4825
|
+
|
4421
4826
|
// Hide from typescript
|
4422
4827
|
const compilationPrototype = Compilation.prototype;
|
4423
4828
|
|