feat(migrate): upgrade existing Vite+ projects across versions#1891
Draft
fengmk2 wants to merge 69 commits into
Draft
feat(migrate): upgrade existing Vite+ projects across versions#1891fengmk2 wants to merge 69 commits into
fengmk2 wants to merge 69 commits into
Conversation
✅ Deploy Preview for viteplus-preview canceled.
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
feb8068 to
5090afc
Compare
vite-plus
@voidzero-dev/vite-plus-core
@voidzero-dev/vite-plus-prompts
@voidzero-dev/vite-plus-cli-darwin-arm64
@voidzero-dev/vite-plus-cli-darwin-x64
@voidzero-dev/vite-plus-cli-linux-arm64-gnu
@voidzero-dev/vite-plus-cli-linux-arm64-musl
@voidzero-dev/vite-plus-cli-linux-x64-gnu
@voidzero-dev/vite-plus-cli-linux-x64-musl
@voidzero-dev/vite-plus-cli-win32-arm64-msvc
@voidzero-dev/vite-plus-cli-win32-x64-msvc
@voidzero-dev/vite-plus-darwin-arm64
@voidzero-dev/vite-plus-darwin-x64
@voidzero-dev/vite-plus-linux-arm64-gnu
@voidzero-dev/vite-plus-linux-arm64-musl
@voidzero-dev/vite-plus-linux-x64-gnu
@voidzero-dev/vite-plus-linux-x64-musl
@voidzero-dev/vite-plus-win32-arm64-msvc
@voidzero-dev/vite-plus-win32-x64-msvc
commit: |
5090afc to
732edd6
Compare
Member
Author
This comment was marked as outdated.
This comment was marked as outdated.
7a1d2de to
c68f763
Compare
1bba44c to
911881e
Compare
- npm-reinstall: guard the package-lock.json parse so a malformed or merge-conflicted lockfile no longer aborts migration mid-write - bun bootstrap: add the direct vite dependency so bun install resolves vitest's vite peer (mirrors the full-migration path) - compat-worker: restore withConfigMetadataResolution so the config compatibility check skips user plugin factories instead of running them (no indefinite hang, no silently dropped warning) - format: only fall back to whole-project formatting outside a git worktree (skip on git errors rather than reformatting everything), and batch the changed-file list to avoid ARG_MAX on large monorepos - oxlint-plugin: invalidate the @nuxt/test-utils cache by package.json mtime so long-lived lint/LSP sessions pick up manifest edits - migrator: drop the dead importOptions wrapper and the unused detectNuxtTestUtilsVitestImportFiles, dedupe redundant source-tree scans and the bun catalog resolver Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Resolve pkg.pr.new commit builds as ordinary npm versions (0.0.0-commit.<sha>) via the registry bridge instead of mutable pkg.pr.new URLs, so test-pkg-pr-new-migrate.sh installs them like released packages. This drops the Bun tarball repack, file: URL overrides, blockExoticSubdeps, and the override/pnpm-version helpers; the project's package manager is pointed at the bridge with npm_config_registry / YARN_NPM_REGISTRY_SERVER. The global CLI keeps installing from pkg.pr.new, which serves the per-platform binaries the bridge cannot. Register each commit build with the bridge from the pkg.pr.new publish workflow (replacing its GitHub webhook), scoped to same-repo PRs. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Run oxfmt on migrator.ts / oxlint-plugin.ts, which drifted from the formatter after the importOptions removal and the @nuxt/test-utils cache change. Regenerate the two global migration snapshots (migration-from-vitest-config and migration-monorepo-pnpm-overrides-dependency-selector) so they reflect the current vitest-provider catalog alignment and pnpm-overrides merge behavior; both were left stale by an earlier commit. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
The pkg.pr.new helper set the bridge registry only via environment variables, which pnpm ignores for resolution (it reads .npmrc), so the migration install fetched the commit version from registry.npmjs.org and failed with ERR_PNPM_NO_MATCHING_VERSION. Write the bridge registry into the project's .npmrc (npm/pnpm/Yarn Classic/Bun) and, for Yarn Berry projects, .yarnrc.yml (npmRegistryServer), so the migrated project resolves the commit builds both during the run and in its own CI. Both writes are idempotent and left in place; the env vars remain as a local-run fallback. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
When a project declares vite-plus in `dependencies` (instead of the conventional `devDependencies`), migration appended a second vite-plus entry to `devDependencies`, leaving it in both groups with a conflicting spec. Every "ensure vite-plus is present" check looked only at `devDependencies`; the firing site for the full-migration path was `rewritePackageJson`, whose `existingVitePlus` ignored `dependencies`. Treat vite-plus as already present when it lives in `dependencies` or `devDependencies` (a `hasDirectVitePlusInstallEntry` helper), and re-pin / normalize the existing entry in place rather than adding a cross-group duplicate. `optionalDependencies` is intentionally excluded so an optional-only entry still gets a guaranteed devDependencies entry. Force-override still re-pins a pre-existing devDependencies entry. Adds a reproducing unit test, the migration-vite-plus-in-dependencies-pnpm snap test, and updates the bootstrap-path tests that codified the old duplicate behavior. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
migrator.ts was ~7,300 lines. Move its 244 declarations verbatim into 16 category modules under migration/migrator/ (eslint, prettier, catalog, vitest-ecosystem, vite-plus-bootstrap, package-json, vite-config, yarn, source-scan, git-hooks, orchestrators, ...). migrator.ts is now a barrel of `export *` re-exports, so the external importers keep importing from ./migrator.ts unchanged. Cross-module function helpers are imported from the barrel (safe because they are only referenced inside function bodies at runtime); shared constants/types live in shared.ts and are imported directly from it to avoid a load-time cycle. Pure code move, no behavior change: tsc clean, vp check clean, 323 migration unit tests unchanged. Adds migrator/README.md documenting the structure and the rules for adding modules. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Add a "Where to Start" pointer so agents read packages/cli/src/migration/migrator/README.md before changing migrator code. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Project skill that verifies a pkg.pr.new build of vite-plus against one real project: runs .github/scripts/test-pkg-pr-new-migrate.sh (vp migrate with deps resolved through the registry bridge), then `vp why` to confirm a single, correct version of vite-plus/vite/vitest. Asks for the PR/SHA and project path when not provided. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
In pkg.pr.new force-override runs (VP_VERSION=https://pkg.pr.new/...), the force-override block re-pins vite-plus to that commit URL and sets needVitePlus. The dedup rewrite only normalized non-protocol specs, so the raw URL leaked into the direct dep instead of `catalog:` (the catalog still holds the URL), breaking the migration-upgrade-pkg-pr-new-pnpm snapshot. Normalize protocol-pinned specs under force-override too, while preserving catalog:named references, matching ensureVitePlusDependencySpecs. Adds a regression spec that mocks VITE_PLUS_VERSION to a pkg.pr.new URL (the shared migrator spec mocks it to `latest`, which hid this case). Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Re-run the Yarn PnP guard after the package manager is resolved: an existing Vite+ project with no detectable manager runs the guard with an undefined manager (a no-op), so a later Yarn resolution under YARN_NODE_LINKER=pnp would slip through. Re-running once the manager is known still rejects the unsupported PnP layout. Pin the preview CLI's own managed Node when running the pkg.pr.new migrate entry. `vp node` resolves Node from the target project's cwd, so a project pinned to an old/unsupported version could fail to launch dist/bin.js even though the isolated CLI ships a compatible runtime; probe the CLI default and pass it via `env exec --node`. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
The registry bridge serves pkg.pr.new commit builds as ordinary npm versions
(0.0.0-commit.<sha>), so the migrate test path no longer needs force-override
to pin raw pkg.pr.new URLs. Remove VP_FORCE_MIGRATE from the bridge e2e script
and convert the migration-upgrade-pkg-pr-new-{pnpm,npm} and
migration-upgrade-pnpm-named-catalog snap fixtures to the bridge version so
they exercise the normal upgrade path (force-override itself stays for the
vp create / ecosystem-ci local-tgz installs).
Revert the force-override protocol-pin normalization in rewritePackageJson and
its spec, since only the now-removed URL+force-override flow reached it. Also
bound the snap normalizer prerelease match to version characters so a
`@0.0.0-commit.<sha>` npm alias in JSON no longer swallows the closing quote.
Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
The bounded-prerelease snap normalizer (515443d) correctly stops eating the ` (current: <semver>)` suffix after the alpha `found` version. This snap was reverted with the network-flaky regen batch; regenerate it for real. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Once the registry bridge accepts a commit build, post (or update via a sticky marker) a PR comment with the resolved vite-plus / vite-plus-core npm versions (0.0.0-commit.<sha>) and the per-package-manager bridge registry config, so reviewers can install the build directly. Gated on the bridge step's real outcome and skipped for fork PRs; never fails the publish. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Align the markdown tables; formatting only (follow-up to the bridge-comment workflow step, which was committed without running vp check). Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
Move the four compat-* files into migration/compat/ with concise names: compat-protocol.ts -> protocol.ts, compat.ts -> manual-chunks.ts, compat-runner.ts -> runner.ts, compat-worker.ts -> worker.ts. Update the cross-file imports, bin.ts and both specs, the tsdown worker entry (now emits dist/migration/compat/worker.js), and the runner's subprocess path (./compat/worker.js). Behavior-preserving: vp check clean, both compat specs pass, and the built bin.js resolves the relocated worker entry. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
A `bunx --bun <tool>` script (e.g. `bunx --bun vite build`) lost its `--bun` flag when the tool was rewritten to a vp subcommand, producing `bunx vp build` and silently switching the user's chosen runtime from Bun to Node. Stop stripping it so it becomes `bunx --bun vp build`, and drop the now-unused forced_bun_suffix_indices tracking. Update the vite_migration Rust unit tests and the JS rewritePackageJson vitest snapshot (package.json scripts are rewritten through the crate via NAPI). Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
6702c0f to
c0970dc
Compare
In the existing-Vite+ upgrade path, ensureExistingPackageManager (the package manager download) starts the "Preparing migration" timer spinner, but nothing stopped it before the interactive setup prompts (collectMigrationSetupPlan). The live spinner kept re-rendering its timer line over the prompt and corrupted it. Clear it right after the download, matching the clearMigrationProgress pattern already used elsewhere in the flow; it restarts for the bootstrap/install phase. Claude-Session: https://claude.ai/code/session_01DQhS6o1fyQd1yjiee6W8jR
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RFC:
rfcs/migrate-existing-projects.mdProblem
Running
vp migrateon an existing v0.1.x Vite+ project did not upgrade cleanly: it delegated to the stale local CLI, leftpnpm-workspace.yamloverrides pinningvite/vitestto old versions, and skewed coverage providers. The v0.2.1 release notes currently tell users not to runvp migrateyet.What this does (verified)
vite-plusis older than the globalvp, run migrate from the global CLI.vite-plus/vite->core spec so the lockfile moves off 0.1.x."pnpm": {}misrouting that left stalepnpm-workspace.yamloverrides.vitestby 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.@vitest/*ecosystem (coverage-v8/-istanbul, ui, web-worker) to the bundled version; exclude@vitest/eslint-plugin.Verified: 248 migration + 728 CLI unit tests,
tsc,vp lint,cargo check/clippy, themigration-vitest-peer-depsnap test, and the urllib 3-PM checks (node-modules/urllib #832-834).Known gaps (draft, follow-ups)
apps/dashboard) is left without@vitest/browser-playwrightand a directvitest, so browser tests break. The fresh-migration path handles this; the upgrade path must too.vitestin the package that needs it instead of the shared root catalog.vitestpin into removal for official-@vitest/*-only projects.migration-*snap suite and do the docs /npm deprecaterollout, then drop the "do not runvp 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 migrateagainst any local project:The first argument accepts either a PR number or commit SHA. The helper keeps the normal
~/.vite-plusinstallation untouched, forces migration through the installed global preview CLI even when the project has a same-version local CLI, pinsvite-plusandvite/core to the matching pkg.pr.new URLs, refuses dirty Git worktrees by default, and forwards additional options such as--no-interactivetovp migrate.