diff --git a/packages/vite/src/node/__tests__/config.spec.ts b/packages/vite/src/node/__tests__/config.spec.ts index ea217b993b2756..443fd7013ec4f0 100644 --- a/packages/vite/src/node/__tests__/config.spec.ts +++ b/packages/vite/src/node/__tests__/config.spec.ts @@ -27,10 +27,6 @@ describe('mergeConfig', () => { const mergedConfig: UserConfigExport = { resolve: { alias: [ - { - find: 'foo', - replacement: 'foo-value' - }, { find: 'bar', replacement: 'bar-value' @@ -38,6 +34,10 @@ describe('mergeConfig', () => { { find: 'baz', replacement: 'baz-value' + }, + { + find: 'foo', + replacement: 'foo-value' } ] } @@ -46,6 +46,38 @@ describe('mergeConfig', () => { expect(mergeConfig(baseConfig, newConfig)).toEqual(mergedConfig) }) + test('keep object alias schema', () => { + const baseConfig = { + resolve: { + alias: { + bar: 'bar-value', + baz: 'baz-value' + } + } + } + + const newConfig = { + resolve: { + alias: { + bar: 'bar-value-2', + foo: 'foo-value' + } + } + } + + const mergedConfig = { + resolve: { + alias: { + bar: 'bar-value-2', + baz: 'baz-value', + foo: 'foo-value' + } + } + } + + expect(mergeConfig(baseConfig, newConfig)).toEqual(mergedConfig) + }) + test('handles arrays', () => { const baseConfig: UserConfigExport = { envPrefix: 'string1' diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index cc611ee027adcf..a69779a629b0d6 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -326,11 +326,13 @@ export async function resolveConfig( ] // resolve alias with internal client alias - const resolvedAlias = mergeAlias( - // @ts-ignore because @rollup/plugin-alias' type doesn't allow function - // replacement, but its implementation does work with function values. - clientAlias, - config.resolve?.alias || config.alias || [] + const resolvedAlias = normalizeAlias( + mergeAlias( + // @ts-ignore because @rollup/plugin-alias' type doesn't allow function + // replacement, but its implementation does work with function values. + clientAlias, + config.resolve?.alias || config.alias || [] + ) ) const resolveOptions: ResolvedConfig['resolve'] = { @@ -709,11 +711,21 @@ export function mergeConfig( return mergeConfigRecursively(defaults, overrides, isRoot ? '' : '.') } -function mergeAlias(a: AliasOptions = [], b: AliasOptions = []): Alias[] { - return [...normalizeAlias(a), ...normalizeAlias(b)] +function mergeAlias( + a?: AliasOptions, + b?: AliasOptions +): AliasOptions | undefined { + if (!a) return b + if (!b) return a + if (isObject(a) && isObject(b)) { + return { ...a, ...b } + } + // the order is flipped because the alias is resolved from top-down, + // where the later should have higher priority + return [...normalizeAlias(b), ...normalizeAlias(a)] } -function normalizeAlias(o: AliasOptions): Alias[] { +function normalizeAlias(o: AliasOptions = []): Alias[] { return Array.isArray(o) ? o.map(normalizeSingleAlias) : Object.keys(o).map((find) =>