diff --git a/e2e/cases/assets/filename-conflict-hint/index.test.ts b/e2e/cases/assets/filename-conflict-hint/index.test.ts new file mode 100644 index 0000000000..fc3c07d8d8 --- /dev/null +++ b/e2e/cases/assets/filename-conflict-hint/index.test.ts @@ -0,0 +1,16 @@ +import { expect, rspackTest } from '@e2e/helper'; + +rspackTest( + 'should print output.filename hints as expected', + async ({ build }) => { + const rsbuild = await build({ + catchBuildError: true, + }); + + expect(rsbuild.buildError).toBeTruthy(); + + await rsbuild.expectLog( + 'You may need to adjust output.filename configuration to prevent name conflicts.', + ); + }, +); diff --git a/e2e/cases/assets/filename-conflict-hint/rsbuild.config.ts b/e2e/cases/assets/filename-conflict-hint/rsbuild.config.ts new file mode 100644 index 0000000000..d1ea10c0c9 --- /dev/null +++ b/e2e/cases/assets/filename-conflict-hint/rsbuild.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from '@rsbuild/core'; + +export default defineConfig({ + output: { + filename: { + image: 'image.png', + }, + dataUriLimit: 0, + }, +}); diff --git a/e2e/cases/assets/filename-conflict-hint/src/index.js b/e2e/cases/assets/filename-conflict-hint/src/index.js new file mode 100644 index 0000000000..ac6a243971 --- /dev/null +++ b/e2e/cases/assets/filename-conflict-hint/src/index.js @@ -0,0 +1,4 @@ +import icon from '@e2e/assets/icon.png'; +import image from '@e2e/assets/image.png'; + +console.log(icon, image); diff --git a/packages/core/src/helpers/format.ts b/packages/core/src/helpers/format.ts index c58a5901a9..3c99abb149 100644 --- a/packages/core/src/helpers/format.ts +++ b/packages/core/src/helpers/format.ts @@ -141,6 +141,18 @@ function hintUnknownFiles(message: string): string { return message; } +const hintAssetsConflict = (message: string): string => { + const hint = 'Multiple assets emit different content to the same filename'; + + if (message.indexOf(hint) === -1) { + return message; + } + + const extraMessage = `You may need to adjust ${color.yellow('output.filename')} configuration to prevent name conflicts. (See ${color.yellow('https://rsbuild.rs/config/output/filename')})`; + + return `${message}\n${extraMessage}`; +}; + /** * Add node polyfill tip when failed to resolve node built-in modules. */ @@ -250,6 +262,7 @@ export function formatStatsError(stats: StatsError): string { message = hintUnknownFiles(message); message = hintNodePolyfill(message); + message = hintAssetsConflict(message); let lines = message.split('\n');