fix: use `xxhash64` for `cache.hashAlgorithm` when `experiments.futureDefaults` (#19323)

This commit is contained in:
Alexander Akait 2025-03-13 22:39:02 +03:00 committed by GitHub
parent 5c51d83932
commit cb93228ce5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 223 additions and 19 deletions

View File

@ -8,6 +8,7 @@
const util = require("util");
const Entrypoint = require("./Entrypoint");
const ModuleGraphConnection = require("./ModuleGraphConnection");
const { DEFAULTS } = require("./config/defaults");
const { first } = require("./util/SetHelpers");
const SortableSet = require("./util/SortableSet");
const {
@ -245,7 +246,7 @@ class ChunkGraph {
* @param {ModuleGraph} moduleGraph the module graph
* @param {string | Hash} hashFunction the hash function to use
*/
constructor(moduleGraph, hashFunction = "md4") {
constructor(moduleGraph, hashFunction = DEFAULTS.HASH_FUNCTION) {
/**
* @private
* @type {WeakMap<Module, ChunkGraphModule>}

View File

@ -5,6 +5,7 @@
"use strict";
const { DEFAULTS } = require("./config/defaults");
const { getOrInsert } = require("./util/MapHelpers");
const { first } = require("./util/SetHelpers");
const createHash = require("./util/createHash");
@ -21,7 +22,7 @@ class CodeGenerationResults {
/**
* @param {string | Hash} hashFunction the hash function to use
*/
constructor(hashFunction = "md4") {
constructor(hashFunction = DEFAULTS.HASH_FUNCTION) {
/** @type {Map<Module, RuntimeSpecMap<CodeGenerationResult>>} */
this.map = new Map();
this._hashFunction = hashFunction;

View File

@ -5,6 +5,7 @@
"use strict";
const { DEFAULTS } = require("./config/defaults");
const createHash = require("./util/createHash");
/** @typedef {import("./Dependency")} Dependency */
@ -17,7 +18,7 @@ class DependencyTemplates {
/**
* @param {string | Hash} hashFunction the hash function to use
*/
constructor(hashFunction = "md4") {
constructor(hashFunction = DEFAULTS.HASH_FUNCTION) {
/** @type {Map<DependencyConstructor, DependencyTemplate>} */
this._map = new Map();
/** @type {string} */

View File

@ -19,6 +19,7 @@ const {
const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
const RuntimeGlobals = require("./RuntimeGlobals");
const Template = require("./Template");
const { DEFAULTS } = require("./config/defaults");
const StaticExportsDependency = require("./dependencies/StaticExportsDependency");
const createHash = require("./util/createHash");
const extractUrlAndGlobal = require("./util/extractUrlAndGlobal");
@ -236,7 +237,12 @@ class ModuleExternalInitFragment extends InitFragment {
* @param {ImportDependencyMeta=} dependencyMeta the dependency meta
* @param {string | HashConstructor=} hashFunction the hash function to use
*/
constructor(request, ident, dependencyMeta, hashFunction = "md4") {
constructor(
request,
ident,
dependencyMeta,
hashFunction = DEFAULTS.HASH_FUNCTION
) {
if (ident === undefined) {
ident = Template.toIdentifier(request);
if (ident !== request) {

View File

@ -9,6 +9,7 @@ const { create: createResolver } = require("enhanced-resolve");
const nodeModule = require("module");
const asyncLib = require("neo-async");
const { isAbsolute } = require("path");
const { DEFAULTS } = require("./config/defaults");
const AsyncQueue = require("./util/AsyncQueue");
const StackedCacheMap = require("./util/StackedCacheMap");
const createHash = require("./util/createHash");
@ -1067,7 +1068,7 @@ class FileSystemInfo {
managedPaths = [],
immutablePaths = [],
logger,
hashFunction = "md4"
hashFunction = DEFAULTS.HASH_FUNCTION
} = {}
) {
this.fs = fs;

View File

@ -6,6 +6,7 @@
"use strict";
const NormalModule = require("./NormalModule");
const { DEFAULTS } = require("./config/defaults");
const createHash = require("./util/createHash");
const memoize = require("./util/memoize");
@ -79,7 +80,7 @@ const getBefore = (strFn, token) => () => {
* @returns {ReturnStringCallback} a function that returns the hash of the string
*/
const getHash =
(strFn, hashFunction = "md4") =>
(strFn, hashFunction = DEFAULTS.HASH_FUNCTION) =>
() => {
const hash = createHash(hashFunction);
hash.update(strFn());
@ -126,7 +127,7 @@ ModuleFilenameHelpers.createFilename = (
// eslint-disable-next-line default-param-last
module = "",
options,
{ requestShortener, chunkGraph, hashFunction = "md4" }
{ requestShortener, chunkGraph, hashFunction = DEFAULTS.HASH_FUNCTION }
) => {
const opts = {
namespace: "",

View File

@ -5,6 +5,7 @@
"use strict";
const { DEFAULTS } = require("../config/defaults");
const createHash = require("../util/createHash");
/** @typedef {import("../util/Hash")} Hash */
@ -20,7 +21,7 @@ class LazyHashedEtag {
* @param {HashableObject} obj object with updateHash method
* @param {string | HashConstructor} hashFunction the hash function to use
*/
constructor(obj, hashFunction = "md4") {
constructor(obj, hashFunction = DEFAULTS.HASH_FUNCTION) {
this._obj = obj;
this._hash = undefined;
this._hashFunction = hashFunction;
@ -50,7 +51,7 @@ const mapObjects = new WeakMap();
* @param {(string | HashConstructor)=} hashFunction the hash function to use
* @returns {LazyHashedEtag} etag
*/
const getter = (obj, hashFunction = "md4") => {
const getter = (obj, hashFunction = DEFAULTS.HASH_FUNCTION) => {
let innerMap;
if (typeof hashFunction === "string") {
innerMap = mapStrings.get(hashFunction);

View File

@ -79,6 +79,10 @@ const {
const NODE_MODULES_REGEXP = /[\\/]node_modules[\\/]/i;
const DEFAULT_CACHE_NAME = "default";
const DEFAULTS = {
// TODO webpack 6 - use xxhash64
HASH_FUNCTION: "md4"
};
/**
* Sets a constant default value when undefined
@ -221,6 +225,7 @@ const applyWebpackOptionsDefaults = (options, compilerIndex) => {
mode: mode || "production",
development,
cacheUnaffected: options.experiments.cacheUnaffected,
futureDefaults,
compilerIndex
});
const cache = Boolean(options.cache);
@ -398,6 +403,7 @@ const applyExperimentsDefaults = (
* @param {object} options options
* @param {string} options.name name
* @param {Mode} options.mode mode
* @param {boolean} options.futureDefaults is future defaults enabled
* @param {boolean} options.development is development mode
* @param {number} [options.compilerIndex] index of compiler
* @param {Experiments["cacheUnaffected"]} options.cacheUnaffected the cacheUnaffected experiment is enabled
@ -405,7 +411,7 @@ const applyExperimentsDefaults = (
*/
const applyCacheDefaults = (
cache,
{ name, mode, development, cacheUnaffected, compilerIndex }
{ name, mode, development, cacheUnaffected, compilerIndex, futureDefaults }
) => {
if (cache === false) return;
switch (cache.type) {
@ -448,7 +454,7 @@ const applyCacheDefaults = (
/** @type {NonNullable<FileCacheOptions["name"]>} */ (cache.name)
)
);
D(cache, "hashAlgorithm", "md4");
D(cache, "hashAlgorithm", futureDefaults ? "xxhash64" : "md4");
D(cache, "store", "pack");
D(cache, "compression", false);
D(cache, "profile", false);
@ -1277,7 +1283,14 @@ const applyOutputDefaults = (
);
D(output, "workerPublicPath", "");
D(output, "chunkLoadTimeout", 120000);
D(output, "hashFunction", futureDefaults ? "xxhash64" : "md4");
F(output, "hashFunction", () => {
if (futureDefaults) {
DEFAULTS.HASH_FUNCTION = "xxhash64";
return "xxhash64";
}
return "md4";
});
D(output, "hashDigest", "hex");
D(output, "hashDigestLength", futureDefaults ? 16 : 20);
D(output, "strictModuleErrorHandling", false);
@ -1724,3 +1737,4 @@ const applyInfrastructureLoggingDefaults = infrastructureLogging => {
module.exports.applyWebpackOptionsBaseDefaults =
applyWebpackOptionsBaseDefaults;
module.exports.applyWebpackOptionsDefaults = applyWebpackOptionsDefaults;
module.exports.DEFAULTS = DEFAULTS;

View File

@ -5,6 +5,7 @@
"use strict";
const { DEFAULTS } = require("../config/defaults");
const {
compareModulesByPreOrderIndexOrIdentifier
} = require("../util/comparators");
@ -37,7 +38,7 @@ class HashedModuleIdsPlugin {
/** @type {HashedModuleIdsPluginOptions} */
this.options = {
context: undefined,
hashFunction: "md4",
hashFunction: DEFAULTS.HASH_FUNCTION,
hashDigest: "base64",
hashDigestLength: 4,
...options

View File

@ -20,6 +20,7 @@ const { JS_TYPES } = require("../ModuleSourceTypesConstants");
const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
const { DEFAULTS } = require("../config/defaults");
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
const JavascriptParser = require("../javascript/JavascriptParser");
const { equals } = require("../util/ArrayHelpers");
@ -623,7 +624,7 @@ class ConcatenatedModule extends Module {
runtime,
compilation,
associatedObjectForCache,
hashFunction = "md4"
hashFunction = DEFAULTS.HASH_FUNCTION
) {
const identifier = ConcatenatedModule._createIdentifier(
rootModule,
@ -1049,7 +1050,7 @@ class ConcatenatedModule extends Module {
rootModule,
modules,
associatedObjectForCache,
hashFunction = "md4"
hashFunction = DEFAULTS.HASH_FUNCTION
) {
const cachedMakePathsRelative = makePathsRelative.bindContextCache(
/** @type {string} */ (rootModule.context),

View File

@ -13,6 +13,7 @@ const {
createGunzip,
constants: zConstants
} = require("zlib");
const { DEFAULTS } = require("../config/defaults");
const createHash = require("../util/createHash");
const { dirname, join, mkdirp } = require("../util/fs");
const memoize = require("../util/memoize");
@ -107,7 +108,7 @@ const serialize = async (
data,
name,
writeFile,
hashFunction = "md4"
hashFunction = DEFAULTS.HASH_FUNCTION
) => {
/** @type {(Buffer[] | Buffer | Promise<SerializeResult>)[]} */
const processedData = [];
@ -434,7 +435,7 @@ class FileMiddleware extends SerializerMiddleware {
* @param {IntermediateFileSystem} fs filesystem
* @param {string | Hash} hashFunction hash function to use
*/
constructor(fs, hashFunction = "md4") {
constructor(fs, hashFunction = DEFAULTS.HASH_FUNCTION) {
super();
this.fs = fs;
this._hashFunction = hashFunction;

View File

@ -4,6 +4,7 @@
"use strict";
const { DEFAULTS } = require("../config/defaults");
const createHash = require("../util/createHash");
const ArraySerializer = require("./ArraySerializer");
const DateObjectSerializer = require("./DateObjectSerializer");
@ -204,7 +205,7 @@ class ObjectMiddleware extends SerializerMiddleware {
* @param {(context: ObjectSerializerContext | ObjectDeserializerContext) => void} extendContext context extensions
* @param {string | Hash} hashFunction hash function to use
*/
constructor(extendContext, hashFunction = "md4") {
constructor(extendContext, hashFunction = DEFAULTS.HASH_FUNCTION) {
super();
this.extendContext = extendContext;
this._hashFunction = hashFunction;

View File

@ -4,6 +4,7 @@
"use strict";
const { DEFAULTS } = require("../config/defaults");
const memoize = require("./memoize");
/** @typedef {import("../serialization/BinaryMiddleware").MEASURE_END_OPERATION_TYPE} MEASURE_END_OPERATION */
@ -97,7 +98,7 @@ module.exports = {
);
};
}
}, "md4"),
}, DEFAULTS.HASH_FUNCTION),
binaryMiddleware
]));
},

View File

@ -1945,6 +1945,179 @@ describe("snapshots", () => {
+ "cache": true,
`)
);
test(
"cache filesystem and futureDefaults",
{ cache: { type: "filesystem" }, experiments: { futureDefaults: true } },
e =>
e.toMatchInlineSnapshot(`
- Expected
+ Received
@@ ... @@
- "cache": false,
+ "cache": Object {
+ "allowCollectingMemory": false,
+ "buildDependencies": Object {
+ "defaultWebpack": Array [
+ "<cwd>/lib/",
+ ],
+ },
+ "cacheDirectory": "<cwd>/node_modules/.cache/webpack",
+ "cacheLocation": "<cwd>/node_modules/.cache/webpack/default-none",
+ "compression": false,
+ "hashAlgorithm": "xxhash64",
+ "idleTimeout": 60000,
+ "idleTimeoutAfterLargeChanges": 1000,
+ "idleTimeoutForInitialStore": 5000,
+ "maxAge": 5184000000,
+ "maxMemoryGenerations": Infinity,
+ "memoryCacheUnaffected": false,
+ "name": "default-none",
+ "profile": false,
+ "readonly": false,
+ "store": "pack",
+ "type": "filesystem",
+ "version": "",
+ },
@@ ... @@
- "asyncWebAssembly": false,
- "backCompat": true,
+ "asyncWebAssembly": true,
+ "backCompat": false,
@@ ... @@
- "cacheUnaffected": false,
- "css": undefined,
- "futureDefaults": false,
+ "cacheUnaffected": true,
+ "css": true,
+ "futureDefaults": true,
@@ ... @@
+ },
+ Object {
+ "rules": Array [
+ Object {
+ "descriptionData": Object {
+ "type": "module",
+ },
+ "resolve": Object {
+ "fullySpecified": true,
+ },
+ },
+ ],
+ "test": /\\.wasm$/i,
+ "type": "webassembly/async",
+ },
+ Object {
+ "mimetype": "application/wasm",
+ "rules": Array [
+ Object {
+ "descriptionData": Object {
+ "type": "module",
+ },
+ "resolve": Object {
+ "fullySpecified": true,
+ },
+ },
+ ],
+ "type": "webassembly/async",
+ },
+ Object {
+ "resolve": Object {
+ "fullySpecified": true,
+ "preferRelative": true,
+ },
+ "test": /\\.css$/i,
+ "type": "css/auto",
+ },
+ Object {
+ "mimetype": "text/css+module",
+ "resolve": Object {
+ "fullySpecified": true,
+ "preferRelative": true,
+ },
+ "type": "css/module",
+ },
+ Object {
+ "mimetype": "text/css",
+ "resolve": Object {
+ "fullySpecified": true,
+ "preferRelative": true,
+ },
+ "type": "css",
@@ ... @@
+ "css": Object {
+ "esModule": true,
+ "exportsOnly": false,
+ },
+ "css/auto": Object {
+ "exportsConvention": "as-is",
+ "localIdentName": "[uniqueName]-[id]-[local]",
+ },
+ "css/global": Object {
+ "exportsConvention": "as-is",
+ "localIdentName": "[uniqueName]-[id]-[local]",
+ },
+ "css/module": Object {
+ "exportsConvention": "as-is",
+ "localIdentName": "[uniqueName]-[id]-[local]",
+ },
@@ ... @@
+ },
@@ ... @@
+ "css": Object {
+ "import": true,
+ "namedExports": true,
+ "url": true,
@@ ... @@
+ "exportsPresence": "error",
@@ ... @@
- "unsafeCache": false,
+ "unsafeCache": [Function anonymous],
@@ ... @@
- "__dirname": "mock",
- "__filename": "mock",
- "global": true,
+ "__dirname": "warn-mock",
+ "__filename": "warn-mock",
+ "global": "warn",
@@ ... @@
+ "css",
@@ ... @@
- "charset": true,
+ "charset": false,
@@ ... @@
- "hashDigestLength": 20,
- "hashFunction": "md4",
+ "hashDigestLength": 16,
+ "hashFunction": "xxhash64",
@@ ... @@
+ "css-import": Object {
+ "conditionNames": Array [
+ "webpack",
+ "production",
+ "style",
+ ],
+ "extensions": Array [
+ ".css",
+ ],
+ "mainFields": Array [
+ "style",
+ "...",
+ ],
+ "mainFiles": Array [],
+ "preferRelative": true,
+ },
@@ ... @@
- "cache": false,
+ "cache": true,
@@ ... @@
- "cache": false,
+ "cache": true,
@@ ... @@
- "<cwd>/node_modules/",
+ /^(.+?[\\\\/]node_modules[\\\\/])/,
`)
);
test(
"disable",