Skip to content

feat(preload): support bundling multiple preload scripts without requiring sandbox: false #815

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions src/build.ts
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -10,24 +10,26 @@ export async function build(inlineConfig: InlineConfig = {}): Promise<void> {
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<void> {
if (config.build?.watch) {
config.build.watch = null
}
await viteBuild(config)
}
48 changes: 29 additions & 19 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -64,7 +66,7 @@ export interface ElectronViteConfig {
*
* https://vitejs.dev/config/
*/
preload?: ViteConfigExport
preload?: ViteConfigExport | ViteConfigExport[]
}

export type InlineConfig = Omit<ViteConfig, 'base'> & {
Expand Down Expand Up @@ -160,22 +162,30 @@ export async function resolveConfig(
}

if (loadResult.config.preload) {
const preloadViteConfig: ViteConfig = mergeConfig(loadResult.config.preload, deepClone(config))
if (Array.isArray(loadResult.config.preload)) {
loadResult.config.preload = loadResult.config.preload.map(normalizePreloadViteConfig)
} else {
loadResult.config.preload = normalizePreloadViteConfig(loadResult.config.preload)
}

preloadViteConfig.mode = inlineConfig.mode || preloadViteConfig.mode || defaultMode
function normalizePreloadViteConfig(preloadConfig: InlineUserConfig): InlineUserConfig {
const preloadViteConfig: InlineUserConfig = mergeConfig(preloadConfig, deepClone(config))

if (outDir) {
resetOutDir(preloadViteConfig, outDir, 'preload')
}
mergePlugins(preloadViteConfig, [
...electronPreloadVitePlugin({ root }),
assetPlugin(),
importMetaPlugin(),
esmShimPlugin()
])
preloadViteConfig.mode = inlineConfig.mode || preloadViteConfig.mode || defaultMode
preloadViteConfig.configFile = false

loadResult.config.preload = preloadViteConfig
loadResult.config.preload.configFile = false
if (outDir) {
resetOutDir(preloadViteConfig, outDir, 'preload')
}
mergePlugins(preloadViteConfig, [
...electronPreloadVitePlugin({ root }),
assetPlugin(),
importMetaPlugin(),
esmShimPlugin()
])

return preloadViteConfig
}
}

if (loadResult.config.renderer) {
Expand Down Expand Up @@ -299,8 +309,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')
Expand Down
20 changes: 14 additions & 6 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import type { ChildProcess } from 'node:child_process'
import {
type UserConfig as ViteConfig,
type ViteDevServer,
createServer as viteCreateServer,
build as viteBuild,
createLogger,
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'

Expand Down Expand Up @@ -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) {
Expand All @@ -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`))
}
Expand Down Expand Up @@ -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<void> {
async function doBuild(config: InlineUserConfig, watchHook: () => void, errorHook: (e: Error) => void): Promise<void> {
return new Promise(resolve => {
if (config.build?.watch) {
let firstBundle = true
Expand Down