import { builtinModules } from 'node:module' import type { AddressInfo } from 'node:net' import type { ConfigEnv, Plugin, UserConfig } from 'vite' import pkg from './package.json' export const builtins = [ 'electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat(), ] export const external = [ ...builtins, ...Object.keys( 'dependencies' in pkg ? (pkg.dependencies as Record) : {} ), ] export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig { const { root, mode, command } = env return { root, mode, build: { // Prevent multiple builds from interfering with each other. emptyOutDir: false, // 🚧 Multiple builds may conflict. outDir: '.vite/build', watch: command === 'serve' ? {} : null, minify: command === 'build', }, clearScreen: false, } } export function getDefineKeys(names: string[]) { const define: { [name: string]: VitePluginRuntimeKeys } = {} return names.reduce((acc, name) => { const NAME = name.toUpperCase() const keys: VitePluginRuntimeKeys = { VITE_DEV_SERVER_URL: `${NAME}_VITE_DEV_SERVER_URL`, VITE_NAME: `${NAME}_VITE_NAME`, } return { ...acc, [name]: keys } }, define) } export function getBuildDefine(env: ConfigEnv<'build'>) { const { command, forgeConfig } = env const renderer = (forgeConfig && forgeConfig.renderer) ?? [ { name: 'main_window', config: 'vite.renderer.config.ts', }, ] const names = renderer .filter(({ name }) => name != null) .map(({ name }) => name!) const defineKeys = getDefineKeys(names) const define = Object.entries(defineKeys).reduce( (acc, [name, keys]) => { const { VITE_DEV_SERVER_URL, VITE_NAME } = keys const def = { [VITE_DEV_SERVER_URL]: command === 'serve' ? JSON.stringify(process.env[VITE_DEV_SERVER_URL]) : undefined, [VITE_NAME]: JSON.stringify(name), } return { ...acc, ...def } }, {} as Record ) return define } export function pluginExposeRenderer(name: string): Plugin { const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name] return { name: '@electron-forge/plugin-vite:expose-renderer', configureServer(server) { process.viteDevServers ??= {} // Expose server for preload scripts hot reload. process.viteDevServers[name] = server server.httpServer?.once('listening', () => { const addressInfo = server.httpServer!.address() as AddressInfo // Expose env constant for main process use. process.env[VITE_DEV_SERVER_URL] = `http://localhost:${addressInfo?.port}` }) }, } } export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { return { name: '@electron-forge/plugin-vite:hot-restart', closeBundle() { if (command === 'reload') { for (const server of Object.values(process.viteDevServers)) { // Preload scripts hot reload. server.ws.send({ type: 'full-reload' }) } } else { // Main process hot restart. // https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223 process.stdin.emit('data', 'rs') } }, } }