import mergeWith from 'lodash.mergewith'; import { isFunction } from '@modern-js/utils'; import { UserConfig, SourceConfig, ToolsConfig } from '.'; export interface NormalizedSourceConfig extends Omit { alias: SourceConfig['alias'] | Array; moduleScopes: | SourceConfig['moduleScopes'] | Array; } export interface NormalizedToolsConfig extends Omit< ToolsConfig, | 'webpack' | 'babel' | 'postcss' | 'autoprefixer' | 'lodash' | 'tsLoader' | 'terser' | 'minifyCss' | 'esbuild' > { webpack: ToolsConfig['webpack'] | Array>; babel: ToolsConfig['babel'] | Array>; postcss: ToolsConfig['postcss'] | Array>; autoprefixer: | ToolsConfig['autoprefixer'] | Array>; lodash: ToolsConfig['lodash'] | Array; tsLoader: | ToolsConfig['tsLoader'] | Array>; terser: ToolsConfig['terser'] | Array>; minifyCss: | ToolsConfig['minifyCss'] | Array>; esbuild: ToolsConfig['esbuild'] | Array>; } export interface NormalizedConfig extends Omit, 'source' | 'tools'> { source: NormalizedSourceConfig; tools: NormalizedToolsConfig; _raw: UserConfig; } /** * merge configuration from modern.config.js and plugins. * * @param configs - Configuration from modern.config.ts or plugin's config hook. * @returns - normalized user config. */ export const mergeConfig = ( configs: Array, ): NormalizedConfig => mergeWith({}, ...configs, (target: any, source: any) => { if (Array.isArray(target) && Array.isArray(source)) { return [...target, ...source]; } if (isFunction(source)) { return Array.isArray(target) ? [...target, source] : [target, source].filter(Boolean); } return undefined; });