Skip to content

plugin-vite does not declare vite as a runtime dependency #4350

Description

@tifandotme

Pre-flight checklist

Forge version

7.11.2

Electron version

42.3.2

Operating system

macOS 26.5.2 arm64

Expected behavior

@electron-forge/plugin-vite can be loaded in a project whose node_modules uses a strict, non-hoisted layout.

Actual behavior

The package requires Vite at runtime but declares it only in devDependencies.

These files all require('vite') at runtime:

  • dist/VitePlugin.js
  • dist/ViteConfig.js
  • dist/config/vite.main.config.js
  • dist/config/vite.preload.config.js
  • dist/config/vite.renderer.config.js

With a hoisted node_modules, this resolves by accident through the application's own copy of Vite. With a strict layout it does not resolve at all, the plugin cannot be loaded, and electron-forge start and electron-forge package both fail.

Reproduced with Bun 1.4.0 isolated installs:

$ node -e "require('@electron-forge/plugin-vite')"
Error: Cannot find module 'vite'
Require stack:
- .../@electron-forge/plugin-vite/dist/VitePlugin.js
$ bun -e "require('@electron-forge/plugin-vite')"
error: Cannot find package 'vite' from
  '.../@electron-forge/plugin-vite/dist/VitePlugin.js'

Bun's isolated linker symlinks each package into a content-addressed store outside the project. Node and Bun resolve a symlink to its real path before they walk parent directories, so the resolution chain starts in the store and never reaches the application's root node_modules. The install.hoist fallback directory, hoistPattern and publicHoistPattern do not change this; all three were tried. The globalStore setting does not change it either. The same reasoning applies to pnpm and to Yarn PnP.

Steps to reproduce

  1. Create an empty directory with this package.json:

    {
      "name": "repro",
      "private": true,
      "devDependencies": {
        "@electron-forge/plugin-vite": "7.11.2",
        "vite": "^8.0.16"
      }
    }
  2. Add this bunfig.toml:

    [install]
    linker = "isolated"
  3. Run bun install.

  4. Run node -e "require('@electron-forge/plugin-vite')".

Suggested fix

Add a peer dependency on Vite in packages/plugin/vite/package.json:

"peerDependencies": {
  "vite": ">=5"
}

A peer dependency rather than a regular dependency, because the application owns the Vite version. Forge reads the user's vite.*.config.ts through loadConfigFromFile, so a pinned regular dependency would install a second Vite and parse the config with the wrong major. vite stays in devDependencies for the package's own tests.

This is also constraint-clean: enforceConsistentDependenciesAcrossTheProject in yarn.config.cjs skips peerDependencies and already exempts vite by name.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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