diff --git a/e2e/cases/filename-function/rsbuild.config.ts b/e2e/cases/filename-function/rsbuild.config.ts index 98419355a7..6aa5016a07 100644 --- a/e2e/cases/filename-function/rsbuild.config.ts +++ b/e2e/cases/filename-function/rsbuild.config.ts @@ -10,6 +10,12 @@ export default defineConfig({ return '/some-path/[name].js'; }, + css: (pathData) => { + if (pathData.chunk?.name === 'index') { + return 'my-index.css'; + } + return '/some-path/[name].css'; + }, }, }, }); diff --git a/packages/core/src/helpers/index.ts b/packages/core/src/helpers/index.ts index 28c4c0c605..27f6ff9a82 100644 --- a/packages/core/src/helpers/index.ts +++ b/packages/core/src/helpers/index.ts @@ -221,7 +221,12 @@ export function getFilename( ): NonNullable; export function getFilename( config: NormalizedConfig | NormalizedEnvironmentConfig, - type: Exclude, + type: 'css', + isProd: boolean, +): NonNullable; +export function getFilename( + config: NormalizedConfig | NormalizedEnvironmentConfig, + type: Exclude, isProd: boolean, isServer?: boolean, ): string; diff --git a/packages/core/src/plugins/output.ts b/packages/core/src/plugins/output.ts index 1c77a7f25f..bcacd69750 100644 --- a/packages/core/src/plugins/output.ts +++ b/packages/core/src/plugins/output.ts @@ -141,6 +141,8 @@ export const pluginOutput = (): RsbuildPlugin => ({ const cssPath = config.output.distPath.css; const cssFilename = getFilename(config, 'css', isProd); + const isCssFilenameFn = typeof cssFilename === 'function'; + const cssAsyncPath = config.output.distPath.cssAsync ?? (cssPath ? `${cssPath}/async` : 'async'); @@ -149,8 +151,18 @@ export const pluginOutput = (): RsbuildPlugin => ({ .plugin(CHAIN_ID.PLUGIN.MINI_CSS_EXTRACT) .use(getCssExtractPlugin(), [ { - filename: posix.join(cssPath, cssFilename), - chunkFilename: posix.join(cssAsyncPath, cssFilename), + filename: isCssFilenameFn + ? (...args) => { + const name = cssFilename(...args); + return posix.join(cssPath, name); + } + : posix.join(cssPath, cssFilename), + chunkFilename: isCssFilenameFn + ? (...args) => { + const name = cssFilename(...args); + return posix.join(cssAsyncPath, name); + } + : posix.join(cssAsyncPath, cssFilename), ...extractPluginOptions, }, ]); diff --git a/packages/core/src/types/config.ts b/packages/core/src/types/config.ts index c2d47a7bc8..f16aabaf83 100644 --- a/packages/core/src/types/config.ts +++ b/packages/core/src/types/config.ts @@ -673,7 +673,7 @@ export type FilenameConfig = { * - dev: '[name].css' * - prod: '[name].[contenthash:8].css' */ - css?: string; + css?: NonNullable['cssFilename']; /** * The name of the SVG images. * @default '[name].[contenthash:8].svg' diff --git a/website/docs/en/config/output/filename.mdx b/website/docs/en/config/output/filename.mdx index 02d74ac87f..dc4f012201 100644 --- a/website/docs/en/config/output/filename.mdx +++ b/website/docs/en/config/output/filename.mdx @@ -128,7 +128,7 @@ After specifying the module name as above, the generated file will be `dist/stat ## Using Function -You can pass a function to `output.filename.js`, allowing you to dynamically generate filenames based on file information: +You can pass a function to `output.filename.js` or `output.filename.css`, allowing you to dynamically generate filenames based on file information: ```js export default { @@ -144,6 +144,14 @@ export default { return '/some-path/[name].js'; }, + css: (pathData, assetInfo) => { + if (pathData.chunk?.name === 'index') { + const isProd = process.env.NODE_ENV === 'production'; + return isProd ? '[name].[contenthash:8].css' : '[name].css'; + } + + return '/some-path/[name].css'; + }, }, }, }; diff --git a/website/docs/zh/config/output/filename.mdx b/website/docs/zh/config/output/filename.mdx index 07a860bc73..d0d99f18fa 100644 --- a/website/docs/zh/config/output/filename.mdx +++ b/website/docs/zh/config/output/filename.mdx @@ -8,7 +8,9 @@ type FilenameConfig = { js?: | string | ((pathData: Rspack.PathData, assetInfo: Rspack.JsAssetInfo) => string); - css?: string; + css?: + | string + | ((pathData: Rspack.PathData, assetInfo: Rspack.JsAssetInfo) => string); svg?: string; font?: string; image?: string; @@ -127,7 +129,7 @@ const { add } = await import( ## 使用函数 -`output.filename.js` 可以传入一个函数,这允许你根据文件信息动态生成文件名: +`output.filename.js` 和 `output.filename.css` 可以传入一个函数,这允许你根据文件信息动态生成文件名: ```js export default { @@ -143,6 +145,14 @@ export default { return '/some-path/[name].js'; }, + css: (pathData, assetInfo) => { + if (pathData.chunk?.name === 'index') { + const isProd = process.env.NODE_ENV === 'production'; + return isProd ? '[name].[contenthash:8].css' : '[name].css'; + } + + return '/some-path/[name].css'; + }, }, }, };