diff --git a/packages/rstack/src/rsbuildConfig.ts b/packages/rstack/src/rsbuildConfig.ts index 466d470..a6ef3cc 100644 --- a/packages/rstack/src/rsbuildConfig.ts +++ b/packages/rstack/src/rsbuildConfig.ts @@ -1,21 +1,26 @@ -import type { ConfigParams, RsbuildConfigDefinition } from '@rsbuild/core'; +import { + type ConfigParams, + type RsbuildConfig, + type RsbuildConfigDefinition, + mergeRsbuildConfig, +} from '@rsbuild/core'; import { withConfigMeta } from '@rstackjs/load-config'; import { loadRstackConfig, type Configs } from './config.ts'; +import { resolveConfigLayers } from './configLayers.ts'; -const resolveRsbuildConfig = async (configs: Configs, params: ConfigParams) => { - const appConfig = configs.app; - if (!appConfig) { - return {}; - } - if (typeof appConfig === 'function') { - return appConfig(params); - } - return appConfig; +export const resolveRsbuildConfig = async ( + layers: readonly Configs[], + params: ConfigParams, +): Promise => { + const configs = await resolveConfigLayers(layers, 'app', params); + return configs.length > 1 + ? mergeRsbuildConfig(...configs) + : (configs[0] ?? {}); }; const loadRsbuildConfig: RsbuildConfigDefinition = async (params) => { const { configs, filePath, dependencies } = await loadRstackConfig(); - const config = await resolveRsbuildConfig(configs, params); + const config = await resolveRsbuildConfig([configs], params); return withConfigMeta(config, { filePath, dependencies }); }; diff --git a/packages/rstack/tests/config/app-merge.test.ts b/packages/rstack/tests/config/app-merge.test.ts new file mode 100644 index 0000000..2f1292c --- /dev/null +++ b/packages/rstack/tests/config/app-merge.test.ts @@ -0,0 +1,31 @@ +import { expect, test } from 'rstack/test'; +import { resolveRsbuildConfig } from '../../src/rsbuildConfig.ts'; + +test('merges app layers using native Rsbuild rules', async () => { + const config = await resolveRsbuildConfig( + [ + { + app: { + source: { + define: { SHARED: true, ENV: 'base' }, + preEntry: ['./base.ts'], + }, + }, + }, + { + app: { + source: { + define: { ENV: 'production' }, + preEntry: ['./project.ts'], + }, + }, + }, + ], + { command: 'build', env: 'production' }, + ); + + expect(config.source).toEqual({ + define: { SHARED: true, ENV: 'production' }, + preEntry: ['./base.ts', './project.ts'], + }); +});