Skip to content

plugin-vite 8.0.1: hotRestart never restarts the app during electron-forge start #4446

Open

Description

@proph37

Pre-flight checklist

  • I have read the contribution documentation for this project.
  • I agree to follow the code of conduct that this project uses.
  • I have searched the issue tracker for a bug that matches the one I want to file, without success.

Forge version

8.0.1

Electron version

v44.5.1

Operating system

macOS 26.6.2 (arm64)

Last known working Forge version

No response

Expected behavior

With hotRestart: true in the Vite plugin config, a change to the main process entry during electron-forge start rebuilds the bundle and restarts the running app.

Actual behavior

The main bundle is rebuilt ([@electron-forge/plugin-vite] target built src/main/index.ts), but the app is not restarted and keeps running the previous code. No "Restarting Electron app" line appears.

Steps to reproduce

  1. A Vite-template project with new VitePlugin({ hotRestart: true, build: [{ entry: 'src/main/index.ts', config: 'vite.main.config.ts', target: 'main' }, ...], renderer: [...] }).
  2. Run electron-forge start.
  3. Change src/main/index.ts. The target is rebuilt; the app keeps its process and old code.

Additional information

In dev mode, main and preload targets are built in a watch subprocess (spawnViteBuildWatch). Two things keep the restart from happening:

  1. VitePlugin.serializableConfig passes only build and renderer to the worker. Its comment says "hotRestart is moot here: workers only run when packaging", but the watch builds of start run there too. So pluginHotRestart('restart') is never added to the worker's Vite config.
  2. Even with it added, pluginHotRestart calls requestAppRestart() inside the worker, where no restart handler is registered (setAppRestartHandler runs in the parent's start()). The worker already forwards reload-renderers to the parent for preload targets; nothing similar exists for restart.

This patch fixes it for us:

--- a/dist/VitePlugin.js
+++ b/dist/VitePlugin.js
 import { readJson, writeJson } from '@electron-forge/core-utils';
+import { requestAppRestart } from '@electron-forge/core-utils/restart';
@@ spawnViteBuildWatch
             else if (msg.type === 'reload-renderers') {
                 onReloadRenderers();
             }
+            else if (msg.type === 'restart' && !requestAppRestart()) {
+                console.warn(styleText('yellow', '[@electron-forge/plugin-vite] Rebuilt the main process bundle, but the running app was not restarted, so it is still running the previous code.'));
+            }
@@ get serializableConfig()
         return {
             build: this.config.build,
             renderer: this.config.renderer,
+            hotRestart: this.config.hotRestart,
         };
--- a/dist/config/vite.base.config.js
+++ b/dist/config/vite.base.config.js
@@ pluginHotRestart, closeBundle
+            else if (command === 'restart' && isRebuild && process.send) {
+                // In the watch subprocess the restart handler lives in the parent; ask it.
+                process.send({ type: 'restart' });
+            }
             else if (command === 'restart' && !requestAppRestart() && isRebuild) {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions