From 13e02f6faddcbcce29fe45800554572660b12245 Mon Sep 17 00:00:00 2001 From: George Xu Date: Thu, 14 Sep 2023 16:21:42 -0700 Subject: [PATCH 1/5] add plugin --- packages/plugin/webpack/src/Config.ts | 4 +++ packages/plugin/webpack/src/WebpackConfig.ts | 6 +++- packages/plugin/webpack/src/WebpackPlugin.ts | 34 ++++++++++++++++--- .../src/util/EntryPointPreloadPlugin.ts | 10 ++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 packages/plugin/webpack/src/util/EntryPointPreloadPlugin.ts 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/WebpackConfig.ts b/packages/plugin/webpack/src/WebpackConfig.ts index ee409ce74e..143f9d6011 100644 --- a/packages/plugin/webpack/src/WebpackConfig.ts +++ b/packages/plugin/webpack/src/WebpackConfig.ts @@ -7,6 +7,7 @@ import { merge as webpackMerge } from 'webpack-merge'; import { WebpackPluginConfig, WebpackPluginEntryPoint, WebpackPluginEntryPointLocalWindow, WebpackPluginEntryPointPreloadOnly } from './Config'; import AssetRelocatorPatch from './util/AssetRelocatorPatch'; +import EntryPointPreloadPlugin from './util/EntryPointPreloadPlugin'; import processConfig from './util/processConfig'; import { isLocalOrNoWindowEntries, isLocalWindow, isNoWindow, isPreloadOnly, isPreloadOnlyEntries } from './util/rendererTypeUtils'; @@ -304,7 +305,10 @@ export default class WebpackConfigGenerator { globalObject: 'self', ...(this.isProd ? {} : { publicPath: '/' }), }, - plugins: target === RendererTarget.ElectronPreload ? [] : [new webpack.ExternalsPlugin('commonjs2', externals)], + plugins: [ + new EntryPointPreloadPlugin({ name: `entry-point-preload-${target}` }), + ...(target !== RendererTarget.ElectronPreload ? [] : [new webpack.ExternalsPlugin('commonjs2', externals)]), + ], }; return webpackMerge(baseConfig, rendererConfig || {}, config); } diff --git a/packages/plugin/webpack/src/WebpackPlugin.ts b/packages/plugin/webpack/src/WebpackPlugin.ts index f07d454442..40c11648b7 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[] = []; + 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')) { + const name = `entry-point-preload-${entryConfig.target}`; + 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 = []; + for (const preloadPlugin of preloadPlugins) { + promises.push( + new Promise((resolve, reject) => { + compiler.hooks.done.tap(preloadPlugin, (stats) => { + if (stats.hasErrors()) { + // TODO(georgexu99): add a way to identify preload entries with the same target name ex) preload config entries + return reject(new Error(`Compilation errors in the preload: ${stats.toString()}`)); + } + return resolve(undefined); + }); + }) + ); + } const webpackDevServer = new WebpackDevServer(this.devServerOptions(), compiler); await webpackDevServer.start(); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 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 + } +} From 670e4cc40fa3d89e7230220f33aea04322effe02 Mon Sep 17 00:00:00 2001 From: George Xu Date: Thu, 14 Sep 2023 16:36:27 -0700 Subject: [PATCH 2/5] add unique identifier to entries with their own preload config --- packages/plugin/webpack/src/WebpackPlugin.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/plugin/webpack/src/WebpackPlugin.ts b/packages/plugin/webpack/src/WebpackPlugin.ts index 40c11648b7..254e78fe40 100644 --- a/packages/plugin/webpack/src/WebpackPlugin.ts +++ b/packages/plugin/webpack/src/WebpackPlugin.ts @@ -290,13 +290,17 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); } const preloadPlugins: string[] = []; + let preloadEntriesWithConfig = 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')) { - const name = `entry-point-preload-${entryConfig.target}`; + let name = `entry-point-preload-${entryConfig.target}`; + if (preloadPlugins.includes(name)) { + name = `${name}-${++preloadEntriesWithConfig}`; + } entryConfig.plugins.push(new EntryPointPreloadPlugin({ name })); preloadPlugins.push(name); } From 3fc0dd23df59a04178547343d1ef71895fed5b7e Mon Sep 17 00:00:00 2001 From: George Xu Date: Thu, 14 Sep 2023 17:41:46 -0700 Subject: [PATCH 3/5] clean up --- packages/plugin/webpack/src/WebpackConfig.ts | 6 +---- packages/plugin/webpack/src/WebpackPlugin.ts | 27 +++++++++----------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/packages/plugin/webpack/src/WebpackConfig.ts b/packages/plugin/webpack/src/WebpackConfig.ts index 143f9d6011..ee409ce74e 100644 --- a/packages/plugin/webpack/src/WebpackConfig.ts +++ b/packages/plugin/webpack/src/WebpackConfig.ts @@ -7,7 +7,6 @@ import { merge as webpackMerge } from 'webpack-merge'; import { WebpackPluginConfig, WebpackPluginEntryPoint, WebpackPluginEntryPointLocalWindow, WebpackPluginEntryPointPreloadOnly } from './Config'; import AssetRelocatorPatch from './util/AssetRelocatorPatch'; -import EntryPointPreloadPlugin from './util/EntryPointPreloadPlugin'; import processConfig from './util/processConfig'; import { isLocalOrNoWindowEntries, isLocalWindow, isNoWindow, isPreloadOnly, isPreloadOnlyEntries } from './util/rendererTypeUtils'; @@ -305,10 +304,7 @@ export default class WebpackConfigGenerator { globalObject: 'self', ...(this.isProd ? {} : { publicPath: '/' }), }, - plugins: [ - new EntryPointPreloadPlugin({ name: `entry-point-preload-${target}` }), - ...(target !== RendererTarget.ElectronPreload ? [] : [new webpack.ExternalsPlugin('commonjs2', externals)]), - ], + plugins: target === RendererTarget.ElectronPreload ? [] : [new webpack.ExternalsPlugin('commonjs2', externals)], }; return webpackMerge(baseConfig, rendererConfig || {}, config); } diff --git a/packages/plugin/webpack/src/WebpackPlugin.ts b/packages/plugin/webpack/src/WebpackPlugin.ts index 254e78fe40..1af2906f34 100644 --- a/packages/plugin/webpack/src/WebpackPlugin.ts +++ b/packages/plugin/webpack/src/WebpackPlugin.ts @@ -296,7 +296,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); entryConfig.plugins.push(new ElectronForgeLoggingPlugin(logger.createTab(`Renderer Target Bundle (${entryConfig.target})`))); const filename = entryConfig.output?.filename as string; - if (filename.endsWith('preload.js')) { + if (filename?.endsWith('preload.js')) { let name = `entry-point-preload-${entryConfig.target}`; if (preloadPlugins.includes(name)) { name = `${name}-${++preloadEntriesWithConfig}`; @@ -313,20 +313,17 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); const compiler = webpack(configs); - const promises = []; - for (const preloadPlugin of preloadPlugins) { - promises.push( - new Promise((resolve, reject) => { - compiler.hooks.done.tap(preloadPlugin, (stats) => { - if (stats.hasErrors()) { - // TODO(georgexu99): add a way to identify preload entries with the same target name ex) preload config entries - return reject(new Error(`Compilation errors in the preload: ${stats.toString()}`)); - } - return resolve(undefined); - }); - }) - ); - } + 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(); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion From 85d54a0365a6adc7f19b13a43df9e9be7c9812d3 Mon Sep 17 00:00:00 2001 From: George Xu Date: Tue, 19 Sep 2023 13:11:38 -0700 Subject: [PATCH 4/5] why did i add this --- packages/plugin/webpack/src/WebpackPlugin.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/plugin/webpack/src/WebpackPlugin.ts b/packages/plugin/webpack/src/WebpackPlugin.ts index 1af2906f34..fe5d1bc467 100644 --- a/packages/plugin/webpack/src/WebpackPlugin.ts +++ b/packages/plugin/webpack/src/WebpackPlugin.ts @@ -326,7 +326,6 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); const webpackDevServer = new WebpackDevServer(this.devServerOptions(), compiler); await webpackDevServer.start(); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.servers.push(webpackDevServer.server!); await Promise.all(promises); }; From 9288cc90d872c0d64d6ec1f100e72e8ebcb6a129 Mon Sep 17 00:00:00 2001 From: George Xu Date: Tue, 19 Sep 2023 13:12:40 -0700 Subject: [PATCH 5/5] rename var --- packages/plugin/webpack/src/WebpackPlugin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin/webpack/src/WebpackPlugin.ts b/packages/plugin/webpack/src/WebpackPlugin.ts index fe5d1bc467..af307404c5 100644 --- a/packages/plugin/webpack/src/WebpackPlugin.ts +++ b/packages/plugin/webpack/src/WebpackPlugin.ts @@ -290,7 +290,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); } const preloadPlugins: string[] = []; - let preloadEntriesWithConfig = 0; + 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})`))); @@ -299,7 +299,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}`); if (filename?.endsWith('preload.js')) { let name = `entry-point-preload-${entryConfig.target}`; if (preloadPlugins.includes(name)) { - name = `${name}-${++preloadEntriesWithConfig}`; + name = `${name}-${++numPreloadEntriesWithConfig}`; } entryConfig.plugins.push(new EntryPointPreloadPlugin({ name })); preloadPlugins.push(name);