Skip to content

Commit 0f70fcb

Browse files
authored
Merge pull request webpack#6791 from storybooks/spilt-chunks-selector
Support selector function as optimization.splitChunks.chunks option
2 parents 3f6b78f + 1677144 commit 0f70fcb

File tree

4 files changed

+229
-22
lines changed

4 files changed

+229
-22
lines changed

lib/optimize/SplitChunksPlugin.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ module.exports = class SplitChunksPlugin {
8585

8686
static normalizeOptions(options = {}) {
8787
return {
88-
chunks: options.chunks || "all",
88+
chunksFilter: SplitChunksPlugin.normalizeChunksFilter(
89+
options.chunks || "all"
90+
),
8991
minSize: options.minSize || 0,
9092
minChunks: options.minChunks || 1,
9193
maxAsyncRequests: options.maxAsyncRequests || 1,
@@ -135,6 +137,19 @@ module.exports = class SplitChunksPlugin {
135137
if (typeof name === "function") return name;
136138
}
137139

140+
static normalizeChunksFilter(chunks) {
141+
if (chunks === "initial") {
142+
return chunk => chunk.canBeInitial();
143+
}
144+
if (chunks === "async") {
145+
return chunk => !chunk.canBeInitial();
146+
}
147+
if (chunks === "all") {
148+
return () => true;
149+
}
150+
if (typeof chunks === "function") return chunks;
151+
}
152+
138153
static normalizeCacheGroups({ cacheGroups, automaticNameDelimiter }) {
139154
if (typeof cacheGroups === "function") {
140155
return cacheGroups;
@@ -162,6 +177,11 @@ module.exports = class SplitChunksPlugin {
162177
r
163178
);
164179
if (result.name) result.getName = () => result.name;
180+
if (result.chunks) {
181+
result.chunksFilter = SplitChunksPlugin.normalizeChunksFilter(
182+
result.chunks
183+
);
184+
}
165185
results.push(result);
166186
}
167187
}
@@ -174,7 +194,9 @@ module.exports = class SplitChunksPlugin {
174194
name: option.name,
175195
automaticNameDelimiter
176196
}),
177-
chunks: option.chunks,
197+
chunksFilter: SplitChunksPlugin.normalizeChunksFilter(
198+
option.chunks
199+
),
178200
enforce: option.enforce,
179201
minSize: option.minSize,
180202
minChunks: option.minChunks,
@@ -264,7 +286,8 @@ module.exports = class SplitChunksPlugin {
264286
const cacheGroup = {
265287
key: cacheGroupSource.key,
266288
priority: cacheGroupSource.priority || 0,
267-
chunks: cacheGroupSource.chunks || this.options.chunks,
289+
chunksFilter:
290+
cacheGroupSource.chunksFilter || this.options.chunksFilter,
268291
minSize:
269292
cacheGroupSource.minSize !== undefined
270293
? cacheGroupSource.minSize
@@ -304,16 +327,9 @@ module.exports = class SplitChunksPlugin {
304327
// Break if minimum number of chunks is not reached
305328
if (chunkIndices.length < cacheGroup.minChunks) continue;
306329
// Select chunks by configuration
307-
const selectedChunks =
308-
cacheGroup.chunks === "initial"
309-
? Array.from(chunkCombination).filter(chunk =>
310-
chunk.canBeInitial()
311-
)
312-
: cacheGroup.chunks === "async"
313-
? Array.from(chunkCombination).filter(
314-
chunk => !chunk.canBeInitial()
315-
)
316-
: Array.from(chunkCombination);
330+
const selectedChunks = Array.from(chunkCombination).filter(
331+
cacheGroup.chunksFilter
332+
);
317333
// Break if minimum number of chunks is not reached
318334
if (selectedChunks.length < cacheGroup.minChunks) continue;
319335
// Determine name for split chunk

schemas/WebpackOptions.json

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,10 +1330,17 @@
13301330
"properties": {
13311331
"chunks": {
13321332
"description": "Select chunks for determining shared modules (defaults to \"async\", \"initial\" and \"all\" requires adding these chunks to the HTML)",
1333-
"enum": [
1334-
"initial",
1335-
"async",
1336-
"all"
1333+
"oneOf": [
1334+
{
1335+
"enum": [
1336+
"initial",
1337+
"async",
1338+
"all"
1339+
]
1340+
},
1341+
{
1342+
"instanceof": "Function"
1343+
}
13371344
]
13381345
},
13391346
"minSize": {
@@ -1420,10 +1427,17 @@
14201427
},
14211428
"chunks": {
14221429
"description": "Select chunks for determining cache group content (defaults to \"initial\", \"initial\" and \"all\" requires adding these chunks to the HTML)",
1423-
"enum": [
1424-
"initial",
1425-
"async",
1426-
"all"
1430+
"oneOf": [
1431+
{
1432+
"enum": [
1433+
"initial",
1434+
"async",
1435+
"all"
1436+
]
1437+
},
1438+
{
1439+
"instanceof": "Function"
1440+
}
14271441
]
14281442
},
14291443
"enforce": {

test/statsCases/split-chunks/expected.txt

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,129 @@ Child name-too-long:
257257
> ./c cccccccccccccccccccccccccccccc
258258
[0] ./d.js 20 bytes {1} {10} {11} {12} [built]
259259
[1] ./f.js 20 bytes {2} {11} {12} [built]
260-
[5] ./c.js 72 bytes {7} {12} [built]
260+
[5] ./c.js 72 bytes {7} {12} [built]
261+
Child custom-chunks-filter:
262+
Entrypoint main = default/main.js
263+
Entrypoint a = default/a.js
264+
Entrypoint b = default/vendors~async-a~async-b~async-c~b~c.js default/vendors~async-a~async-b~b.js default/b.js
265+
Entrypoint c = default/vendors~async-a~async-b~async-c~b~c.js default/vendors~async-c~c.js default/c.js
266+
chunk {0} default/vendors~async-a~async-b~async-c~b~c.js (vendors~async-a~async-b~async-c~b~c) 20 bytes <{9}> ={1}= ={11}= ={12}= ={2}= ={3}= ={4}= ={6}= ={7}= ={8}= >{2}< >{5}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors~async-a~async-b~async-c~b~c)
267+
> ./b b
268+
> ./c c
269+
> ./a [8] ./index.js 1:0-47
270+
> ./b [8] ./index.js 2:0-47
271+
> ./c [8] ./index.js 3:0-47
272+
[2] ./node_modules/x.js 20 bytes {0} {10} [built]
273+
chunk {1} default/async-a~async-b~async-c~b~c.js (async-a~async-b~async-c~b~c) 20 bytes <{9}> ={0}= ={2}= ={3}= ={4}= ={6}= ={7}= ={8}= >{2}< >{5}< [rendered] split chunk (cache group: default) (name: async-a~async-b~async-c~b~c)
274+
> ./a [8] ./index.js 1:0-47
275+
> ./b [8] ./index.js 2:0-47
276+
> ./c [8] ./index.js 3:0-47
277+
[0] ./d.js 20 bytes {1} {10} {11} {12} [built]
278+
chunk {2} default/async-b~async-c~async-g~b~c.js (async-b~async-c~async-g~b~c) 20 bytes <{0}> <{1}> <{10}> <{3}> <{6}> <{9}> ={0}= ={1}= ={3}= ={4}= ={5}= ={7}= ={8}= [rendered] split chunk (cache group: default) (name: async-b~async-c~async-g~b~c)
279+
> ./g [] 6:0-47
280+
> ./g [] 6:0-47
281+
> ./b [8] ./index.js 2:0-47
282+
> ./c [8] ./index.js 3:0-47
283+
[1] ./f.js 20 bytes {2} {11} {12} [built]
284+
chunk {3} default/vendors~async-a~async-b~b.js (vendors~async-a~async-b~b) 20 bytes <{9}> ={0}= ={1}= ={11}= ={2}= ={6}= ={7}= >{2}< >{5}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors~async-a~async-b~b)
285+
> ./b b
286+
> ./a [8] ./index.js 1:0-47
287+
> ./b [8] ./index.js 2:0-47
288+
[3] ./node_modules/y.js 20 bytes {3} {10} [built]
289+
chunk {4} default/vendors~async-c~c.js (vendors~async-c~c) 20 bytes <{9}> ={0}= ={1}= ={12}= ={2}= ={8}= [initial] [rendered] split chunk (cache group: vendors) (name: vendors~async-c~c)
290+
> ./c c
291+
> ./c [8] ./index.js 3:0-47
292+
[7] ./node_modules/z.js 20 bytes {4} [built]
293+
chunk {5} default/async-g.js (async-g) 34 bytes <{0}> <{1}> <{10}> <{3}> <{6}> ={2}= [rendered]
294+
> ./g [] 6:0-47
295+
> ./g [] 6:0-47
296+
[9] ./g.js 34 bytes {5} [built]
297+
chunk {6} default/async-a.js (async-a) 156 bytes <{9}> ={0}= ={1}= ={3}= >{2}< >{5}< [rendered]
298+
> ./a [8] ./index.js 1:0-47
299+
[6] ./a.js + 1 modules 156 bytes {6} {10} [built]
300+
| ./a.js 121 bytes [built]
301+
| ./e.js 20 bytes [built]
302+
chunk {7} default/async-b.js (async-b) 72 bytes <{9}> ={0}= ={1}= ={2}= ={3}= [rendered]
303+
> ./b [8] ./index.js 2:0-47
304+
[4] ./b.js 72 bytes {7} {11} [built]
305+
chunk {8} default/async-c.js (async-c) 72 bytes <{9}> ={0}= ={1}= ={2}= ={4}= [rendered]
306+
> ./c [8] ./index.js 3:0-47
307+
[5] ./c.js 72 bytes {8} {12} [built]
308+
chunk {9} default/main.js (main) 147 bytes >{0}< >{1}< >{2}< >{3}< >{4}< >{6}< >{7}< >{8}< [entry] [rendered]
309+
> ./ main
310+
[8] ./index.js 147 bytes {9} [built]
311+
chunk {10} default/a.js (a) 216 bytes >{2}< >{5}< [entry] [rendered]
312+
> ./a a
313+
[0] ./d.js 20 bytes {1} {10} {11} {12} [built]
314+
[2] ./node_modules/x.js 20 bytes {0} {10} [built]
315+
[3] ./node_modules/y.js 20 bytes {3} {10} [built]
316+
[6] ./a.js + 1 modules 156 bytes {6} {10} [built]
317+
| ./a.js 121 bytes [built]
318+
| ./e.js 20 bytes [built]
319+
chunk {11} default/b.js (b) 112 bytes ={0}= ={3}= [entry] [rendered]
320+
> ./b b
321+
[0] ./d.js 20 bytes {1} {10} {11} {12} [built]
322+
[1] ./f.js 20 bytes {2} {11} {12} [built]
323+
[4] ./b.js 72 bytes {7} {11} [built]
324+
chunk {12} default/c.js (c) 112 bytes ={0}= ={4}= [entry] [rendered]
325+
> ./c c
326+
[0] ./d.js 20 bytes {1} {10} {11} {12} [built]
327+
[1] ./f.js 20 bytes {2} {11} {12} [built]
328+
[5] ./c.js 72 bytes {8} {12} [built]
329+
Child custom-chunks-filter-in-cache-groups:
330+
Entrypoint main = default/main.js
331+
Entrypoint a = default/a.js
332+
Entrypoint b = default/vendors.js default/b.js
333+
Entrypoint c = default/vendors.js default/c.js
334+
chunk {0} default/vendors.js (vendors) 112 bytes <{5}> ={2}= ={3}= ={4}= ={7}= ={8}= >{1}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors)
335+
> ./b b
336+
> ./c c
337+
> ./a [8] ./index.js 1:0-47
338+
> ./b [8] ./index.js 2:0-47
339+
> ./c [8] ./index.js 3:0-47
340+
[2] ./node_modules/x.js 20 bytes {0} {6} [built]
341+
[3] ./node_modules/y.js 20 bytes {0} {6} [built]
342+
[6] ./node_modules/z.js 20 bytes {0} [built]
343+
[10] multi x y z 52 bytes {0} [built]
344+
chunk {1} default/async-g.js (async-g) 54 bytes <{0}> <{2}> <{6}> [rendered]
345+
> ./g [] 6:0-47
346+
> ./g [] 6:0-47
347+
[1] ./f.js 20 bytes {1} {3} {4} {7} {8} [built]
348+
[9] ./g.js 34 bytes {1} [built]
349+
chunk {2} default/async-a.js (async-a) 176 bytes <{5}> ={0}= >{1}< [rendered]
350+
> ./a [8] ./index.js 1:0-47
351+
[0] ./d.js 20 bytes {2} {3} {4} {6} {7} {8} [built]
352+
[7] ./a.js + 1 modules 156 bytes {2} {6} [built]
353+
| ./a.js 121 bytes [built]
354+
| ./e.js 20 bytes [built]
355+
chunk {3} default/async-b.js (async-b) 112 bytes <{5}> ={0}= [rendered]
356+
> ./b [8] ./index.js 2:0-47
357+
[0] ./d.js 20 bytes {2} {3} {4} {6} {7} {8} [built]
358+
[1] ./f.js 20 bytes {1} {3} {4} {7} {8} [built]
359+
[4] ./b.js 72 bytes {3} {7} [built]
360+
chunk {4} default/async-c.js (async-c) 112 bytes <{5}> ={0}= [rendered]
361+
> ./c [8] ./index.js 3:0-47
362+
[0] ./d.js 20 bytes {2} {3} {4} {6} {7} {8} [built]
363+
[1] ./f.js 20 bytes {1} {3} {4} {7} {8} [built]
364+
[5] ./c.js 72 bytes {4} {8} [built]
365+
chunk {5} default/main.js (main) 147 bytes >{0}< >{2}< >{3}< >{4}< [entry] [rendered]
366+
> ./ main
367+
[8] ./index.js 147 bytes {5} [built]
368+
chunk {6} default/a.js (a) 216 bytes >{1}< [entry] [rendered]
369+
> ./a a
370+
[0] ./d.js 20 bytes {2} {3} {4} {6} {7} {8} [built]
371+
[2] ./node_modules/x.js 20 bytes {0} {6} [built]
372+
[3] ./node_modules/y.js 20 bytes {0} {6} [built]
373+
[7] ./a.js + 1 modules 156 bytes {2} {6} [built]
374+
| ./a.js 121 bytes [built]
375+
| ./e.js 20 bytes [built]
376+
chunk {7} default/b.js (b) 112 bytes ={0}= [entry] [rendered]
377+
> ./b b
378+
[0] ./d.js 20 bytes {2} {3} {4} {6} {7} {8} [built]
379+
[1] ./f.js 20 bytes {1} {3} {4} {7} {8} [built]
380+
[4] ./b.js 72 bytes {3} {7} [built]
381+
chunk {8} default/c.js (c) 112 bytes ={0}= [entry] [rendered]
382+
> ./c c
383+
[0] ./d.js 20 bytes {2} {3} {4} {6} {7} {8} [built]
384+
[1] ./f.js 20 bytes {1} {3} {4} {7} {8} [built]
385+
[5] ./c.js 72 bytes {4} {8} [built]

test/statsCases/split-chunks/webpack.config.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,57 @@ module.exports = [
9898
}
9999
},
100100
stats
101+
},
102+
103+
{
104+
name: "custom-chunks-filter",
105+
mode: "production",
106+
entry: {
107+
main: "./",
108+
a: "./a",
109+
b: "./b",
110+
c: "./c"
111+
},
112+
output: {
113+
filename: "default/[name].js"
114+
},
115+
optimization: {
116+
splitChunks: {
117+
minSize: 0,
118+
chunks: chunk => chunk.name !== "a"
119+
}
120+
},
121+
stats
122+
},
123+
124+
{
125+
name: "custom-chunks-filter-in-cache-groups",
126+
mode: "production",
127+
entry: {
128+
main: "./",
129+
a: "./a",
130+
b: "./b",
131+
c: "./c",
132+
vendors: ["x", "y", "z"]
133+
},
134+
output: {
135+
filename: "default/[name].js"
136+
},
137+
optimization: {
138+
splitChunks: {
139+
minSize: 0,
140+
chunks: "all",
141+
cacheGroups: {
142+
default: false,
143+
vendors: {
144+
test: "vendors",
145+
name: "vendors",
146+
enforce: true,
147+
chunks: chunk => chunk.name !== "a"
148+
}
149+
}
150+
}
151+
},
152+
stats
101153
}
102154
];

0 commit comments

Comments
 (0)