From 59ca1b985b42b0aa658f5892d2f5f5d1e8ff4b23 Mon Sep 17 00:00:00 2001 From: Liang Date: Tue, 10 Nov 2026 23:06:40 +0800 Subject: [PATCH] feat(create): skip migration for templates that already use Vite+ --- .../mock-manifest.json | 21 +++++++++ .../snapshots.toml | 10 +++++ .../create_remote_vite_plus_template.md | 41 ++++++++++++++++++ .../create-vp-test-vite-plus-1.0.0.tgz | Bin 0 -> 850 bytes docs/guide/create.md | 2 + packages/cli/src/create/bin.ts | 35 +++++++++++---- 6 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/mock-manifest.json create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots.toml create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots/create_remote_vite_plus_template.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/tarballs/create-vp-test-vite-plus-1.0.0.tgz diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/mock-manifest.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/mock-manifest.json new file mode 100644 index 0000000000..d0f621feb5 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/mock-manifest.json @@ -0,0 +1,21 @@ +{ + "create-vp-test-vite-plus": { + "name": "create-vp-test-vite-plus", + "dist-tags": { + "latest": "1.0.0" + }, + "versions": { + "1.0.0": { + "name": "create-vp-test-vite-plus", + "version": "1.0.0", + "bin": { + "create-vp-test-vite-plus": "index.cjs" + }, + "dist": { + "tarball": "{REGISTRY}/create-vp-test-vite-plus/-/create-vp-test-vite-plus-1.0.0.tgz", + "integrity": "sha512-xvpZCYhS9b6ee0uUQC7FlICwKIR/W6nkIQfWZ1UAfd8b+gzgUjT5kR8JILcITLstgv0prAnOeAVmsgyQExbD7A==" + } + } + } + } +} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots.toml new file mode 100644 index 0000000000..1ce15ee705 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots.toml @@ -0,0 +1,10 @@ +# The fake `create-vp-test-vite-plus` CLI writes a project that already uses +# Vite+, so `vp create` must leave its setup unchanged. +[[case]] +name = "create_remote_vite_plus_template" +vp = "local" +steps = [ + { argv = ["vp", "create", "vp-test-vite-plus", "--no-interactive", "--no-agent", "--no-editor", "--no-git", "--no-hooks", "--", "my-app"], comment = "create from a template that already generates a Vite+ project", snapshot = false, continue-on-failure = true }, + { argv = ["vpt", "print-file", "my-app/package.json"], comment = "dependencies and scripts are not rewritten", continue-on-failure = true }, + { argv = ["vpt", "stat-file", "my-app/pnpm-workspace.yaml", "--assert-not", "file"], comment = "no Vite+ overrides are added", continue-on-failure = true }, +] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots/create_remote_vite_plus_template.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots/create_remote_vite_plus_template.md new file mode 100644 index 0000000000..29f82ffa4a --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/snapshots/create_remote_vite_plus_template.md @@ -0,0 +1,41 @@ +# create_remote_vite_plus_template + +## `vp create vp-test-vite-plus --no-interactive --no-agent --no-editor --no-git --no-hooks -- my-app` + +create from a template that already generates a Vite+ project + + +## `vpt print-file my-app/package.json` + +dependencies and scripts are not rewritten + +``` +{ + "name": "my-app", + "private": true, + "type": "module", + "scripts": { + "dev": "vp dev", + "lint": "eslint ." + }, + "devDependencies": { + "eslint": "^9.0.0", + "vite-plus": "latest" + }, + "devEngines": { + "packageManager": { + "name": "pnpm", + "version": "", + "onFail": "download" + } + } +} +``` + +## `vpt stat-file my-app/pnpm-workspace.yaml --assert-not file` + +no Vite+ overrides are added + +``` +my-app/pnpm-workspace.yaml: missing +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/tarballs/create-vp-test-vite-plus-1.0.0.tgz b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/create_remote_vite_plus_template/tarballs/create-vp-test-vite-plus-1.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..d037e32f0db14f4e604c3c18a84394015a0def56 GIT binary patch literal 850 zcmV-Y1FifYiwFR%G4pBw1MOJdP8&xQrn&S}oVbb>1g!VpV8jKbjc|lo652>nNR-L? z*o?ED-OS7`Muf{gPG2uqsnj#OHc&&MNQNk3zYEXK%=z0h{^lHekBxVb^-#7l7Jpy^ zT$n!`$7zQln2|6$I*#W$;D%m1hT2$9v&(t ztZ&_=kDK^!CjaKY7e>VY@GgUz;(_yjdj5N}b-*5~RLsW*B-LTqzIKA*xv1eK4cmOC{WUh0tUqY zA;ub5LPEV`$Q2g@cuB67D}(QOX^4v+j_r7;nvK)?cDOTKuK#C=pPP@{|Ne{oz^m*3 zecLBJE)# zP6ZY5zJg7V_%Y`a7cH~V=__k#W3rtweRxU0EEVTt6b78E&6;wiKDd9;y6ns z9U}Hwo@jXeW`peg&oeLqPt9pnokEk3N`odleJ*gj+=f%=%XD<{9m&sunDKs5W$}c* c3J0QDzT4L(P>mWjYJ8*k2fRoZ%>Wz#0H$BMhyVZp literal 0 HcmV?d00001 diff --git a/docs/guide/create.md b/docs/guide/create.md index 1e3c258f74..1c36b98261 100644 --- a/docs/guide/create.md +++ b/docs/guide/create.md @@ -74,6 +74,8 @@ Vite+ ships with these built-in templates: Run `vp create --list` to see the built-in templates and the common shorthand templates Vite+ recognizes. +After a third-party template runs, `vp create` migrates the generated project to Vite+. When a standalone project already depends on `vite-plus`, `vp create` skips this migration and keeps the template's tooling choices. + ## Options - `--directory ` writes the generated project into a specific target directory. Only built-in templates and bundled `@org` templates support this option. diff --git a/packages/cli/src/create/bin.ts b/packages/cli/src/create/bin.ts index 30bd7261f5..87c1c3ada9 100644 --- a/packages/cli/src/create/bin.ts +++ b/packages/cli/src/create/bin.ts @@ -38,11 +38,13 @@ import { resolveApproveBuildTargets, } from '../utils/approve-builds.ts'; import { unwrapCliParseOutcome } from '../utils/cli-parse.ts'; +import { isForceOverrideMode } from '../utils/constants.ts'; import { documentationUrl } from '../utils/documentation.ts'; import { detectExistingEditors, selectEditors, writeEditorConfigs } from '../utils/editor.ts'; import { findGitRoot, initGitRepository } from '../utils/git.ts'; import { renderCliDoc } from '../utils/help.ts'; import { readJsonFile } from '../utils/json.ts'; +import { hasVitePlusDependency } from '../utils/package.ts'; import { displayRelative } from '../utils/path.ts'; import { cancelAndExit, @@ -1149,6 +1151,18 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h resumeCreateProgress(); } + // A `create-xxx` CLI that already generates a Vite+ project made its own + // toolchain choices (e.g. keeping ESLint), so skip migration like `vp migrate` + // does for Vite+ projects. Monorepo packages still need the rewrite to align + // with the workspace catalog. + const packageJsonPath = path.join(fullPath, 'package.json'); + const isVitePlusTemplate = + !isMonorepo && + templateInfo.type === TemplateType.remote && + !isForceOverrideMode() && + fs.existsSync(packageJsonPath) && + hasVitePlusDependency(readJsonFile(packageJsonPath)); + // The migrate-before-rewrite reorder is only needed when the template // actually ships ESLint or Prettier (e.g. `create-vite --template // react-ts`). Builtin templates (vite:library, vite:application, @@ -1156,9 +1170,10 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h // and relies on `rewrite*Project` to add tarball overrides BEFORE the // first install, so install-first would break CI's local-tarball resolve. const shouldMigrateLintFmtTools = - detectEslintProject(fullPath).hasDependency || - detectPrettierProject(fullPath).hasDependency || - detectTsupProject(fullPath).hasDependency; + !isVitePlusTemplate && + (detectEslintProject(fullPath).hasDependency || + detectPrettierProject(fullPath).hasDependency || + detectTsupProject(fullPath).hasDependency); let installSummary: CommandRunSummary | undefined; @@ -1338,12 +1353,14 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h await installAndMigrate(fullPath); } updateCreateProgress('Applying Vite+ project setup'); - const skipStagedMigration = shouldSkipStagedMigrationForHooks( - fullPath, - shouldSetupHooks, - workspaceInfo.packageManager, - ); - rewriteStandaloneProject(fullPath, workspaceInfo, skipStagedMigration, compactOutput); + if (!isVitePlusTemplate) { + const skipStagedMigration = shouldSkipStagedMigrationForHooks( + fullPath, + shouldSetupHooks, + workspaceInfo.packageManager, + ); + rewriteStandaloneProject(fullPath, workspaceInfo, skipStagedMigration, compactOutput); + } setPackageManager(fullPath, workspaceInfo.downloadPackageManager); for (const framework of detectFramework(fullPath)) { if (!hasFrameworkShim(fullPath, framework)) {