diff --git a/src/config.ts b/src/config.ts index 87994bc..559b05b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -164,7 +164,8 @@ export async function resolveConfig( process.env.NODE_ENV = defaultMode - let userConfig: UserConfig | undefined + const userConfig: UserConfig | undefined = {} + let configFileDependencies: string[] = [] let { configFile } = config @@ -191,123 +192,20 @@ export async function resolveConfig( const outDir = config.build?.outDir - if (loadResult.config.main) { - const mainViteConfig: MainViteConfig = mergeConfig(loadResult.config.main, deepClone(config)) + const { main, preload, renderer } = loadResult.config - mainViteConfig.mode = inlineConfig.mode || mainViteConfig.mode || defaultMode - - if (outDir) { - resetOutDir(mainViteConfig, outDir, 'main') - } - - const configDrivenPlugins: PluginOption[] = await resolveConfigDrivenPlugins(mainViteConfig) - - const builtInMainPlugins: PluginOption[] = [ - electronMainConfigPresetPlugin({ root }), - electronMainConfigValidatorPlugin(), - assetPlugin(), - workerPlugin(), - modulePathPlugin( - mergeConfig( - { - plugins: [ - electronMainConfigPresetPlugin({ root }), - assetPlugin(), - importMetaPlugin(), - esmShimPlugin(), - ...configDrivenPlugins - ] - }, - mainViteConfig - ) - ), - importMetaPlugin(), - esmShimPlugin(), - ...configDrivenPlugins - ] - - mainViteConfig.plugins = builtInMainPlugins.concat(mainViteConfig.plugins || []) - - loadResult.config.main = mainViteConfig + if (main) { + userConfig.main = await new MainConfigFactory(main, config, { outDir, root }).build() } - if (loadResult.config.preload) { - const preloadViteConfig: PreloadViteConfig = mergeConfig(loadResult.config.preload, deepClone(config)) - - preloadViteConfig.mode = inlineConfig.mode || preloadViteConfig.mode || defaultMode - - if (outDir) { - resetOutDir(preloadViteConfig, outDir, 'preload') - } - - const configDrivenPlugins: PluginOption[] = await resolveConfigDrivenPlugins(preloadViteConfig) - - const builtInPreloadPlugins: PluginOption[] = [ - electronPreloadConfigPresetPlugin({ root }), - electronPreloadConfigValidatorPlugin(), - assetPlugin(), - importMetaPlugin(), - esmShimPlugin(), - ...configDrivenPlugins - ] - - if (preloadViteConfig.build?.isolatedEntries) { - builtInPreloadPlugins.push( - isolateEntriesPlugin( - mergeConfig( - { - plugins: [ - electronPreloadConfigPresetPlugin({ root }), - assetPlugin(), - importMetaPlugin(), - esmShimPlugin(), - ...configDrivenPlugins - ] - }, - preloadViteConfig - ) - ) - ) - } - - preloadViteConfig.plugins = builtInPreloadPlugins.concat(preloadViteConfig.plugins) - - loadResult.config.preload = preloadViteConfig + if (preload) { + userConfig.preload = await new PreloadConfigFactory(preload, config, { outDir, root }).build() } - if (loadResult.config.renderer) { - const rendererViteConfig: RendererViteConfig = mergeConfig(loadResult.config.renderer, deepClone(config)) - - rendererViteConfig.mode = inlineConfig.mode || rendererViteConfig.mode || defaultMode - - if (outDir) { - resetOutDir(rendererViteConfig, outDir, 'renderer') - } - - const builtInRendererPlugins: PluginOption[] = [ - electronRendererConfigPresetPlugin({ root }), - electronRendererConfigValidatorPlugin() - ] - - if (rendererViteConfig.build?.isolatedEntries) { - builtInRendererPlugins.push( - isolateEntriesPlugin( - mergeConfig( - { - plugins: [electronRendererConfigPresetPlugin({ root })] - }, - rendererViteConfig - ) - ) - ) - } - - rendererViteConfig.plugins = builtInRendererPlugins.concat(rendererViteConfig.plugins || []) - - loadResult.config.renderer = rendererViteConfig + if (renderer) { + userConfig.renderer = await new RendererConfigFactory(renderer, config, { outDir, root }).build() } - userConfig = loadResult.config configFile = loadResult.path configFileDependencies = loadResult.dependencies } @@ -322,6 +220,108 @@ export async function resolveConfig( return resolved } +export abstract class ConfigFactory { + constructor( + protected readonly baseConfig: T, + protected readonly inlineConfig: InlineConfig, + protected readonly options: { outDir?: string; root?: string } + ) {} + + async build(cleanMode?: boolean): Promise { + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + const config = mergeConfig(deepClone(this.baseConfig) as any, deepClone(this.inlineConfig)) as T + + config.mode = this.inlineConfig.mode || config.mode || process.env.NODE_ENV + + if (this.options.outDir) { + resetOutDir(config, this.options.outDir, this.processType()) + } + + const builtinPlugins = await this.resolveBuiltinPlugins(config, cleanMode) + + config.plugins = builtinPlugins.concat(config.plugins || []) + + return config + } + + protected abstract processType(): 'main' | 'preload' | 'renderer' + + protected abstract resolveBuiltinPlugins(config: T, cleanMode?: boolean): Promise +} + +export class MainConfigFactory extends ConfigFactory { + protected processType(): 'main' { + return 'main' + } + + protected async resolveBuiltinPlugins(config: MainViteConfig, cleanMode?: boolean): Promise { + const configDrivenPlugins: PluginOption[] = await resolveConfigDrivenPlugins(config) + + return cleanMode + ? [ + electronMainConfigPresetPlugin({ root: this.options.root }), + assetPlugin(), + importMetaPlugin(), + esmShimPlugin(), + ...configDrivenPlugins + ] + : [ + electronMainConfigPresetPlugin({ root: this.options.root }), + electronMainConfigValidatorPlugin(), + assetPlugin(), + workerPlugin(), + modulePathPlugin(this), + importMetaPlugin(), + esmShimPlugin(), + ...configDrivenPlugins + ] + } +} + +export class PreloadConfigFactory extends ConfigFactory { + protected processType(): 'preload' { + return 'preload' + } + + protected async resolveBuiltinPlugins(config: PreloadViteConfig, cleanMode?: boolean): Promise { + const configDrivenPlugins: PluginOption[] = await resolveConfigDrivenPlugins(config) + + return cleanMode + ? [ + electronPreloadConfigPresetPlugin({ root: this.options.root }), + assetPlugin(), + importMetaPlugin(), + esmShimPlugin(), + ...configDrivenPlugins + ] + : [ + electronPreloadConfigPresetPlugin({ root: this.options.root }), + electronPreloadConfigValidatorPlugin(), + assetPlugin(), + importMetaPlugin(), + esmShimPlugin(), + ...configDrivenPlugins, + ...(config.build?.isolatedEntries ? [isolateEntriesPlugin(this)] : []) + ] + } +} + +export class RendererConfigFactory extends ConfigFactory { + protected processType(): 'renderer' { + return 'renderer' + } + + protected async resolveBuiltinPlugins(config: RendererViteConfig, cleanMode?: boolean): Promise { + return cleanMode + ? [electronRendererConfigPresetPlugin({ root: this.options.root })] + : [ + electronRendererConfigPresetPlugin({ root: this.options.root }), + electronRendererConfigValidatorPlugin(), + ...(config.build?.isolatedEntries ? [isolateEntriesPlugin(this)] : []) + ] + } +} + function resetOutDir(config: ViteConfig, outDir: string, subOutDir: string): void { let userOutDir = config.build?.outDir if (outDir === userOutDir) { diff --git a/src/plugins/isolateEntries.ts b/src/plugins/isolateEntries.ts index 70535d9..5d17ec2 100644 --- a/src/plugins/isolateEntries.ts +++ b/src/plugins/isolateEntries.ts @@ -3,6 +3,7 @@ import path from 'node:path' import { type InlineConfig, type Plugin, type LogLevel, type Rolldown, build as viteBuild, mergeConfig } from 'vite' import colors from 'picocolors' import { cleanUrl } from '../utils' +import type { ConfigFactory, PreloadViteConfig, RendererViteConfig } from '../config' const VIRTUAL_ENTRY_ID = '\0virtual:isolate-entries' @@ -13,7 +14,7 @@ const LogLevels: Record = { info: 3 } -export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin { +export default function isolateEntriesPlugin(factory: ConfigFactory): Plugin { let entries: string[] | { [x: string]: string }[] let transformedCount = 0 @@ -49,6 +50,7 @@ export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin { async load(id): Promise { if (id === VIRTUAL_ENTRY_ID) { + const userConfig = await factory.build(true) const shouldLog = LogLevels[userConfig.logLevel || 'info'] >= LogLevels.info const watchFiles = new Set() diff --git a/src/plugins/modulePath.ts b/src/plugins/modulePath.ts index fffb33b..50e383b 100644 --- a/src/plugins/modulePath.ts +++ b/src/plugins/modulePath.ts @@ -2,13 +2,14 @@ import { type Plugin, type InlineConfig, type Rolldown, build as viteBuild, merg import MagicString from 'magic-string' import { cleanUrl, toRelativePath } from '../utils' import { supportImportMetaPaths } from '../electron' +import type { ConfigFactory, MainViteConfig } from '../config' const modulePathRE = /__VITE_MODULE_PATH__([\w$]+)__/g /** * Resolve `?modulePath` import and return the module bundle path. */ -export default function modulePathPlugin(config: InlineConfig): Plugin { +export default function modulePathPlugin(factory: ConfigFactory): Plugin { const isImportMetaPathSupported = supportImportMetaPaths() const assetCache = new Set() return { @@ -21,6 +22,7 @@ export default function modulePathPlugin(config: InlineConfig): Plugin { async load(id): Promise { if (id.endsWith('?modulePath')) { // id resolved by Vite resolve plugin + const config = await factory.build(true) const bundles = await bundleEntryFile(cleanUrl(id), config) const [outputChunk, ...outputChunks] = bundles.output const hash = this.emitFile({