Skip to content

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

Draft
fengmk2 wants to merge 83 commits into
mainfrom
rfc/migrate-upgrade-path
Draft

feat(migrate): upgrade existing Vite+ projects across versions#1891
fengmk2 wants to merge 83 commits into
mainfrom
rfc/migrate-upgrade-path

Conversation

@fengmk2

@fengmk2 fengmk2 commented Jun 19, 2026

Copy link
Copy Markdown
Member

RFC: rfcs/migrate-existing-projects.md

Problem

Running 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 pinning vite/vitest to old versions, and skewed coverage providers. The v0.2.1 release notes currently tell users not to run vp migrate yet.

What this does (verified)

  • Routing: when the local vite-plus is older than the global vp, run migrate from the global CLI.
  • Re-pin a behind vite-plus / vite->core spec so the lockfile moves off 0.1.x.
  • Fix the empty "pnpm": {} misrouting that left stale pnpm-workspace.yaml overrides.
  • Manage vitest by usage: removed in the common case (vite-plus provides it transitively), kept + ecosystem-aligned when the project uses it directly or via a range-peer integration.
  • Align the full @vitest/* ecosystem (coverage-v8/-istanbul, ui, web-worker) to the bundled version; exclude @vitest/eslint-plugin.

Node.js version upgrade

A project pinning a Node version below the Vite+ supported range (package.json#engines.node, currently ^20.19.0 || ^22.18.0 || >=24.11.0) makes package managers skip the native binding's optional dependency ("Cannot find native binding"). Migration now reads the effective Node pin (.node-version -> devEngines.runtime -> engines.node, reusing the Rust runtime resolver, with .nvmrc/Volta converted to .node-version first) and rewrites an exact or major.minor pin below the range to the concrete latest release of that major (24.3.0 / 24.2 -> 24.18.0). A bare major or an open range that still resolves to a supported release is left unchanged. Interactive migration confirms the upgrade (default yes); --no-interactive applies it directly.

vp migrate on a fresh project pinning .node-version = 24.3.0 (below the range)
VITE+ - The Unified Toolchain for the Web

◇ Set up pre-commit hooks to run formatting, linting, and type checking with auto-fixes?
  Yes

◇ Which coding agent instruction files should Vite+ create?
  AGENTS.md

◇ Which editor are you using?
    Writes editor config files to enable recommended extensions and Oxlint/Oxfmt integrations.
  VSCode

◇ Upgrade Node.js 24.3.0 to 24.18.0? 24.3.0 is below the Vite+ supported range.
  Yes

◇ Code formatted

◇ Migrated . to Vite+
• Node 24.3.0  pnpm 10.18.0
✓ Dependencies installed in 8.2s
• 1 config update applied, 1 file had imports rewritten
• Git hooks configured
! Warnings:
  - Upgraded Node.js 24.3.0 to 24.18.0 (below the supported range)

.node-version is rewritten 24.3.0 -> 24.18.0. The confirm prompt pauses the migration progress spinner so it does not animate beneath the prompt.

Known gaps (draft, follow-ups)

  • The upgrade path does not yet handle vitest browser mode: a browser-test package (e.g. vibe-dashboard apps/dashboard) is left without @vitest/browser-playwright and a direct vitest, so browser tests break. The fresh-migration path handles this; the upgrade path must too.
  • Monorepo vitest localization: pin a concrete vitest in the package that needs it instead of the shared root catalog.
  • Collapse the direct-usage vitest pin into removal for official-@vitest/*-only projects.
  • Regenerate the migration-* snap suite and do the docs / npm deprecate rollout, then drop the "do not run vp migrate" disclaimer.

Manual pkg.pr.new migration testing

Use the repository helper to install an isolated pkg.pr.new global CLI and run the PR version of vp migrate against any local project:

./.github/scripts/test-pkg-pr-new-migrate.sh 1891 /path/to/project

The first argument accepts either a PR number or commit SHA. The helper keeps the normal ~/.vite-plus installation untouched, forces migration through the installed global preview CLI even when the project has a same-version local CLI, pins vite-plus and vite/core to the matching pkg.pr.new URLs, refuses dirty Git worktrees by default, and forwards additional options such as --no-interactive to vp migrate.

@fengmk2 fengmk2 self-assigned this Jun 19, 2026
@netlify

netlify Bot commented Jun 19, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

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

@socket-security

socket-security Bot commented Jun 19, 2026

Copy link
Copy Markdown

@fengmk2 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 pkg.pr.new labels Jun 21, 2026
@fengmk2 fengmk2 force-pushed the rfc/migrate-upgrade-path branch from feb8068 to 5090afc Compare June 21, 2026 14:11
@pkg-pr-new

pkg-pr-new Bot commented Jun 21, 2026

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: affd11e

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

fengmk2 commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

E2E test projects

@chatgpt-codex-connector

This comment was marked as outdated.

@fengmk2

fengmk2 commented Jun 28, 2026

Copy link
Copy Markdown
Member Author

test comment

@fengmk2 fengmk2 force-pushed the rfc/migrate-upgrade-path branch from 2e6555c to ebad088 Compare June 28, 2026 05:01
@fengmk2 fengmk2 force-pushed the rfc/migrate-upgrade-path branch from ebad088 to 9849ce1 Compare June 28, 2026 05:38
fengmk2 added 3 commits June 28, 2026 13:57
A project pinning a Node version below Vite+'s supported range (package.json
engines.node: ^20.19.0 || ^22.18.0 || >=24.11.0), e.g. .node-version 24.3.0 or
24.2, made engine-strict skip the native binding's optional dependency ("Cannot
find native binding"). During migrate, read the effective Node pin (reusing the
vite_js_runtime resolver: .node-version -> devEngines.runtime -> engines.node;
.nvmrc/Volta are converted to .node-version first) and, when it is an exact or
major.minor pin below the range, rewrite it to the concrete latest release of
that major (24.3.0/24.2 -> 24.18.0). A bare major or open range that resolves to
a supported release is left unchanged.

The supported range and latest-of-major resolution come from package.json
engines.node via NAPI (no hardcoded range or per-major floors). Interactive
migration confirms the upgrade (default yes), pausing the migration progress
spinner so it does not animate beneath the prompt; non-interactive applies it
directly. The two volta/nvmrc snap fixtures use supported versions to stay
deterministic; the logic is covered by mocked unit tests. Docs synced in
migrate-rules.md and the migrate RFCs.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
The compat-runner spec matched the worker path with /compat\/worker\.js$/,
but fileURLToPath yields OS-native separators, so on Windows the path ends
with compat\worker.js and the assertion failed. Match either separator.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
A project skill that drives and captures vp's interactive clack prompts in a
tmux session, with a STOP_AT mode that double-captures a prompt to detect a
spinner animating beneath it (how the Node-upgrade confirm overlap was found).

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
@fengmk2 fengmk2 force-pushed the rfc/migrate-upgrade-path branch from 9849ce1 to d9c74ff Compare June 28, 2026 05:57
Comment thread docs/guide/migrate-rules.md Outdated
Match the docker-image workflow's method: build the sticky bridge-version
comment as a github-script line array (so the fenced JSON block can't collide
with YAML block-scalar indentation) and post it via a marker-based
listComments -> updateComment/createComment, replacing the gh api + sed shell
logic and the now-inlined .github/bridge-comment-template.md.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
fengmk2 added 2 commits June 28, 2026 14:39
…checks

- migration.rs: extract a shared resolved_if_supported helper so the NAPI
  entry point and the test-only mirror verify the resolved version against the
  supported range with one implementation, and correct the inaccurate
  "shared by the NAPI entry point" doc on the test helper.
- format.ts: isExistingFile uses a single statSync().isFile() in try/catch
  instead of existsSync + statSync (two stat syscalls per changed file).
- vitest-ecosystem.ts: compute the required-vitest-peer dependency scan lazily
  (requiredVitestPeer ?? scan()) so the cheap ecosystem-dep check short-circuits
  it, matching the file's existing precomputedScans idiom.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
fengmk2 added 2 commits June 28, 2026 15:32
… rules

Per PR review: the migrate-rules guide does not need to spell out the
interactive vs --no-interactive confirm behavior for the Node.js upgrade.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Replace the manual `curl POST /-/refs` with the bridge's
publish-preview action (fengmk2/pkg-pr-registry-bridge), which downloads each
pkg.pr.new package, re-packs the two preview packages, uploads them with
matching integrity, and registers the ref, the CPU work that previously ran in
the bridge's GitHub webhook. SHA-pinned to bridge main.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
fengmk2 added 2 commits June 28, 2026 21:27
…mment

The bridge comment rebuilt 0.0.0-commit.<sha> from the raw sha; read the
publish-preview action's `version` output instead so the version scheme has a
single source of truth. Also correct the line-array comment to name the real
reason (avoid escaping the inline backticks and fenced json block).

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
The bridge moved from fengmk2/pkg-pr-registry-bridge (render.vip) to
voidzero-dev/pkg-pr-registry-bridge (void.app). Per the new docs/ci-setup.md,
switch the publish workflow to the root action voidzero-dev/pkg-pr-registry-bridge
and the void.app bridge URL, and update the test-pkg-pr-new-migrate helper's
bridge registry to void.app.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
fengmk2 added 2 commits June 28, 2026 23:53
Projects commonly gitignore .npmrc, so the bridge registry the helper writes was
silently dropped from the commit and the project's CI resolved the commit build
from the default registry (which has no 0.0.0-commit.<sha>), failing the
supply-chain policy check with ERR_PNPM_TARBALL_URL_MISMATCH. Force-stage .npmrc
(and .yarnrc.yml for Yarn Berry) so the bridge registry reaches the project's CI.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
fengmk2 added 2 commits June 29, 2026 00:51
The existing-Vite+ upgrade (bootstrap/re-pin) path did not add a direct `vite`
devDep for pnpm, so an already-Vite+ pnpm project being re-pinned kept no direct
vite and pnpm's autoInstallPeers fabricated a separate upstream vite to satisfy
the vitest-ecosystem peer, splitting vite-plus/vite/vitest (`vp why -r vite`
then shows two instances). reconcileVitePlusBootstrapPackage now calls
ensureDirectViteForPnpm (the same helper the full-migration path uses in
rewriteRootWorkspacePackageJson / rewriteMonorepoProject), so the root and every
member that depends on vite-plus gain a direct `vite: catalog:`.

Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg.pr.new 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

Development

Successfully merging this pull request may close these issues.

1 participant