Skip to content

Commit d688f4d

Browse files
authored
feat: split chunks overall filename (#9243)
1 parent 38fbd20 commit d688f4d

File tree

16 files changed

+143
-57
lines changed

16 files changed

+143
-57
lines changed

Diff for: crates/node_binding/binding.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,7 @@ export interface RawSplitChunkSizes {
22132213
export interface RawSplitChunksOptions {
22142214
fallbackCacheGroup?: RawFallbackCacheGroupOptions
22152215
name?: string | false | Function
2216+
filename?: JsFilename
22162217
cacheGroups?: Array<RawCacheGroupOptions>
22172218
/** What kind of chunks should be selected. */
22182219
chunks?: RegExp | 'async' | 'initial' | 'all' | Function

Diff for: crates/rspack_binding_values/src/raw_options/raw_split_chunks/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub struct RawSplitChunksOptions {
3333
#[napi(ts_type = "string | false | Function")]
3434
#[debug(skip)]
3535
pub name: Option<RawChunkOptionName>,
36+
pub filename: Option<JsFilename>,
3637
pub cache_groups: Option<Vec<RawCacheGroupOptions>>,
3738
/// What kind of chunks should be selected.
3839
#[napi(ts_type = "RegExp | 'async' | 'initial' | 'all' | Function")]
@@ -107,6 +108,8 @@ impl From<RawSplitChunksOptions> for rspack_plugin_split_chunks::PluginOptions {
107108

108109
let mut cache_groups = vec![];
109110

111+
let overall_filename = raw_opts.filename.map(Filename::from);
112+
110113
let overall_chunk_filter = raw_opts.chunks.map(create_chunks_filter);
111114

112115
let overall_min_chunks = raw_opts.min_chunks.unwrap_or(1);
@@ -214,7 +217,10 @@ impl From<RawSplitChunksOptions> for rspack_plugin_split_chunks::PluginOptions {
214217
automatic_name_delimiter: v
215218
.automatic_name_delimiter
216219
.unwrap_or(overall_automatic_name_delimiter.clone()),
217-
filename: v.filename.map(Filename::from),
220+
filename: v
221+
.filename
222+
.map(Filename::from)
223+
.or_else(|| overall_filename.clone()),
218224
reuse_existing_chunk: v.reuse_existing_chunk.unwrap_or(false),
219225
max_async_requests: v.max_async_requests.unwrap_or(f64::INFINITY),
220226
max_initial_requests: v.max_initial_requests.unwrap_or(f64::INFINITY),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import "./shared1";
2+
import "./common1";
3+
4+
it("should be able to load the split chunk on demand (shared)", () => {
5+
return import(/* webpackChunkName: "theName" */ "./shared2");
6+
});
7+
8+
it("should be able to load the split chunk on demand (common)", () => {
9+
return Promise.all([
10+
import(/* webpackChunkName: "otherName1" */ "./common2"),
11+
import(/* webpackChunkName: "otherName2" */ "./common3")
12+
]);
13+
});
14+
15+
it("should have files", async () => {
16+
const fs = require("fs");
17+
const path = require("path");
18+
const files = await fs.promises.readdir(__dirname);
19+
expect(files).toContain("shared-shared-shared1_js.js");
20+
expect(files).toContain("shared-shared-shared2_js.js");
21+
expect(files).toContain("splitted-chunks");
22+
const innerFiles = await fs.promises.readdir(path.resolve(__dirname, "splitted-chunks"));
23+
expect(innerFiles).toContain("common-common1_js.js");
24+
expect(innerFiles).toContain("common-common2_js.js");
25+
expect(innerFiles).toContain("common-common3_js.js");
26+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import "./shared1";
2+
import "./shared2";
3+
import "./common1";
4+
import "./common2";
5+
import "./common3";

Diff for: packages/rspack-test-tools/tests/configCases/split-chunks/custom-filename-overall/common1.js

Whitespace-only changes.

Diff for: packages/rspack-test-tools/tests/configCases/split-chunks/custom-filename-overall/common2.js

Whitespace-only changes.

Diff for: packages/rspack-test-tools/tests/configCases/split-chunks/custom-filename-overall/common3.js

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/** @type {import("@rspack/core").Configuration} */
2+
module.exports = {
3+
mode: "development",
4+
entry: {
5+
a: "./a",
6+
b: "./b"
7+
},
8+
output: {
9+
filename: "[name].js",
10+
libraryTarget: "commonjs2"
11+
},
12+
optimization: {
13+
chunkIds: "named",
14+
splitChunks: {
15+
filename: "splitted-chunks/[name].js",
16+
cacheGroups: {
17+
shared: {
18+
chunks: "all",
19+
test: /shared/,
20+
filename: "shared-[name].js",
21+
enforce: true
22+
},
23+
common: {
24+
chunks: "all",
25+
test: /common/,
26+
enforce: true
27+
}
28+
}
29+
}
30+
}
31+
};

Diff for: packages/rspack-test-tools/tests/configCases/split-chunks/custom-filename-overall/shared1.js

Whitespace-only changes.

Diff for: packages/rspack-test-tools/tests/configCases/split-chunks/custom-filename-overall/shared2.js

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/** @type {import("../../../..").TConfigCaseConfig} */
2+
module.exports = {
3+
findBundle: function (i, options) {
4+
return ["a.js"];
5+
}
6+
};

Diff for: packages/rspack/etc/core.api.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -4260,7 +4260,6 @@ export type OptimizationSplitChunksCacheGroup = {
42604260
test?: string | RegExp | ((module: Module) => unknown);
42614261
priority?: number;
42624262
enforce?: boolean;
4263-
filename?: Filename;
42644263
reuseExistingChunk?: boolean;
42654264
type?: string | RegExp;
42664265
idHint?: string;
@@ -7147,6 +7146,7 @@ export const rspackOptions: z.ZodObject<{
71477146
minChunks: z.ZodOptional<z.ZodNumber>;
71487147
usedExports: z.ZodOptional<z.ZodBoolean>;
71497148
name: z.ZodOptional<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodLiteral<false>]>, z.ZodFunction<z.ZodTuple<[z.ZodType<Module, z.ZodTypeDef, Module>, z.ZodArray<z.ZodType<Chunk, z.ZodTypeDef, Chunk>, "many">, z.ZodString], z.ZodUnknown>, z.ZodOptional<z.ZodString>>]>>;
7149+
filename: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<PathData, z.ZodTypeDef, PathData>, z.ZodOptional<z.ZodType<JsAssetInfo, z.ZodTypeDef, JsAssetInfo>>], z.ZodUnknown>, z.ZodString>]>>;
71507150
minSize: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodRecord<z.ZodString, z.ZodNumber>]>>;
71517151
maxSize: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodRecord<z.ZodString, z.ZodNumber>]>>;
71527152
maxAsyncSize: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodRecord<z.ZodString, z.ZodNumber>]>>;
@@ -7160,6 +7160,7 @@ export const rspackOptions: z.ZodObject<{
71607160
minChunks: z.ZodOptional<z.ZodNumber>;
71617161
usedExports: z.ZodOptional<z.ZodBoolean>;
71627162
name: z.ZodOptional<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodLiteral<false>]>, z.ZodFunction<z.ZodTuple<[z.ZodType<Module, z.ZodTypeDef, Module>, z.ZodArray<z.ZodType<Chunk, z.ZodTypeDef, Chunk>, "many">, z.ZodString], z.ZodUnknown>, z.ZodOptional<z.ZodString>>]>>;
7163+
filename: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<PathData, z.ZodTypeDef, PathData>, z.ZodOptional<z.ZodType<JsAssetInfo, z.ZodTypeDef, JsAssetInfo>>], z.ZodUnknown>, z.ZodString>]>>;
71637164
minSize: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodRecord<z.ZodString, z.ZodNumber>]>>;
71647165
maxSize: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodRecord<z.ZodString, z.ZodNumber>]>>;
71657166
maxAsyncSize: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodRecord<z.ZodString, z.ZodNumber>]>>;
@@ -7170,7 +7171,6 @@ export const rspackOptions: z.ZodObject<{
71707171
test: z.ZodOptional<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, z.ZodFunction<z.ZodTuple<[z.ZodType<Module, z.ZodTypeDef, Module>], z.ZodUnknown>, z.ZodUnknown>]>>;
71717172
priority: z.ZodOptional<z.ZodNumber>;
71727173
enforce: z.ZodOptional<z.ZodBoolean>;
7173-
filename: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodFunction<z.ZodTuple<[z.ZodType<PathData, z.ZodTypeDef, PathData>, z.ZodOptional<z.ZodType<JsAssetInfo, z.ZodTypeDef, JsAssetInfo>>], z.ZodUnknown>, z.ZodString>]>>;
71747174
reuseExistingChunk: z.ZodOptional<z.ZodBoolean>;
71757175
type: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>>;
71767176
idHint: z.ZodOptional<z.ZodString>;
@@ -7244,6 +7244,7 @@ export const rspackOptions: z.ZodObject<{
72447244
}, "strict", z.ZodTypeAny, {
72457245
chunks?: RegExp | "initial" | "async" | "all" | ((args_0: Chunk, ...args: unknown[]) => boolean) | undefined;
72467246
name?: string | false | ((args_0: Module, args_1: Chunk[], args_2: string, ...args: unknown[]) => string | undefined) | undefined;
7247+
filename?: string | ((args_0: PathData, args_1: JsAssetInfo | undefined, ...args: unknown[]) => string) | undefined;
72477248
usedExports?: boolean | undefined;
72487249
defaultSizeTypes?: string[] | undefined;
72497250
cacheGroups?: Record<string, false | {
@@ -7288,6 +7289,7 @@ export const rspackOptions: z.ZodObject<{
72887289
}, {
72897290
chunks?: RegExp | "initial" | "async" | "all" | ((args_0: Chunk, ...args: unknown[]) => boolean) | undefined;
72907291
name?: string | false | ((args_0: Module, args_1: Chunk[], args_2: string, ...args: unknown[]) => string | undefined) | undefined;
7292+
filename?: string | ((args_0: PathData, args_1: JsAssetInfo | undefined, ...args: unknown[]) => string) | undefined;
72917293
usedExports?: boolean | undefined;
72927294
defaultSizeTypes?: string[] | undefined;
72937295
cacheGroups?: Record<string, false | {
@@ -7371,6 +7373,7 @@ export const rspackOptions: z.ZodObject<{
73717373
splitChunks?: false | {
73727374
chunks?: RegExp | "initial" | "async" | "all" | ((args_0: Chunk, ...args: unknown[]) => boolean) | undefined;
73737375
name?: string | false | ((args_0: Module, args_1: Chunk[], args_2: string, ...args: unknown[]) => string | undefined) | undefined;
7376+
filename?: string | ((args_0: PathData, args_1: JsAssetInfo | undefined, ...args: unknown[]) => string) | undefined;
73747377
usedExports?: boolean | undefined;
73757378
defaultSizeTypes?: string[] | undefined;
73767379
cacheGroups?: Record<string, false | {
@@ -7439,6 +7442,7 @@ export const rspackOptions: z.ZodObject<{
74397442
splitChunks?: false | {
74407443
chunks?: RegExp | "initial" | "async" | "all" | ((args_0: Chunk, ...args: unknown[]) => boolean) | undefined;
74417444
name?: string | false | ((args_0: Module, args_1: Chunk[], args_2: string, ...args: unknown[]) => string | undefined) | undefined;
7445+
filename?: string | ((args_0: PathData, args_1: JsAssetInfo | undefined, ...args: unknown[]) => string) | undefined;
74427446
usedExports?: boolean | undefined;
74437447
defaultSizeTypes?: string[] | undefined;
74447448
cacheGroups?: Record<string, false | {
@@ -9067,6 +9071,7 @@ export const rspackOptions: z.ZodObject<{
90679071
splitChunks?: false | {
90689072
chunks?: RegExp | "initial" | "async" | "all" | ((args_0: Chunk, ...args: unknown[]) => boolean) | undefined;
90699073
name?: string | false | ((args_0: Module, args_1: Chunk[], args_2: string, ...args: unknown[]) => string | undefined) | undefined;
9074+
filename?: string | ((args_0: PathData, args_1: JsAssetInfo | undefined, ...args: unknown[]) => string) | undefined;
90709075
usedExports?: boolean | undefined;
90719076
defaultSizeTypes?: string[] | undefined;
90729077
cacheGroups?: Record<string, false | {
@@ -9674,6 +9679,7 @@ export const rspackOptions: z.ZodObject<{
96749679
splitChunks?: false | {
96759680
chunks?: RegExp | "initial" | "async" | "all" | ((args_0: Chunk, ...args: unknown[]) => boolean) | undefined;
96769681
name?: string | false | ((args_0: Module, args_1: Chunk[], args_2: string, ...args: unknown[]) => string | undefined) | undefined;
9682+
filename?: string | ((args_0: PathData, args_1: JsAssetInfo | undefined, ...args: unknown[]) => string) | undefined;
96779683
usedExports?: boolean | undefined;
96789684
defaultSizeTypes?: string[] | undefined;
96799685
cacheGroups?: Record<string, false | {
@@ -10149,6 +10155,7 @@ type SharedOptimizationSplitChunksCacheGroup = {
1014910155
minChunks?: number;
1015010156
usedExports?: boolean;
1015110157
name?: false | OptimizationSplitChunksName;
10158+
filename?: Filename;
1015210159
minSize?: OptimizationSplitChunksSizes;
1015310160
maxSize?: OptimizationSplitChunksSizes;
1015410161
maxAsyncSize?: OptimizationSplitChunksSizes;

Diff for: packages/rspack/src/config/types.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,9 @@ type SharedOptimizationSplitChunksCacheGroup = {
21492149
* */
21502150
name?: false | OptimizationSplitChunksName;
21512151

2152+
/** Allows to override the filename when and only when it's an initial chunk. */
2153+
filename?: Filename;
2154+
21522155
/**
21532156
* Minimum size, in bytes, for a chunk to be generated.
21542157
*
@@ -2202,9 +2205,6 @@ export type OptimizationSplitChunksCacheGroup = {
22022205
*/
22032206
enforce?: boolean;
22042207

2205-
/** Allows to override the filename when and only when it's an initial chunk. */
2206-
filename?: Filename;
2207-
22082208
/**
22092209
* Whether to reuse existing chunks when possible.
22102210
* @default false

Diff for: packages/rspack/src/config/zod.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,7 @@ const sharedOptimizationSplitChunksCacheGroup = {
12061206
minChunks: z.number().min(1).optional(),
12071207
usedExports: z.boolean().optional(),
12081208
name: optimizationSplitChunksName.optional(),
1209+
filename: filename.optional(),
12091210
minSize: optimizationSplitChunksSizes.optional(),
12101211
maxSize: optimizationSplitChunksSizes.optional(),
12111212
maxAsyncSize: optimizationSplitChunksSizes.optional(),
@@ -1226,7 +1227,6 @@ const optimizationSplitChunksCacheGroup = z.strictObject({
12261227
.optional(),
12271228
priority: z.number().optional(),
12281229
enforce: z.boolean().optional(),
1229-
filename: filename.optional(),
12301230
reuseExistingChunk: z.boolean().optional(),
12311231
type: z.string().or(z.instanceof(RegExp)).optional(),
12321232
idHint: z.string().optional(),

Diff for: website/docs/en/plugins/webpack/split-chunks-plugin.mdx

+27-25
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,33 @@ If the `splitChunks.name` matches an [entry point](/config/entry) name, the entr
223223

224224
:::
225225

226+
### splitChunks.filename
227+
228+
#### splitChunks.cacheGroups.\{cacheGroup\}.filename
229+
230+
- **Type:** `string | function`
231+
232+
Allows to override the filename when and only when it's an initial chunk. All placeholders available in output.filename are also available here.
233+
234+
```js title="rspack.config.mjs"
235+
export default {
236+
//...
237+
optimization: {
238+
splitChunks: {
239+
cacheGroups: {
240+
defaultVendors: {
241+
filename: 'vendors-[name].js',
242+
// or
243+
filename: (pathData, assetInfo) => {
244+
return `${pathData.chunk.name}-bundle.js`;
245+
},
246+
},
247+
},
248+
},
249+
},
250+
};
251+
```
252+
226253
### splitChunks.usedExports
227254

228255
<ApiMeta addedVersion="1.0.0" />
@@ -323,31 +350,6 @@ Tells Rspack to ignore `splitChunks.minSize`, splitChunks`.minChunks`, `splitChu
323350

324351
Sets the hint for chunk id. It will be added to chunk's filename.
325352

326-
#### splitChunks.cacheGroups.\{cacheGroup\}.filename
327-
328-
- **Type:** `string | function`
329-
330-
Allows to override the filename when and only when it's an initial chunk. All placeholders available in output.filename are also available here.
331-
332-
```js title="rspack.config.mjs"
333-
export default {
334-
//...
335-
optimization: {
336-
splitChunks: {
337-
cacheGroups: {
338-
defaultVendors: {
339-
filename: 'vendors-[name].js',
340-
// or
341-
filename: (pathData, assetInfo) => {
342-
return `${pathData.chunk.name}-bundle.js`;
343-
},
344-
},
345-
},
346-
},
347-
},
348-
};
349-
```
350-
351353
#### splitChunks.cacheGroups.\{cacheGroup\}.reuseExistingChunk
352354

353355
- **Type:** `boolean`

Diff for: website/docs/zh/plugins/webpack/split-chunks-plugin.mdx

+27-25
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,33 @@ export default {
213213

214214
:::
215215

216+
### splitChunks.filename
217+
218+
#### splitChunks.cacheGroups.\{cacheGroup\}.filename
219+
220+
- **类型:** `string | function`
221+
222+
仅在初始 chunk 时才允许覆盖文件名。 也可以在 output.filename 中使用所有占位符。
223+
224+
```js title="rspack.config.mjs"
225+
export default {
226+
//...
227+
optimization: {
228+
splitChunks: {
229+
cacheGroups: {
230+
defaultVendors: {
231+
filename: 'vendors-[name].js',
232+
// or
233+
filename: (pathData, assetInfo) => {
234+
return `${pathData.chunk.name}-bundle.js`;
235+
},
236+
},
237+
},
238+
},
239+
},
240+
};
241+
```
242+
216243
### splitChunks.usedExports
217244

218245
<ApiMeta addedVersion="1.0.0" />
@@ -313,31 +340,6 @@ export default {
313340

314341
设置 chunk id 的提示。 它将被添加到 chunk 的文件名中。
315342

316-
#### splitChunks.cacheGroups.\{cacheGroup\}.filename
317-
318-
- **类型:** `string | function`
319-
320-
仅在初始 chunk 时才允许覆盖文件名。 也可以在 output.filename 中使用所有占位符。
321-
322-
```js title="rspack.config.mjs"
323-
export default {
324-
//...
325-
optimization: {
326-
splitChunks: {
327-
cacheGroups: {
328-
defaultVendors: {
329-
filename: 'vendors-[name].js',
330-
// or
331-
filename: (pathData, assetInfo) => {
332-
return `${pathData.chunk.name}-bundle.js`;
333-
},
334-
},
335-
},
336-
},
337-
},
338-
};
339-
```
340-
341343
#### splitChunks.cacheGroups.\{cacheGroup\}.reuseExistingChunk
342344

343345
- **类型:** `boolean`

0 commit comments

Comments
 (0)