diff --git a/packages/plugin/webpack/src/Config.ts b/packages/plugin/webpack/src/Config.ts index 4cf1d4a3d8..0d886f5e94 100644 --- a/packages/plugin/webpack/src/Config.ts +++ b/packages/plugin/webpack/src/Config.ts @@ -121,6 +121,10 @@ export interface WebpackPluginRendererConfig { entryPoints: WebpackPluginEntryPoint[]; } +export interface EntryPointPluginConfig { + name: string; +} + export interface WebpackPluginConfig { /** * The webpack config for your main process diff --git a/packages/plugin/webpack/src/WebpackPlugin.ts b/packages/plugin/webpack/src/WebpackPlugin.ts index f07d454442..af307404c5 100644 --- a/packages/plugin/webpack/src/WebpackPlugin.ts +++ b/packages/plugin/webpack/src/WebpackPlugin.ts @@ -14,6 +14,7 @@ import { merge } from 'webpack-merge'; import { WebpackPluginConfig } from './Config'; import ElectronForgeLoggingPlugin from './util/ElectronForgeLogging'; +import EntryPointPreloadPlugin from './util/EntryPointPreloadPlugin'; import once from './util/once'; import WebpackConfigGenerator from './WebpackConfig'; @@ -283,25 +284,50 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); }; launchRendererDevServers = async (logger: Logger): Promise => { - const config = await this.configGenerator.getRendererConfig(this.config.renderer.entryPoints); - if (config.length === 0) { + const configs = await this.configGenerator.getRendererConfig(this.config.renderer.entryPoints); + if (configs.length === 0) { return; } - for (const entryConfig of config) { + const preloadPlugins: string[] = []; + let numPreloadEntriesWithConfig = 0; + for (const entryConfig of configs) { if (!entryConfig.plugins) entryConfig.plugins = []; entryConfig.plugins.push(new ElectronForgeLoggingPlugin(logger.createTab(`Renderer Target Bundle (${entryConfig.target})`))); + const filename = entryConfig.output?.filename as string; + if (filename?.endsWith('preload.js')) { + let name = `entry-point-preload-${entryConfig.target}`; + if (preloadPlugins.includes(name)) { + name = `${name}-${++numPreloadEntriesWithConfig}`; + } + entryConfig.plugins.push(new EntryPointPreloadPlugin({ name })); + preloadPlugins.push(name); + } + entryConfig.infrastructureLogging = { level: 'none', }; entryConfig.stats = 'none'; } - const compiler = webpack(config); + const compiler = webpack(configs); + + const promises = preloadPlugins.map((preloadPlugin) => { + return new Promise((resolve, reject) => { + compiler.hooks.done.tap(preloadPlugin, (stats) => { + if (stats.hasErrors()) { + return reject(new Error(`Compilation errors in the preload: ${stats.toString()}`)); + } + return resolve(undefined); + }); + }); + }); + const webpackDevServer = new WebpackDevServer(this.devServerOptions(), compiler); await webpackDevServer.start(); this.servers.push(webpackDevServer.server!); + await Promise.all(promises); }; devServerOptions(): WebpackDevServer.Configuration { diff --git a/packages/plugin/webpack/src/util/EntryPointPreloadPlugin.ts b/packages/plugin/webpack/src/util/EntryPointPreloadPlugin.ts new file mode 100644 index 0000000000..816c1f905c --- /dev/null +++ b/packages/plugin/webpack/src/util/EntryPointPreloadPlugin.ts @@ -0,0 +1,10 @@ +import { PluginBase } from '@electron-forge/plugin-base'; + +import { EntryPointPluginConfig } from '../Config'; + +export default class EntryPointPreloadPlugin extends PluginBase { + name = this.config.name; + apply() { + // noop + } +}