feat(create): auto-migrate ESLint/Prettier to oxlint/oxfmt#1434
Draft
feat(create): auto-migrate ESLint/Prettier to oxlint/oxfmt#1434
Conversation
Vite+ is opinionated about oxlint + oxfmt, but `vp create` previously scaffolded templates (e.g. `create-vite --template react-ts`) and left their ESLint flat config and Prettier configs untouched — forcing users to run `vp migrate` as a second step. This wires the existing migration helpers into `vp create` so freshly scaffolded projects are already on the unified toolchain, with no confirmation prompt. - Relocate the ESLint/Prettier prompt/warn/confirm helpers from migration/bin.ts to migration/migrator.ts so create/bin.ts can reuse them without triggering bin.ts's top-level `main()` side effect. - In create/bin.ts, run `promptEslintMigration` and `promptPrettierMigration` after `runViteInstall` (so `@oxlint/migrate` can resolve the template's ESLint plugin imports) and before `runViteFmt`. Always non-interactive — unlike `vp migrate`, the scaffold has no prior user preferences to respect. - Gate on `installSummary.status === 'installed'` so VP_SKIP_INSTALL snap-test runs skip migration cleanly. - Update rfcs/code-generator.md: flip the "does NOT migrate ESLint/Prettier" bullets, update flow diagrams and example output, and document why create skips the confirmation prompt.
✅ Deploy Preview for viteplus-preview canceled.
|
Member
Author
How to use the Graphite Merge QueueAdd the label auto-merge to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
The existing `new-create-vite` snap test runs with VP_SKIP_INSTALL=1 (set globally by the snap-test tool), so the new install-gated migration path in vp create is a no-op there. Add a dedicated snap test that unsets VP_SKIP_INSTALL, runs `vp create --template react-ts` end-to-end, and asserts the post-migration state: - .oxlintrc.json generated - eslint.config.js deleted - package.json lint script rewritten to `vp lint .` - eslint devDependency removed
fengmk2
commented
Apr 21, 2026
fengmk2
commented
Apr 21, 2026
fengmk2
commented
Apr 21, 2026
fengmk2
commented
Apr 21, 2026
…rewrite Addresses review feedback: the RFC and implementation were misordered — the "merge .oxlintrc/.oxfmtrc → vite.config.ts" step was described before the ESLint/Prettier migration that generates those configs, so in practice `.oxlintrc.json` ended up as a loose file instead of being merged, unlike `vp migrate`. Reorder the create pipeline to match `vp migrate`: scaffold → install #1 (template deps incl. ESLint plugins, so @oxlint/migrate can resolve imports from eslint.config.js) → migrate ESLint → oxlint / Prettier → oxfmt (generates .oxlintrc.json, .oxfmtrc.json) → rewrite (merges .oxlintrc/.oxfmtrc into vite.config.ts, swaps vite/vitest → vite-plus) → install #2 (fetches vite-plus, prunes eslint/prettier deps) → fmt End state now matches `vp migrate`: `.oxlintrc.json` is merged into `vite.config.ts` as a `lint: { ... }` section, eslint/prettier deps are gone, and `vite-plus` is installed. Update the new-create-vite-migrates-eslint-prettier snap test to assert the merged end state (`.oxlintrc.json` absent, `vite.config.ts` has a `lint:` section, `vite-plus` devDep present). Update the RFC flow diagrams and bullet lists to reflect the migrate-before-merge ordering.
… windows
Addresses review feedback on the new-create-vite-migrates-eslint-prettier
snap test:
- Switch from `vp create vite:application --directory my-react-ts` to
`vp create vite@9.0.5 -- my-react-ts --template react-ts`. Pinning
create-vite to 9.0.5 makes the snap stable against upstream template
changes, and the project name is passed as a positional (which is
what create-vite expects; `--directory` is rejected for remote
templates).
- Add `cat my-react-ts/vite.config.ts` so the snap captures the full
merged config (oxlint `lint: { ... }` block + `fmt: {}` section),
making the parity with `vp migrate` directly visible in diffs.
- Drop `ignoredPlatforms: ["win32"]` — nothing in this flow is
Windows-specific.
…hint Simplify review follow-ups: - Extract the install-gated migrate block into a local `migrateLintFmtTools` arrow so the standalone and monorepo branches stop duplicating the same 7-line sequence (install status check → progress update → pause/resume → two awaits). The WHY comment now lives once above the helper instead of being copy-pasted above each call site. - Trim the redundant second-install WHAT comment to a single-line WHY (fetch vite-plus added by rewrite, prune removed eslint/prettier). - Drop "Fix the issue and re-run `vp migrate`" from `promptEslintMigration` / `promptPrettierMigration` failure messages. These helpers are now invoked by both `vp create` and `vp migrate`, so the recovery hint was misleading for create-context callers.
…tier CI failure: vp create library (npm/yarn/bun) was failing with ERR_PNPM_NO_MATCHING_VERSION for @voidzero-dev/vite-plus-core@0.0.0. The previous commit added an unconditional pre-rewrite install so that `@oxlint/migrate` could resolve the template's ESLint plugin imports. That broke builtin templates (vite:library, vite:application, vite:monorepo) — their scaffold already references vite-plus and relies on `rewrite*Project` to add the tarball overrides BEFORE the first install. Running install first made pnpm fall back to the npm registry for vite-plus-core@0.0.0, which CI publishes only as a local tarball. Gate the migrate-before-rewrite reorder on `detectEslintProject` / `detectPrettierProject`. Builtin templates have neither, so they keep the original rewrite → install → fmt flow (unchanged from main). Remote templates like `create-vite --template react-ts` do ship ESLint/Prettier, so they still get the reorder that merges .oxlintrc /.oxfmtrc into vite.config.ts.
… entry The existing matrix only covers builtin templates (vite:monorepo, vite:application, vite:library) — none of which ship ESLint or Prettier, so the recent ESLint/Prettier auto-migration path in `vp create` goes untested by this workflow. Add `remote-vite-react-ts` that scaffolds with `vp create vite@9.0.5 -- test-project --template react-ts` (pinned so the snap is stable against upstream template changes) and asserts the post-migration end state: - eslint.config.js deleted - .oxlintrc.json merged into vite.config.ts (not left loose) - vite.config.ts contains a `lint:` section - package.json: eslint devDep removed, vite-plus devDep present, `lint` script rewritten to `vp lint …` The verification step is gated on a new matrix `verify-migration` field so builtin entries skip it. All four package managers (pnpm, npm, yarn, bun) exercise the path.
The newly added `remote-vite-react-ts` matrix entry passes on pnpm but fails on npm/yarn/bun with ERR_PNPM_NO_MATCHING_VERSION for @voidzero-dev/vite-plus-core@0.0.0 — even in the (npm) job. Root cause: create-vite@9.0.5 writes `"packageManager": "pnpm@..."` into the scaffolded package.json, which `vp install` follows over the `--package-manager` CLI flag. Combined with the local-tarball overrides CI uses (which are written in a form pnpm-standalone won't consult on the second install), install #2 falls back to the npm registry for vite-plus-core@0.0.0 and fails. Wiring --package-manager through remote-template scaffolds (and updating the overrides injection to match) is separate infrastructure work. For now, exclude npm/yarn/bun combinations via a matrix `exclude` so the regression coverage we gain on pnpm is still in CI without red builds on the other three.
…stall The remote-template migrate flow was breaking on npm/yarn/bun because `vp install` couldn't honor `--package-manager`: - `vite_install`'s `prompt_package_manager_selection` hardcodes pnpm in CI / non-TTY environments when no `packageManager` field, no workspace file, and no lockfile are present. create-vite scaffolds without a `packageManager` field, so every non-pnpm path silently switched to pnpm at install #1 — leaving the wrong lockfile for install #2 and tripping ERR_PNPM_NO_MATCHING_VERSION on CI's local tarballs. - Yarn Berry's default Plug'n'Play stores deps inside .yarn/cache/*.zip. `@oxlint/migrate` calls fileURLToPath over zip entries and throws MODULE_NOT_FOUND on `@eslint/js`. Before install #1 in the migrate-gated branches (standalone + monorepo): - Call `setPackageManager(fullPath, downloadPackageManager)` so `vp install` picks up the `--package-manager` choice from the field. - For yarn, write a minimal `.yarnrc.yml` with `nodeLinker: node-modules` so the install produces a classic `node_modules/` that `@oxlint/migrate` can resolve. Export `setPackageManager` from migrator.ts for reuse from create/bin.ts. Verified end-to-end locally: all four package managers (pnpm / npm / yarn / bun) now migrate `vite@9.0.5 --template react-ts` cleanly — eslint.config.js removed, `.oxlintrc.json` merged into vite.config.ts, packageManager pinned to the chosen PM. Drop the CI matrix `exclude` that previously scoped this entry to pnpm.
Simplify follow-up: the standalone and monorepo branches in vp create were each carrying the same 7-step block (setPackageManager → yarn .yarnrc.yml → progress update → runViteInstall → migrate prompts), differing only in the install cwd. The yarn caveat comment was duplicated verbatim in both blocks. Fold both blocks plus the previously separate `migrateLintFmtTools` arrow into a single `installAndMigrate(installCwd)` closure. The WHY comments live once above the helper. Net -26 lines in create/bin.ts with no behavior change; all four package managers (pnpm/npm/yarn/bun) still migrate `vite@9.0.5 --template react-ts` correctly end-to-end.
Member
Author
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0f8b49b. Configure here.
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.

Vite+ is opinionated about oxlint + oxfmt, but
vp createpreviouslyscaffolded templates (e.g.
create-vite --template react-ts) and lefttheir ESLint flat config and Prettier configs untouched — forcing users
to run
vp migrateas a second step. This wires the existing migrationhelpers into
vp createso freshly scaffolded projects are already onthe unified toolchain, with no confirmation prompt.
migration/bin.ts to migration/migrator.ts so create/bin.ts can reuse
them without triggering bin.ts's top-level
main()side effect.promptEslintMigrationandpromptPrettierMigrationafterrunViteInstall(so@oxlint/migratecan resolve the template's ESLint plugin imports) and before
runViteFmt. Always non-interactive — unlikevp migrate, thescaffold has no prior user preferences to respect.
installSummary.status === 'installed'so VP_SKIP_INSTALLsnap-test runs skip migration cleanly.
ESLint/Prettier" bullets, update flow diagrams and example output,
and document why create skips the confirmation prompt.
Note
Medium Risk
Changes
vp createpost-scaffold flow to conditionally install-before-rewrite and run non-interactive ESLint/Prettier migrations, which can affect dependency installation order and generated configs across package managers (notably Yarn). CI coverage is added, but the behavior change is user-facing and tied to tooling resolution.Overview
vp createnow detects when a scaffolded template includes ESLint (flat config) and/or Prettier and automatically migrates them to oxlint/oxfmt before the usual Vite+ rewrite, so the generated.oxlintrc.json/.oxfmtrc.jsonget merged intovite.config.tsand scripts/deps are updated.To enable reuse without CLI side effects, the ESLint/Prettier prompt/warn/confirm helpers are moved from
migration/bin.tsintomigration/migrator.ts(andsetPackageManageris exported), andcreate/bin.tsadds an install-first path (including forcing Yarnnode-moduleslinker) gated on successful install.CI and snapshot coverage are expanded with a remote
create-vite react-tscase and assertions thateslint.config.jsis removed, no loose.oxlintrc.jsonremains,vite.config.tshas alintsection, andpackage.jsondropseslintwhile usingvp lint.Reviewed by Cursor Bugbot for commit 0f8b49b. Configure here.