Skip to content

Commit c9af289

Browse files
committed
fix: avoid chunk conflication when muliple libs present
1 parent f6981ca commit c9af289

File tree

15 files changed

+292
-17
lines changed

15 files changed

+292
-17
lines changed

packages/core/src/config.ts

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -973,10 +973,11 @@ const composeExternalsConfig = (
973973
};
974974
};
975975

976-
const composeAutoExtensionConfig = (
976+
const composeOutputFilenameConfig = (
977977
config: LibConfig,
978978
format: Format,
979979
autoExtension: boolean,
980+
multiCompilerIndex: number | null,
980981
pkgJson?: PkgJson,
981982
): {
982983
config: EnvironmentConfig;
@@ -998,9 +999,38 @@ const composeAutoExtensionConfig = (
998999
return filenameHash ? '.[contenthash:8]' : '';
9991000
};
10001001

1002+
// Copied from https://github.com/web-infra-dev/rspack/blob/2efea8673f86a562559e26a9351680e8df4d9ae9/packages/rspack/src/config/defaults.ts#L667-L680.
1003+
const inferChunkFilename = (filename: string): string | undefined => {
1004+
if (typeof filename !== 'function') {
1005+
const hasName = filename.includes('[name]');
1006+
const hasId = filename.includes('[id]');
1007+
const hasChunkHash = filename.includes('[chunkhash]');
1008+
const hasContentHash = filename.includes('[contenthash]');
1009+
const multiCompilerPrefix =
1010+
typeof multiCompilerIndex === 'number' ? `${multiCompilerIndex}~` : '';
1011+
// Anything changing depending on chunk is fine
1012+
1013+
if (hasChunkHash || hasContentHash || hasName || hasId)
1014+
return filename.replace(
1015+
/(^|\/)([^/]*(?:\?|$))/,
1016+
`$1${multiCompilerPrefix}$2`,
1017+
);
1018+
// Otherwise prefix "[id]." in front of the basename to make it changing
1019+
return filename.replace(
1020+
/(^|\/)([^/]*(?:\?|$))/,
1021+
`$1${multiCompilerIndex}[id].$2`,
1022+
);
1023+
}
1024+
1025+
return undefined;
1026+
};
1027+
10011028
const hash = getHash();
10021029
const defaultJsFilename = `[name]${hash}${jsExtension}`;
10031030
const userJsFilename = config.output?.filename?.js;
1031+
const defaultJsChunkFilename = inferChunkFilename(
1032+
(userJsFilename as string) ?? defaultJsFilename,
1033+
);
10041034

10051035
// will be returned to use in redirect feature
10061036
// only support string type for now since we can not get the return value of function
@@ -1009,15 +1039,25 @@ const composeAutoExtensionConfig = (
10091039
? extname(userJsFilename)
10101040
: jsExtension;
10111041

1012-
const finalConfig = userJsFilename
1013-
? {}
1014-
: {
1042+
const chunkFilename: RsbuildConfig = {
1043+
tools: {
1044+
rspack: {
1045+
output: {
1046+
chunkFilename: defaultJsChunkFilename,
1047+
},
1048+
},
1049+
},
1050+
};
1051+
1052+
const finalConfig: RsbuildConfig = userJsFilename
1053+
? chunkFilename
1054+
: mergeRsbuildConfig(chunkFilename, {
10151055
output: {
10161056
filename: {
10171057
js: defaultJsFilename,
10181058
},
10191059
},
1020-
};
1060+
});
10211061

10221062
return {
10231063
config: finalConfig,
@@ -1604,6 +1644,7 @@ const composeExternalHelpersConfig = (
16041644

16051645
async function composeLibRsbuildConfig(
16061646
config: LibConfig,
1647+
multiCompilerIndex: number | null, // null means there's non multi-compiler
16071648
root?: string,
16081649
sharedPlugins?: RsbuildPlugins,
16091650
) {
@@ -1649,17 +1690,28 @@ async function composeLibRsbuildConfig(
16491690
config.output?.externals,
16501691
);
16511692
const {
1652-
config: autoExtensionConfig,
1693+
config: outputFilenameConfig,
16531694
jsExtension,
16541695
dtsExtension,
1655-
} = composeAutoExtensionConfig(config, format, autoExtension, pkgJson);
1696+
} = composeOutputFilenameConfig(
1697+
config,
1698+
format,
1699+
autoExtension,
1700+
multiCompilerIndex,
1701+
pkgJson,
1702+
);
16561703
const { entryConfig, outBase } = await composeEntryConfig(
16571704
config.source?.entry!,
16581705
config.bundle,
16591706
rootPath,
16601707
cssModulesAuto,
16611708
config.outBase,
16621709
);
1710+
// const outputConfig = composeOutputConfig(
1711+
// multiCompilerIndex,
1712+
// format,
1713+
// jsExtension,
1714+
// );
16631715
const { config: bundlelessExternalConfig } = composeBundlelessExternalConfig(
16641716
jsExtension,
16651717
redirect,
@@ -1709,10 +1761,11 @@ async function composeLibRsbuildConfig(
17091761

17101762
return mergeRsbuildConfig(
17111763
formatConfig,
1764+
// outputConfig,
17121765
shimsConfig,
17131766
syntaxConfig,
17141767
externalHelpersConfig,
1715-
autoExtensionConfig,
1768+
outputFilenameConfig,
17161769
targetConfig,
17171770
// #region Externals configs
17181771
// The order of the externals config should come in the following order:
@@ -1761,7 +1814,7 @@ export async function composeCreateRsbuildConfig(
17611814
);
17621815
}
17631816

1764-
const libConfigPromises = libConfigsArray.map(async (libConfig) => {
1817+
const libConfigPromises = libConfigsArray.map(async (libConfig, index) => {
17651818
const userConfig = mergeRsbuildConfig<LibConfig>(
17661819
sharedRsbuildConfig,
17671820
libConfig,
@@ -1771,6 +1824,7 @@ export async function composeCreateRsbuildConfig(
17711824
// configuration and Lib configuration in the settings.
17721825
const libRsbuildConfig = await composeLibRsbuildConfig(
17731826
userConfig,
1827+
libConfigsArray.length > 1 ? index : null,
17741828
root,
17751829
sharedPlugins,
17761830
);

packages/core/tests/__snapshots__/config.test.ts.snap

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
393393
output: {
394394
path: '<WORKSPACE>/dist',
395395
filename: '[name].js',
396-
chunkFilename: '[name].js',
396+
chunkFilename: '0~[name].js',
397397
publicPath: 'auto',
398398
pathinfo: false,
399399
hashFunction: 'xxhash64',
@@ -1091,7 +1091,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
10911091
output: {
10921092
path: '<WORKSPACE>/dist',
10931093
filename: '[name].cjs',
1094-
chunkFilename: '[name].cjs',
1094+
chunkFilename: '1~[name].cjs',
10951095
publicPath: 'auto',
10961096
pathinfo: false,
10971097
hashFunction: 'xxhash64',
@@ -1775,7 +1775,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
17751775
output: {
17761776
path: '<WORKSPACE>/dist',
17771777
filename: '[name].js',
1778-
chunkFilename: '[name].js',
1778+
chunkFilename: '2~[name].js',
17791779
publicPath: '/',
17801780
pathinfo: false,
17811781
hashFunction: 'xxhash64',
@@ -2375,7 +2375,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
23752375
output: {
23762376
path: '<WORKSPACE>/dist',
23772377
filename: '[name].js',
2378-
chunkFilename: '[name].js',
2378+
chunkFilename: '3~[name].js',
23792379
publicPath: '/',
23802380
pathinfo: false,
23812381
hashFunction: 'xxhash64',
@@ -3674,6 +3674,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
36743674
},
36753675
},
36763676
"output": {
3677+
"chunkFilename": "0~[name].js",
36773678
"chunkFormat": "module",
36783679
"chunkLoading": "import",
36793680
"library": {
@@ -3945,6 +3946,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
39453946
},
39463947
},
39473948
"output": {
3949+
"chunkFilename": "1~[name].cjs",
39483950
"chunkFormat": "commonjs",
39493951
"chunkLoading": "require",
39503952
"iife": false,
@@ -4182,6 +4184,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
41824184
},
41834185
"output": {
41844186
"asyncChunks": false,
4187+
"chunkFilename": "2~[name].js",
41854188
"library": {
41864189
"type": "umd",
41874190
},
@@ -4413,6 +4416,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config i
44134416
},
44144417
"output": {
44154418
"asyncChunks": false,
4419+
"chunkFilename": "3~[name].js",
44164420
"iife": true,
44174421
"library": {
44184422
"type": "modern-module",

pnpm-lock.yaml

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "minify-output-chunk-file-name-multi-test",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module"
6+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig({
7+
source: {
8+
entry: {
9+
lib1: './src/lib1.js',
10+
},
11+
},
12+
}),
13+
generateBundleEsmConfig({
14+
source: {
15+
entry: {
16+
lib2: './src/lib2.js',
17+
},
18+
},
19+
}),
20+
],
21+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
output: {
6+
filename: {
7+
js: 'static/js/[name].[contenthash:8].js',
8+
},
9+
},
10+
lib: [
11+
generateBundleEsmConfig({
12+
source: {
13+
entry: {
14+
lib1: './src/lib1.js',
15+
},
16+
},
17+
}),
18+
generateBundleEsmConfig({
19+
source: {
20+
entry: {
21+
lib2: './src/lib2.js',
22+
},
23+
},
24+
}),
25+
],
26+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { defineConfig } from '@rslib/core';
2+
import { generateBundleEsmConfig } from 'test-helper';
3+
4+
export default defineConfig({
5+
lib: [
6+
generateBundleEsmConfig({
7+
source: {
8+
entry: {
9+
lib1: './src/lib1.js',
10+
},
11+
},
12+
output: {
13+
filename: {
14+
js: 'static1/js/[name].js',
15+
},
16+
},
17+
}),
18+
generateBundleEsmConfig({
19+
source: {
20+
entry: {
21+
lib2: './src/lib2.js',
22+
},
23+
},
24+
output: {
25+
filename: {
26+
js: 'static2/js/[name].[contenthash:8].js',
27+
},
28+
},
29+
}),
30+
],
31+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export default async function main() {
2+
const { foo } = await import('./shared.js');
3+
return foo;
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export default async function main() {
2+
const { bar } = await import('./shared.js');
3+
return bar;
4+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const foo = 'foo';
2+
export const bar = 'bar';

0 commit comments

Comments
 (0)