fix(types): split chunks cached group (#19384)
Github Actions / lint (push) Waiting to run Details
Github Actions / basic (push) Waiting to run Details
Github Actions / validate-legacy-node (push) Waiting to run Details
Github Actions / unit (push) Waiting to run Details
Github Actions / integration (10.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (10.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (10.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (12.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (14.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (16.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (18.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (18.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (20.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (20.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (20.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (23.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (23.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (lts/*, ubuntu-latest, a, 1) (push) Blocked by required conditions Details
Github Actions / integration (lts/*, ubuntu-latest, b, 1) (push) Blocked by required conditions Details

This commit is contained in:
Alexander Akait 2025-04-04 20:17:40 +03:00 committed by GitHub
parent 6d37e76297
commit 880cf0804d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 63 additions and 51 deletions

View File

@ -53,7 +53,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
/**
* @typedef {object} CacheGroupSource
* @property {string=} key
* @property {string} key
* @property {number=} priority
* @property {GetName=} getName
* @property {ChunkFilterFunction=} chunksFilter
@ -77,20 +77,20 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
/**
* @typedef {object} CacheGroup
* @property {string} key
* @property {number=} priority
* @property {number} priority
* @property {GetName=} getName
* @property {ChunkFilterFunction=} chunksFilter
* @property {ChunkFilterFunction} chunksFilter
* @property {SplitChunksSizes} minSize
* @property {SplitChunksSizes} minSizeReduction
* @property {SplitChunksSizes} minRemainingSize
* @property {SplitChunksSizes} enforceSizeThreshold
* @property {SplitChunksSizes} maxAsyncSize
* @property {SplitChunksSizes} maxInitialSize
* @property {number=} minChunks
* @property {number=} maxAsyncRequests
* @property {number=} maxInitialRequests
* @property {number} minChunks
* @property {number} maxAsyncRequests
* @property {number} maxInitialRequests
* @property {TemplatePath=} filename
* @property {string=} idHint
* @property {string} idHint
* @property {string} automaticNameDelimiter
* @property {boolean} reuseExistingChunk
* @property {boolean} usedExports
@ -157,14 +157,15 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
* @property {SortableSet<Module>} modules
* @property {CacheGroup} cacheGroup
* @property {number} cacheGroupIndex
* @property {string} name
* @property {string=} name
* @property {Record<string, number>} sizes
* @property {Set<Chunk>} chunks
* @property {Set<Chunk>} reusableChunks
* @property {Set<bigint | Chunk>} chunksKeys
*/
const defaultGetName = /** @type {TODO} */ (() => {});
/** @type {GetName} */
const defaultGetName = () => undefined;
const deterministicGroupingForModules =
/** @type {(options: DeterministicGroupingOptionsForModule) => DeterministicGroupingGroupedItemsForModule[]} */
@ -242,9 +243,7 @@ const compareModuleIterables = compareIterables(compareModulesByIdentifier);
*/
const compareEntries = (a, b) => {
// 1. by priority
const diffPriority =
/** @type {number} */ (a.cacheGroup.priority) -
/** @type {number} */ (b.cacheGroup.priority);
const diffPriority = a.cacheGroup.priority - b.cacheGroup.priority;
if (diffPriority) return diffPriority;
// 2. by number of chunks
const diffCount = a.chunks.size - b.chunks.size;
@ -746,7 +745,7 @@ module.exports = class SplitChunksPlugin {
);
/** @type {CacheGroup} */
const cacheGroup = {
key: /** @type {string} */ (cacheGroupSource.key),
key: cacheGroupSource.key,
priority: cacheGroupSource.priority || 0,
chunksFilter: cacheGroupSource.chunksFilter || this.options.chunksFilter,
minSize,
@ -924,7 +923,7 @@ module.exports = class SplitChunksPlugin {
const groupedByExportsMap = new Map();
const getExportsChunkSetsInGraph = memoize(() => {
/** @type {Map<bigint, Set<Chunk>>} */
/** @type {Map<bigint | Chunk, Set<Chunk>>} */
const chunkSetsInGraph = new Map();
/** @type {Set<Chunk>} */
const singleChunkSets = new Set();
@ -935,7 +934,7 @@ module.exports = class SplitChunksPlugin {
if (chunks.length === 1) {
singleChunkSets.add(chunks[0]);
} else {
const chunksKey = /** @type {bigint} */ (getKey(chunks));
const chunksKey = getKey(chunks);
if (!chunkSetsInGraph.has(chunksKey)) {
chunkSetsInGraph.set(chunksKey, new Set(chunks));
}
@ -979,7 +978,7 @@ module.exports = class SplitChunksPlugin {
// Create a list of possible combinations
/**
* @param {Map<bigint, Set<Chunk>>} chunkSets chunk sets
* @param {Map<bigint | Chunk, Set<Chunk>>} chunkSets chunk sets
* @param {Set<Chunk>} singleChunkSets single chunks sets
* @param {Map<number, Set<Chunk>[]>} chunkSetsByCount chunk sets by count
* @returns {(key: bigint | Chunk) => (Set<Chunk> | Chunk)[]} combinations
@ -1126,21 +1125,14 @@ module.exports = class SplitChunksPlugin {
module
) => {
// Break if minimum number of chunks is not reached
if (
selectedChunks.length <
/** @type {number} */ (cacheGroup.minChunks)
)
return;
if (selectedChunks.length < cacheGroup.minChunks) return;
// Determine name for split chunk
const name =
/** @type {string} */
(
/** @type {GetName} */
(cacheGroup.getName)(module, selectedChunks, cacheGroup.key)
);
/** @type {GetName} */
(cacheGroup.getName)(module, selectedChunks, cacheGroup.key);
// Check if the name is ok
const existingChunk = compilation.namedChunks.get(name);
const existingChunk = name && compilation.namedChunks.get(name);
if (existingChunk) {
const parentValidationKey = `${name}|${
typeof selectedChunksKey === "bigint"
@ -1205,7 +1197,7 @@ module.exports = class SplitChunksPlugin {
? ` name:${name}`
: ` chunks:${keyToString(selectedChunksKey)}`);
// Add module to maps
let info = /** @type {ChunksInfoItem} */ (chunksInfoMap.get(key));
let info = chunksInfoMap.get(key);
if (info === undefined) {
chunksInfoMap.set(
key,
@ -1293,8 +1285,7 @@ module.exports = class SplitChunksPlugin {
// Break if minimum number of chunks is not reached
const count =
chunkCombination instanceof Chunk ? 1 : chunkCombination.size;
if (count < /** @type {number} */ (cacheGroup.minChunks))
continue;
if (count < cacheGroup.minChunks) continue;
// Select chunks by configuration
const { chunks: selectedChunks, key: selectedChunksKey } =
getSelectedChunks(
@ -1468,18 +1459,14 @@ module.exports = class SplitChunksPlugin {
) {
for (const chunk of usedChunks) {
// respect max requests
const maxRequests = /** @type {number} */ (
chunk.isOnlyInitial()
? item.cacheGroup.maxInitialRequests
: chunk.canBeInitial()
? Math.min(
/** @type {number} */
(item.cacheGroup.maxInitialRequests),
/** @type {number} */
(item.cacheGroup.maxAsyncRequests)
)
: item.cacheGroup.maxAsyncRequests
);
const maxRequests = chunk.isOnlyInitial()
? item.cacheGroup.maxInitialRequests
: chunk.canBeInitial()
? Math.min(
item.cacheGroup.maxInitialRequests,
item.cacheGroup.maxAsyncRequests
)
: item.cacheGroup.maxAsyncRequests;
if (
Number.isFinite(maxRequests) &&
getRequests(chunk) >= maxRequests
@ -1501,10 +1488,7 @@ module.exports = class SplitChunksPlugin {
if (usedChunks.size < item.chunks.size) {
if (isExistingChunk)
usedChunks.add(/** @type {Chunk} */ (newChunk));
if (
/** @type {number} */ (usedChunks.size) >=
/** @type {number} */ (item.cacheGroup.minChunks)
) {
if (usedChunks.size >= item.cacheGroup.minChunks) {
const chunksArr = Array.from(usedChunks);
for (const module of item.modules) {
addModuleToChunksInfoMap(
@ -1778,9 +1762,7 @@ module.exports = class SplitChunksPlugin {
hashFilename(name, outputOptions);
}
if (i !== results.length - 1) {
const newPart = compilation.addChunk(
/** @type {Chunk["name"]} */ (name)
);
const newPart = compilation.addChunk(name);
chunk.split(newPart);
newPart.chunkReason = chunk.chunkReason;
if (chunk.filenameTemplate) {
@ -1798,7 +1780,7 @@ module.exports = class SplitChunksPlugin {
}
} else {
// change the chunk to be a part
chunk.name = /** @type {Chunk["name"]} */ (name);
chunk.name = name;
}
}
}

View File

@ -0,0 +1 @@
module.exports = "a";

View File

@ -0,0 +1,4 @@
it("should work", async function() {
const a = await import(/* webpackChunkName: "chunk" */ "./a");
expect(a.default).toBe("a");
});

View File

@ -0,0 +1,5 @@
module.exports = {
findBundle: function (i, options) {
return ["common-a_js.js", "main.js"];
}
};

View File

@ -0,0 +1,20 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
target: "web",
output: {
filename: "[name].js"
},
optimization: {
chunkIds: "named",
splitChunks: {
cacheGroups: {
common: {
name: () => {},
test: /a\.js/,
chunks: "all",
enforce: true
}
}
}
}
};

2
types.d.ts vendored
View File

@ -969,7 +969,7 @@ declare abstract class CacheFacade {
): Promise<T>;
}
declare interface CacheGroupSource {
key?: string;
key: string;
priority?: number;
getName?: (
module: Module,