From b1545b18d723571592e984c3df190747a6d938c0 Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Thu, 23 Jul 2026 14:51:59 +0900 Subject: [PATCH 1/2] fix(create): honor explicit package manager outside monorepos Keep existing monorepo package managers authoritative while allowing standalone creates to override package-manager signals inherited from ancestor directories. --- .../package-lock.json | 12 ++++++++++++ .../snapshots.toml | 3 ++- .../snapshots/create_from_nonworkspace_subdir.md | 12 ++++++++++-- packages/cli/src/create/bin.ts | 15 +++++++++++---- rfcs/package-manager-detection.md | 7 ++++--- 5 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/package-lock.json diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/package-lock.json b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/package-lock.json new file mode 100644 index 0000000000..1c1a1dd527 --- /dev/null +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/package-lock.json @@ -0,0 +1,12 @@ +{ + "name": "parent-project", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "parent-project", + "version": "0.0.0" + } + } +} diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots.toml b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots.toml index 6fc7cd7131..ce9304ffa1 100644 --- a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots.toml +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots.toml @@ -3,7 +3,8 @@ name = "create_from_nonworkspace_subdir" vp = "global" skip-platforms = ["windows"] steps = [ - { argv = ["vp", "create", "--no-interactive", "vite:application"], cwd = "scripts", comment = "from non-monorepo subdir", snapshot = false, continue-on-failure = true }, + { argv = ["vp", "create", "--no-interactive", "--package-manager", "pnpm", "vite:application"], cwd = "scripts", comment = "explicit package manager overrides the non-workspace ancestor", snapshot = false, continue-on-failure = true }, { argv = ["vpt", "stat-file", "scripts/vite-plus-application/package.json", "--assert", "file"], comment = "created at scripts/vite-plus-application", continue-on-failure = true }, + { argv = ["vpt", "grep-file", "scripts/vite-plus-application/package.json", "\"name\": \"pnpm\""], comment = "pins pnpm in devEngines", continue-on-failure = true }, { argv = ["vpt", "stat-file", "vite-plus-application/package.json", "--assert-not", "file"], comment = "not created at parent root", continue-on-failure = true }, ] diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots/create_from_nonworkspace_subdir.md b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots/create_from_nonworkspace_subdir.md index 5a7dbcc662..408d5fa248 100644 --- a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots/create_from_nonworkspace_subdir.md +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/create_from_nonworkspace_subdir/snapshots/create_from_nonworkspace_subdir.md @@ -1,8 +1,8 @@ # create_from_nonworkspace_subdir -## `cd scripts && vp create --no-interactive vite:application` +## `cd scripts && vp create --no-interactive --package-manager pnpm vite:application` -from non-monorepo subdir +explicit package manager overrides the non-workspace ancestor ## `vpt stat-file scripts/vite-plus-application/package.json --assert file` @@ -13,6 +13,14 @@ created at scripts/vite-plus-application scripts/vite-plus-application/package.json: file ``` +## `vpt grep-file scripts/vite-plus-application/package.json '"name": "pnpm"'` + +pins pnpm in devEngines + +``` +scripts/vite-plus-application/package.json: found "\"name\": \"pnpm\"" +``` + ## `vpt stat-file vite-plus-application/package.json --assert-not file` not created at parent root diff --git a/packages/cli/src/create/bin.ts b/packages/cli/src/create/bin.ts index 0ef9c028e1..6dffca1a0c 100644 --- a/packages/cli/src/create/bin.ts +++ b/packages/cli/src/create/bin.ts @@ -826,7 +826,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h } } - // Resolve package manager: workspace detection > CLI flag > interactive prompt/default + // Resolve package manager: existing monorepo > CLI flag > ambient detection > prompt/default if ( options.packageManager && !Object.values(PackageManager).includes(options.packageManager as PackageManager) @@ -837,16 +837,23 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h ); cancelAndExit('Invalid --package-manager value', 1); } + const requestedPackageManager = options.packageManager as PackageManager | undefined; + const detectedPackageManager = workspaceInfoOptional.packageManager; const packageManager = - workspaceInfoOptional.packageManager ?? - (options.packageManager as PackageManager | undefined) ?? + (isMonorepo + ? (detectedPackageManager ?? requestedPackageManager) + : (requestedPackageManager ?? detectedPackageManager)) ?? (await selectPackageManager(options.interactive, compactOutput)); + const packageManagerVersion = + packageManager === detectedPackageManager + ? workspaceInfoOptional.packageManagerVersion + : 'latest'; const shouldSilencePackageManagerInstallLog = compactOutput || (isMonorepo && workspaceInfoOptional.packageManager !== undefined); // ensure the package manager is installed by vite-plus const downloadResult = await downloadPackageManager( packageManager, - workspaceInfoOptional.packageManagerVersion, + packageManagerVersion, options.interactive, shouldSilencePackageManagerInstallLog, ); diff --git a/rfcs/package-manager-detection.md b/rfcs/package-manager-detection.md index 376c88b059..ac3180619b 100644 --- a/rfcs/package-manager-detection.md +++ b/rfcs/package-manager-detection.md @@ -145,11 +145,12 @@ vp create vite:monorepo --no-interactive --package-manager bun **Resolution priority for `vp create`**: -1. Detected workspace package manager (`packageManager` field or `devEngines.packageManager`; existing monorepo takes precedence) +1. Existing monorepo package manager (`packageManager` field or `devEngines.packageManager`) 2. `--package-manager` CLI flag -3. Interactive prompt / auto-default (pnpm) +3. Package manager detected from a non-monorepo ancestor +4. Interactive prompt / auto-default (pnpm) -This ensures monorepo consistency: if you run `vp create` inside an existing workspace that already has a `packageManager` field, the workspace setting wins over the CLI flag. +This ensures monorepo consistency while allowing standalone projects to override ambient detection explicitly. ## Auto-Update Behavior From e8f10cf329551ff2bd8343027697805bab483550 Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Thu, 23 Jul 2026 15:08:18 +0900 Subject: [PATCH 2/2] docs(create): clarify monorepo package manager precedence --- rfcs/package-manager-detection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/package-manager-detection.md b/rfcs/package-manager-detection.md index ac3180619b..c5a411706e 100644 --- a/rfcs/package-manager-detection.md +++ b/rfcs/package-manager-detection.md @@ -145,7 +145,7 @@ vp create vite:monorepo --no-interactive --package-manager bun **Resolution priority for `vp create`**: -1. Existing monorepo package manager (`packageManager` field or `devEngines.packageManager`) +1. Any package manager detected for an existing monorepo (from manifest fields, workspace files, lockfiles, or package-manager configuration) 2. `--package-manager` CLI flag 3. Package manager detected from a non-monorepo ancestor 4. Interactive prompt / auto-default (pnpm)