FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat(migrate): upgrade existing Vite+ projects across versions by fengmk2 · Pull Request #1891 · voidzero-dev/vite-plus · GitHub

feat(migrate): upgrade existing Vite+ projects across versions - #1891

Merged
fengmk2 merged 185 commits into
mainfrom
rfc/migrate-upgrade-path
Jul 2, 2026
Merged

feat(migrate): upgrade existing Vite+ projects across versions#1891
fengmk2 merged 185 commits into
mainfrom
rfc/migrate-upgrade-path

Conversation

fengmk2 commented Jun 19, 2026
edited
Loading

Copy link
Copy Markdown
Member

RFC: rfcs/migrate-existing-projects.md

Problem

vp migrate on an existing v0.1.x Vite+ project did not upgrade cleanly: it delegated to the stale local CLI, left pnpm-workspace.yaml overrides and catalogs pinning vite/vitest to old versions, and skewed coverage providers. The v0.2.x release notes currently tell users not to run vp migrate yet.

What it does

  • Routing: when the local vite-plus is older than the global vp, run migrate from the global CLI so the stale local CLI does not run.
  • Re-pin vite-plus and the vite -> @voidzero-dev/vite-plus-core alias off 0.1.x, across dependencies, overrides/resolutions, and catalogs, for every workspace package rather than only the root manifest.
  • vitest by usage: removed in the common case (vite-plus provides it transitively), kept and ecosystem-aligned when a package uses it directly or via a range-peer integration; align @vitest/* (coverage-v8/-istanbul, ui, web-worker) to the bundled version, with the browser providers kept opt-in.
  • pnpm bootstrap: move package.json#pnpm settings into pnpm-workspace.yaml, fix the empty "pnpm": {} misrouting that left stale overrides, inject the direct vite edge where pnpm needs it, and approve required build scripts. The "pending" check scans every workspace package's catalog ref, so a package pinned to a stale named catalog (catalog:legacy) is not missed.
  • Plugin packages: preserve real vite/vitest imports in vite-plugin-* and unplugin packages instead of rewriting them to vite-plus.
  • Summary: the migrate output leads with Updated . to Vite+ <version> (or Migrated for a fresh project) and lists the toolchain version changes as a from -> to table for vite-plus, the raw vite version, and vitest when present.
  • Progress: on a large monorepo the per-package config-compatibility check reports live progress (Checking config compatibility (N/total): <package>), so the spinner keeps moving and shows what it is processing instead of stalling on a stale message.

Version-only by default, --full for setup

On an existing Vite+ project, vp migrate does the toolchain version upgrade above and silently skips the first-time setup bucket (git hooks, editor config, agent files, ESLint/Prettier migration, framework shims, tsconfig baseUrl, and .nvmrc/Volta to .node-version), so a version bump does not re-touch things you already set up. Pass --full to run the whole setup, or a per-action flag (--hooks / --agent / --editor) to opt into a single action. A bare upgrade that left setup actions on the table hints at vp migrate --full. Fresh (non Vite+) projects always run the full migration.

# default: toolchain version upgrade only
$ vp migrate --no-interactive
◇ Updated . to Vite+ 0.2.1
• Node 22.18.0  pnpm 10.18.0
• Dependencies:
    vite-plus  0.1.21 → 0.2.1
    vite              → 8.1.0
• Package manager settings configured
• Skipped editor, hooks, and lint setup. Run `vp migrate --full` to apply them.

# --full: upgrade plus the setup bucket
$ vp migrate --full --no-interactive
◇ Updated . to Vite+ 0.2.1
• Node 22.18.0  pnpm 10.18.0
• Dependencies:
    vite-plus  0.1.21 → 0.2.1
    vite              → 8.1.0
• 2 config updates applied
• Node version manager file migrated to .node-version
• Package manager settings configured

# --hooks: upgrade plus a single setup action (no --full)
$ vp migrate --hooks --no-interactive
◇ Updated . to Vite+ 0.2.1
• Node 22.18.0  pnpm 10.18.0
• Dependencies:
    vite-plus  0.1.21 → 0.2.1
    vite              → 8.1.0
• Git hooks configured
• Package manager settings configured

On a large monorepo the spinner walks the per-package config-compatibility check, so the run is never silent:

   ◒  Checking config compatibility (7/42): examples/tpr-demo
   ◒  Checking config compatibility (23/42): tests/fixtures/pages-basic
   ◒  Checking config compatibility (40/42): tests/fixtures/ecosystem/next-themes

Node.js version

The native binding runs on any Node >=20.0.0, and the published @voidzero-dev/vite-plus-* platform packages now declare that ABI floor (the vite-plus and core packages keep their wider engines.node support range). So a Node pin whose floor is below the support range but at or above 20.0.0 (engines.node: 24.x, >=22, .node-version 24.3.0, ...) still installs the native binding and is left untouched by migration. Converting .nvmrc and Volta volta.node to .node-version (and repointing any actions/setup-node node-version-file: .nvmrc reference in workflows and composite actions, .github/actions/**/action.{yml,yaml}, so CI does not break) is part of the --full setup, not the default upgrade.

Manual pkg.pr.new testing

Install an isolated pkg.pr.new global CLI and run the PR's vp migrate against a local project. Dependencies resolve through the registry bridge as ordinary 0.0.0-commit.<sha> versions, persisted into the project's .npmrc (and .yarnrc.yml for Yarn Berry) so its own CI installs the same build:

./.github/scripts/test-pkg-pr-new-migrate.sh 1891 /path/to/project [--no-interactive]

The first argument accepts a PR number or commit SHA. The helper keeps ~/.vite-plus untouched, forces migration through the preview CLI even when the project has a same-version local CLI, clears only the workspace root lockfile and node_modules before migrating, and refuses dirty Git worktrees unless ALLOW_DIRTY=1. Confirm the result with vp why -r vite-plus vite vitest (each must resolve to a single version).

fengmk2 self-assigned this Jun 19, 2026

netlify Bot commented Jun 19, 2026
edited
Loading

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 3028a34
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a45e0addb0cdc00085eedbd

socket-security Bot commented Jun 19, 2026
edited
Loading

Copy link
Copy Markdown

fengmk2 added test: e2e Auto run e2e tests test: install-e2e run vite install e2e test test: create-e2e Run `vp create` e2e tests test: sfw preview-build Publish this PR's commits to the registry bridge as preview builds labels Jun 21, 2026
fengmk2 force-pushed the rfc/migrate-upgrade-path branch from feb8068 to 5090afc Compare June 21, 2026 14:11

pkg-pr-new Bot commented Jun 21, 2026
edited
Loading

Copy link
Copy Markdown

Open in StackBlitz

vite-plus

npm i https://pkg.pr.new/voidzero-dev/vite-plus@1891

@voidzero-dev/vite-plus-core

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1891

@voidzero-dev/vite-plus-prompts

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-prompts@1891

@voidzero-dev/vite-plus-cli-darwin-arm64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-darwin-arm64@1891

@voidzero-dev/vite-plus-cli-darwin-x64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-darwin-x64@1891

@voidzero-dev/vite-plus-cli-linux-arm64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-arm64-gnu@1891

@voidzero-dev/vite-plus-cli-linux-arm64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-arm64-musl@1891

@voidzero-dev/vite-plus-cli-linux-x64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-x64-gnu@1891

@voidzero-dev/vite-plus-cli-linux-x64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-x64-musl@1891

@voidzero-dev/vite-plus-cli-win32-arm64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-win32-arm64-msvc@1891

@voidzero-dev/vite-plus-cli-win32-x64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-win32-x64-msvc@1891

@voidzero-dev/vite-plus-darwin-arm64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-darwin-arm64@1891

@voidzero-dev/vite-plus-darwin-x64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-darwin-x64@1891

@voidzero-dev/vite-plus-linux-arm64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-arm64-gnu@1891

@voidzero-dev/vite-plus-linux-arm64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-arm64-musl@1891

@voidzero-dev/vite-plus-linux-x64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-x64-gnu@1891

@voidzero-dev/vite-plus-linux-x64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-x64-musl@1891

@voidzero-dev/vite-plus-win32-arm64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-win32-arm64-msvc@1891

@voidzero-dev/vite-plus-win32-x64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-win32-x64-msvc@1891

commit: 3ee9ab7

fengmk2 force-pushed the rfc/migrate-upgrade-path branch from 5090afc to 732edd6 Compare June 22, 2026 01:52

fengmk2 commented Jun 22, 2026
edited
Loading

Copy link
Copy Markdown
Member Author

E2E test projects

 × typescript(TS2783): 'staged' is specified more than once, so this usage will be overwritten.
     ╭─[vite.config.ts:118:3]
 117 │     export default defineConfig({
 118 │ ╭─▶   staged: {
 119 │ │       '*': 'vp check --fix',
 120 │ ╰─▶   },
 121 │       ...config, // shared lint/fmt/build from @janosh/vite-config (dotfiles)
     ╰────
help: Option 'moduleResolution=node10' has been removed. Please remove it from your configuration.
        See https://github.com/oxc-project/tsgolint/issues/351 for more information.
✖ bash -c "tsc --noEmit":
error TS2688: Cannot find type definition file for 'vite-plus/client'.
  The file is in the program because:
    Entry point of type library 'vite-plus/client' specified in compilerOptions

  tsconfig.json:12:33
    12     "types": ["vitest/globals", "vite-plus/client"],
                                       ~~~~~~~~~~~~~~~~~~
    File is entry point of type library specified here.

This comment was marked as outdated.

fengmk2 added preview-build Publish this PR's commits to the registry bridge as preview builds and removed preview-build Publish this PR's commits to the registry bridge as preview builds labels Jun 23, 2026
fengmk2 force-pushed the rfc/migrate-upgrade-path branch from 7a1d2de to c68f763 Compare June 23, 2026 07:11
fengmk2 added preview-build Publish this PR's commits to the registry bridge as preview builds and removed preview-build Publish this PR's commits to the registry bridge as preview builds labels Jun 23, 2026
fengmk2 added preview-build Publish this PR's commits to the registry bridge as preview builds and removed preview-build Publish this PR's commits to the registry bridge as preview builds labels Jun 24, 2026
fengmk2 force-pushed the rfc/migrate-upgrade-path branch from 1bba44c to 911881e Compare June 24, 2026 03:55
fengmk2 added preview-build Publish this PR's commits to the registry bridge as preview builds and removed preview-build Publish this PR's commits to the registry bridge as preview builds labels Jun 24, 2026

chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7da2ece3dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/cli/install.sh Outdated
Comment thread packages/cli/src/migration/bin.ts Outdated
fengmk2 added 4 commits July 2, 2026 00:02
An existing Vite+ project's version-update prompted to set up pre-commit hooks
whenever a legacy husky/lint-staged config was present, unlike agent/editor
setup which already defer to --full. For an unsupported lint-staged format the
prompt could never do anything (it always ended in "skipping git hooks setup").

getExistingVitePlusSetupOptions now defaults hooks to false like agent/editor;
legacy husky/lint-staged migration runs only with `vp migrate --full` or an
explicit `--hooks`. Drops the now-unused legacyGitHooksMigrationCandidate param
and variable.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
…igrate.sh

The version report resolved the package manager via `vp env current | vp node`,
but the isolated install runs with VP_NODE_MANAGER=no, so `vp node` has no
managed Node and the parse returned empty: no `-r`, so `vp why` queried the
workspace root without recursion and reported nothing.

Detect pnpm from the project's own markers (a `packageManager` pin, a workspace
file, or the post-install lockfile) instead. For pnpm, report all three packages
in one recursive query (`vp why -r vite-plus vite vitest`); npm/yarn/bun still
loop one package at a time since their `why` accepts only one.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Two fixes to the vitest-injection guard in rewritePackageJson (PR review):

- The injection fallback matched any dep whose name contains "vitest",
  including VITEST_DIRECT_USAGE_EXCLUDED packages like @vitest/eslint-plugin.
  When such a package drove the only signal, a catalog monorepo omitted the
  vitest catalog entry yet this still injected `vitest: catalog:`, a dangling
  spec that breaks pnpm install. Use isVitestAdjacent (which applies the
  exclusion filter).
- A @nuxt/test-utils package keeps its `from 'vitest'` imports (the rewriter
  preserves them for Nuxt), but the guard never added a direct vitest, so under
  strict pnpm/Yarn layouts the preserved imports could not resolve. Add
  hasNuxtTestUtilsDependency to needDirectVitest and the injection condition.

Adds two reproducing migrator tests.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR

fengmk2 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@codex review

Picks up voidzero-dev/pkg-pr-registry-bridge#51, which fixes preview tarballs
missing the tar end-of-archive marker (ERR_PNPM_TARBALL_EXTRACT: "Invalid
checksum for TAR header") when the packed size is an exact multiple of 10240.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR

chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5cf9447af4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/cli/src/migration/bin.ts Outdated
…r gate, preview registry)

Addresses four Codex review comments on PR #1891, all verified valid:

- install.sh: `resolve_bridge_commit_version ... || true` so `set -e` does not
  abort at the assignment before the "Could not resolve" error prints (the
  installer otherwise fails silently on an unregistered/transient bridge miss).
- test-pkg-pr-new-migrate.sh: only force-stage `.npmrc`/`.yarnrc.yml` that carry
  the bridge marker, not a pre-existing ignored file that may hold private
  registry auth tokens the migration never touched.
- migration/bin.ts: detect Prettier unconditionally on existing-Vite+ upgrades so
  the format gate skips Oxfmt on a Prettier project even on a non-`--full`
  upgrade; the Prettier migration itself stays gated on `--full`.
- preview-registry.ts: thread the detected package manager into
  reconcilePreviewBridgeRegistry so a pnpm/npm/bun project with a stray
  `.yarnrc.yml` still gets `.npmrc` (its install reads `.npmrc`). Adds a test.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR

fengmk2 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@codex review

chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab9a0b36e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

A standalone (non-monorepo) migration on pnpm 9.5.0-10.6.1 rewrote the toolchain
edges to `catalog:` (catalogs are supported from 9.5.0) but never wrote the
catalog entries to pnpm-workspace.yaml: that write was gated on
`usePnpmWorkspaceYaml` (settings support, >= 10.6.2), so the install could not
resolve `catalog:` and failed.

Gate the pnpm-workspace.yaml write on `usePnpmWorkspaceYaml || supportCatalog`
and pass `usePnpmWorkspaceYaml` as the `writeWorkspaceSettings` flag, so a
9.5-10.6.1 project gets a catalog-only file (settings stay in package.json),
mirroring the monorepo orchestrator. 452cbf6 fixed the existing-Vite+ bootstrap
path; this covers the standalone new-project path.

Removes the now-redundant `shouldRewritePnpmWorkspaceYaml` state (it only ever
mirrored `usePnpmWorkspaceYaml`). Adds a reproducing test.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR

fengmk2 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

@codex review

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 0fecc75a64

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

fengmk2 added 9 commits July 2, 2026 08:55
Rewrite the page in descriptive voice (only Before You Migrate stays
imperative) so readers can tell user steps from automatic behavior.
Merge Dependency Versions/Changes into one Dependency Rules section
with an at-a-glance table, split Source Rewrite Rules into scannable
subsections, turn the script command mapping into a table, group the
pnpm rules by topic, and move the Rolldown warning and reinstall/fmt
behavior into a new After the Migration section.

No behavioral rules were added, removed, or weakened.
Correctness fixes from the xhigh workflow review of this branch vs main:

- vite-plus-bootstrap: write the pnpm-workspace.yaml catalog (creating the
  file when missing) on standalone pnpm 9.5-10.6.1 upgrades so reconciled
  catalog: specs resolve, and judge catalog: specs/overrides through the
  workspace catalog in the <10.6.2 pending check so a migrated project
  converges to the already-using-Vite+ fast exit
- compat runner: kill the config-resolution worker after 30s (new
  runCommandSilently timeoutMs) instead of hanging vp migrate when a
  project-local vite-plus predates the lazyPlugins-skip handshake
- npm reinstall: move stale node_modules/vite aside and restore it when the
  final npm install fails, instead of deleting it up front
- format: only fall back to whole-project formatting on a genuine "not a
  git repository"; dubious-ownership/git-missing now skip formatting; cap
  format arg batches at 24KB on Windows (32,767-char CreateProcess limit)
- catalog: survive scalar-valued peerDependencyRules entries in
  pnpm-workspace.yaml instead of crashing mid-write
- import rewriter: rewrite declare module 'vite' augmentations in every
  file again (they must track the rewritten config import identity) while
  keeping the #2004 config-only scoping for value imports and reference
  directives; count triple-slash-only preserved vitest references in
  preserved_vitest_files
- package detection: verify an ancestor .pnp.cjs actually owns the project
  (findPackageLocator) before running setup(), so foreign PnP hooks are
  never installed process-wide
- preview registry: stash a custom Yarn Berry npmRegistryServer in a YAML
  comment and restore it on real-release cleanup instead of deleting it
- prompts: stop interpolating huge path batches into the vp fmt failure hint
- oxlint plugin: bypass the @nuxt/test-utils cache when stat fails instead
  of colliding on the mtimeMs 0 sentinel
…import

Regenerate the migration-rewrite-declare-module snapshot for the review fix
that rewrites declare module 'vite' augmentations in every file again: an
augmentation binds to the literal specifier, so it must target the same
module as the rewritten vite.config.ts import ('vite-plus') or the augmented
UserConfig options fail type-checking. Value imports and reference-type
directives keep the #2004 config-files-only scoping, and vitest augmentations
are still never rewritten.

Also document the augmentation exception in migrate-rules.md.
Partially reverts e29973c. Through the core alias a preserved
declare module 'vite' augmentation reaches the same
@voidzero-dev/vite-plus-core module whose UserConfig types defineConfig
from vite-plus, so it keeps working after migration. vite-plus exports
no UserConfig symbol, so the rewritten declare module 'vite-plus'
augmentation merged with nothing and silently stopped applying. Users
extending vite-plus's own surface write declare module 'vite-plus'
directly.

Restores the #2004 config-files-only scoping for all vite specifiers,
flips the regression test to assert preservation, regenerates the
migration-rewrite-declare-module snapshot, and documents the rationale
in migrate-rules.md.

fengmk2 commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

AI review and fixed done, human test pass, waiting for CI pass then merge. 🤖

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview-build Publish this PR's commits to the registry bridge as preview builds test: create-e2e Run `vp create` e2e tests test: e2e Auto run e2e tests test: install-e2e run vite install e2e test test: sfw

Projects

None yet

4 participants


Back | FazBrowse Home | New Git URL