Skip to content

Support upstream Vite overrides in ecosystem CI #3135

Description

@fengmk2

Description

vite-ecosystem-ci overrides vite with a locally built upstream version to test downstream projects before a Vite release. Projects that use Vite+ need to keep their build tooling working while their tests exercise that replacement Vite.

The vinext suite uses vite-plus@1.1.0 and runs vp pack during package builds. With the ecosystem CI override, installation fails in postinstall before tests can run:

Failed to resolve pack command: GenericFailure, Expected @voidzero-dev/vite-plus-core@1.1.0, but found vite@8.3.4 at .../node_modules/vite/package.json. Run `vp migrate` to align the Vite alias, then run `vp install`.

Restoring the core alias with vp migrate would defeat the purpose of testing upstream Vite.

The resolver validates both the CLI's own core dependency and the project's vite alias. Excluding the CLI dependency from the override therefore does not remove the project validation failure. Simply skipping validation is also insufficient: pack imports vite/pack, which upstream Vite does not export.

Suggested solution

Separate the internal toolchain from the Vite version under test:

  • Let vp pack use and validate its own matching core without requiring the project's vite to have the same identity.
  • Consider a direct @voidzero-dev/vite-plus-core dependency for internal pack imports and configuration loading, so a global vite override cannot replace them.
  • Provide explicit support for using the project's upstream Vite in vp dev, vp build, and vp preview, including a local file: dependency. Resolve its public CLI entry rather than assuming the bundled core's directory layout.
  • Ensure Vite API calls and Vitest's Vite dependency also use the version under test. vite-plus currently re-exports its own vite dependency, so preserving that dependency for pack can otherwise leave API tests using bundled Vite. Keep vp test and vite-plus/test on the same Vitest instance.

A regression fixture should verify that pack works alongside an overridden Vite and that CLI/API tests actually execute the replacement package. Normal internal-core version checks should remain in place.

Alternative

The experimental vinext adapter preserves the CLI's core with vite-plus>vite: catalog:, invokes the private vite-plus/dist/pack-bin.js entry directly, and redirects Vite API/CLI tests to upstream Vite. It also corrects CLI paths and isolates fixture dependency resolution.

This lets the suite execute, but depends on private implementation details and rewrites downstream tests. A supported mechanism would avoid those workarounds.

Additional context

Only vinext was tested in the fork:

Both runs get past the pack failure and finish with 574 passed, 3 skipped, and 1 failed test. The remaining Workers runtime assertion expects /bundle/runtime.js but receives /bundle/_next/static/runtime.js. It occurs with both Vite versions; these runs are not fully green.

Relevant implementation: core resolution, pack dispatch, pack imports, and API exports.

Related: #2023 discusses the broader aliasing strategy. This request focuses on supporting upstream Vite overrides for ecosystem CI.

Validations

  • Read the Contributing Guidelines.
  • Confirm this request is for Vite+ itself and not for Vite, Vitest, tsdown, Rolldown, or Oxc.
  • Check that there isn't already an issue requesting the same feature.

Activity

  1. self-assigned this
    on Oct 20, 2026
  2. added theissue type on Oct 20, 2026
  3. fengmk2 commented on Oct 20, 2026

    @fengmk2
    MemberAuthor

    Related workaround PR: vitejs/vite-ecosystem-ci#536.

    The draft lets the vinext suite run against upstream Vite while preserving the Vite+ core for pack.

  4. fengmk2 commented on Oct 21, 2026

    @fengmk2
    MemberAuthor

    A revised proposal for discussion: extract a shared runtime package for pack and Rolldown. The package name below is provisional, and this design is not yet agreed.

    The current approach in draft #3142 copies pack and Rolldown into vite-plus while core still contains them. This duplicates the bundled tools in normal installations. Adding a direct canonical core dependency also risks restoring the alias/canonical package duplication addressed by the Vite module identity work.

    The proposed ownership would be:

    • @voidzero-dev/vite-plus-runtime owns tsdown, its CSS/executable extensions, Rolldown, pluginutils, declarations, and worker files.
    • @voidzero-dev/vite-plus-core retains Vite and depends on the shared runtime. Its existing ./pack and ./rolldown* exports become small JavaScript and type forwarders.
    • vite-plus retains its existing vite alias and adds an exact dependency on the same runtime release. Pack imports the runtime directly. The CLI has no direct canonical core dependency.

    The implementations move into the new package; they are removed from core and the CLI.

    flowchart TD
        project["Project and Vite plugins"] -->|"vite alias"| core["vite-plus-core: Vite"]
        cli["vite-plus"] -->|"vite alias"| core
        cli -->|"pack"| runtime["Shared runtime: tsdown + Rolldown + pluginutils"]
        core -->|"Rolldown and compatibility exports"| runtime
        cli --> native["Existing native platform packages"]
        runtime --> native
    
    Loading

    With VP_USE_PROJECT_VITE=1, the project and CLI replace their vite dependency with the same upstream package. Vite commands, public APIs, configuration loading, and Vitest must still use that same Vite instance. Pack keeps its matching runtime release. The opt-in relaxes Vite's release check, while the Vite identity check and pack runtime version check remain.

    The runtime uses the existing native platform packages through declared dependencies, with no dependency back to the CLI. Release and preview publishing would gain a tier: platform packages → runtime → core → CLI. Version stamping, local registry packing, toolchain metadata, and license generation would also need updates.

    An alternative is to keep tsdown in the CLI and let pack reuse Vite's Rolldown: vite/rolldown* for core, or rolldown* resolved from upstream Vite's dependency scope. Upstream Vite 8.3.4 does not export vite/rolldown, so that approach needs a resolver. It avoids a new package, but couples pack to the Rolldown version under test. Pack also uses experimental Rolldown APIs, so an upstream change could break postinstall packaging before the Vite tests run.

    Approach Rolldown implementations bundled in Vite+ packages Pack follows upstream Rolldown New package
    Copy pack and Rolldown into the CLI Two No No
    Reuse the selected Vite's Rolldown One Yes No
    Extract a shared runtime One No One

    The shared runtime guarantees one owner for our bundled Rolldown. It does not guarantee one installed Rolldown during upstream CI: upstream Vite can bring its own version alongside pack's fixed version. Package-manager peer contexts also still need validation.

    An isolated prototype installed from tarballs with pnpm shared the same runtime path between core and the CLI. Pack JavaScript, declaration, and CSS builds, Vite builds, and environment guard checks passed with core and upstream Vite. This used minimal CLI forwarders, not a complete rebuilt CLI. Full CLI/Vitest, release bindings, other package managers, and worker coverage remain outstanding; worker probes also exposed baseline failures that need investigation.

    Before changing the implementation, we should agree on:

    1. Should pack retain a fixed Rolldown when Vite is overridden, or should pack participate in testing upstream Rolldown too?
    2. Is one new shared runtime package and its release integration an acceptable cost?
    3. Is the requirement one Vite+-bundled Rolldown implementation, or one installed Rolldown across the entire overridden project?

    My current preference is the shared runtime boundary, subject to that discussion.

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

Metadata

Metadata

Assignees

Type

Fields

Priority

Low

Effort

None yet

Target date

None yet

Start date

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions