diff --git a/src/build.ts b/src/build.ts index ec24d10..cff9ce6 100644 --- a/src/build.ts +++ b/src/build.ts @@ -1,5 +1,5 @@ import { build as viteBuild } from 'vite' -import { type InlineConfig, resolveConfig } from './config' +import { type InlineConfig, resolveConfig, type InlineUserConfig } from './config' /** * Bundles the electron app for production. @@ -10,24 +10,26 @@ export async function build(inlineConfig: InlineConfig = {}): Promise { if (config.config) { const mainViteConfig = config.config?.main if (mainViteConfig) { - if (mainViteConfig.build?.watch) { - mainViteConfig.build.watch = null - } - await viteBuild(mainViteConfig) + await _build(mainViteConfig) } const preloadViteConfig = config.config?.preload if (preloadViteConfig) { - if (preloadViteConfig.build?.watch) { - preloadViteConfig.build.watch = null + if (Array.isArray(preloadViteConfig)) { + await Promise.all(preloadViteConfig.map(_build)) + } else { + await _build(preloadViteConfig) } - await viteBuild(preloadViteConfig) } const rendererViteConfig = config.config?.renderer if (rendererViteConfig) { - if (rendererViteConfig.build?.watch) { - rendererViteConfig.build.watch = null - } - await viteBuild(rendererViteConfig) + _build(rendererViteConfig) } } } + +async function _build(config: InlineUserConfig): Promise { + if (config.build?.watch) { + config.build.watch = null + } + await viteBuild(config) +} diff --git a/src/config.ts b/src/config.ts index 69d836a..b63bb70 100644 --- a/src/config.ts +++ b/src/config.ts @@ -25,25 +25,27 @@ import { isObject, isFilePathESM } from './utils' export { defineConfig as defineViteConfig } from 'vite' +export type InlineUserConfig = ViteConfig & { configFile?: string | false } + export interface UserConfig { /** * Vite config options for electron main process * * https://vitejs.dev/config/ */ - main?: ViteConfig & { configFile?: string | false } + main?: InlineUserConfig /** * Vite config options for electron renderer process * * https://vitejs.dev/config/ */ - renderer?: ViteConfig & { configFile?: string | false } + renderer?: InlineUserConfig /** * Vite config options for electron preload files * * https://vitejs.dev/config/ */ - preload?: ViteConfig & { configFile?: string | false } + preload?: InlineUserConfig | InlineUserConfig[] } export interface ElectronViteConfig { @@ -64,7 +66,7 @@ export interface ElectronViteConfig { * * https://vitejs.dev/config/ */ - preload?: ViteConfigExport + preload?: ViteConfigExport | ViteConfigExport[] } export type InlineConfig = Omit & { @@ -160,22 +162,48 @@ export async function resolveConfig( } if (loadResult.config.preload) { - const preloadViteConfig: ViteConfig = mergeConfig(loadResult.config.preload, deepClone(config)) - - preloadViteConfig.mode = inlineConfig.mode || preloadViteConfig.mode || defaultMode - - if (outDir) { - resetOutDir(preloadViteConfig, outDir, 'preload') + if (Array.isArray(loadResult.config.preload)) { + const shouldNotEmptyOutDir = loadResult.config.preload.length > 1 ? true : undefined + loadResult.config.preload = loadResult.config.preload.map(config => + normalizePreloadViteConfig(config, shouldNotEmptyOutDir) + ) + } else { + loadResult.config.preload = normalizePreloadViteConfig(loadResult.config.preload) } - mergePlugins(preloadViteConfig, [ - ...electronPreloadVitePlugin({ root }), - assetPlugin(), - importMetaPlugin(), - esmShimPlugin() - ]) - loadResult.config.preload = preloadViteConfig - loadResult.config.preload.configFile = false + function normalizePreloadViteConfig( + preloadConfig: InlineUserConfig, + shouldNotEmptyOutDir?: boolean + ): InlineUserConfig { + const preloadViteConfig: InlineUserConfig = mergeConfig(preloadConfig, deepClone(config)) + + preloadViteConfig.mode = inlineConfig.mode || preloadViteConfig.mode || defaultMode + preloadViteConfig.configFile = false + + if (shouldNotEmptyOutDir) { + preloadViteConfig.build ||= {} + + if (preloadViteConfig.build.emptyOutDir === true) { + throw new Error( + "The electron vite preload config `build.emptyOutDir` should be set to `false` when multiple preload scripts are used to prevent overwriting each other's output files." + ) + } + + preloadViteConfig.build.emptyOutDir = false + } + + if (outDir) { + resetOutDir(preloadViteConfig, outDir, 'preload') + } + mergePlugins(preloadViteConfig, [ + ...electronPreloadVitePlugin({ root }), + assetPlugin(), + importMetaPlugin(), + esmShimPlugin() + ]) + + return preloadViteConfig + } } if (loadResult.config.renderer) { @@ -299,8 +327,8 @@ export async function loadConfigFromFile( if (config.preload) { const preloadViteConfig = config.preload preloadConfig = await (typeof preloadViteConfig === 'function' ? preloadViteConfig(configEnv) : preloadViteConfig) - if (!isObject(preloadConfig)) { - throw new Error(`preload config must export or return an object`) + if (!isObject(preloadConfig) && (!Array.isArray(preloadConfig) || !preloadConfig.every(isObject))) { + throw new Error(`preload config must export or return an object or an array of objects`) } } else { configRequired.push('preload') diff --git a/src/server.ts b/src/server.ts index 5a72de7..3c236dd 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,6 +1,5 @@ import type { ChildProcess } from 'node:child_process' import { - type UserConfig as ViteConfig, type ViteDevServer, createServer as viteCreateServer, build as viteBuild, @@ -8,7 +7,7 @@ import { mergeConfig } from 'vite' import colors from 'picocolors' -import { type InlineConfig, resolveConfig } from './config' +import { type InlineConfig, resolveConfig, type InlineUserConfig } from './config' import { resolveHostname } from './utils' import { startElectron } from './electron' @@ -53,7 +52,14 @@ export async function createServer( if (preloadViteConfig && !options.rendererOnly) { logger.info(colors.gray(`\n-----\n`)) + let resolvedCount = 0 const watchHook = (): void => { + resolvedCount++ + if (Array.isArray(preloadViteConfig) && resolvedCount < preloadViteConfig.length) { + // Only resolve when all preload scripts are built + return + } + logger.info(colors.green(`\nrebuild the electron preload files successfully`)) if (server) { @@ -63,7 +69,11 @@ export async function createServer( } } - await doBuild(preloadViteConfig, watchHook, errorHook) + if (Array.isArray(preloadViteConfig)) { + await Promise.all(preloadViteConfig.map(config => doBuild(config, watchHook, errorHook))) + } else { + await doBuild(preloadViteConfig, watchHook, errorHook) + } logger.info(colors.green(`\nbuild the electron preload files successfully`)) } @@ -110,9 +120,7 @@ export async function createServer( } } -type UserConfig = ViteConfig & { configFile?: string | false } - -async function doBuild(config: UserConfig, watchHook: () => void, errorHook: (e: Error) => void): Promise { +async function doBuild(config: InlineUserConfig, watchHook: () => void, errorHook: (e: Error) => void): Promise { return new Promise(resolve => { if (config.build?.watch) { let firstBundle = true