From 8941df4571fa00ae947cf75612fb32af8d6136a1 Mon Sep 17 00:00:00 2001
From: Sakana <15715093608@163.com>
Date: Thu, 1 Oct 2026 21:40:49 +0800
Subject: [PATCH 1/2] fix(migrate): preserve workspace members when selecting
pnpm
---
.../migration_workspace_members/.gitignore | 2 +
.../migration_workspace_members/package.json | 7 +++
.../packages/a/index.html | 2 +
.../packages/a/package.json | 11 ++++
.../packages/b/index.html | 2 +
.../packages/b/package.json | 11 ++++
.../snapshots.toml | 12 ++++
.../snapshots/migration_workspace_members.md | 53 ++++++++++++++++++
.../src/migration/__tests__/migrator.spec.ts | 55 +++++++++++++++++++
.../src/migration/migrator/orchestrators.ts | 2 +
10 files changed, 157 insertions(+)
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/.gitignore
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/package.json
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/index.html
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/package.json
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/index.html
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/package.json
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots.toml
create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/.gitignore b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/.gitignore
new file mode 100644
index 0000000000..f06235c460
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+dist
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/package.json
new file mode 100644
index 0000000000..60e494364a
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "migration-workspace-members",
+ "private": true,
+ "workspaces": [
+ "packages/*"
+ ]
+}
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/index.html b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/index.html
new file mode 100644
index 0000000000..e3059559fc
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/index.html
@@ -0,0 +1,2 @@
+
+
Workspace member a
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/package.json
new file mode 100644
index 0000000000..5fe599d880
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/a/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "a",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "build": "vite build"
+ },
+ "devDependencies": {
+ "vite": "^7.0.0"
+ }
+}
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/index.html b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/index.html
new file mode 100644
index 0000000000..80cde771a0
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/index.html
@@ -0,0 +1,2 @@
+
+Workspace member b
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/package.json
new file mode 100644
index 0000000000..3b42051e19
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/packages/b/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "b",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "build": "vite build"
+ },
+ "devDependencies": {
+ "vite": "^7.0.0"
+ }
+}
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots.toml
new file mode 100644
index 0000000000..587a1cce35
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots.toml
@@ -0,0 +1,12 @@
+[[case]]
+name = "migration_workspace_members"
+vp = "local"
+local-registry = true
+unset-env = ["VP_SKIP_INSTALL"]
+steps = [
+ { argv = ["vp", "migrate", "--no-interactive", "--no-hooks", "--no-agent", "--no-editor"], comment = "migrate a workspace without a lockfile or package-manager declaration", timeout = 120000 },
+ { argv = ["vpt", "print-file", "pnpm-workspace.yaml"], comment = "the selected pnpm manager retains the workspace members" },
+ { argv = ["vp", "run", "-r", "build"], comment = "both migrated workspace members remain runnable", snapshot = false },
+ { argv = ["vpt", "stat-file", "packages/a/dist/index.html", "--assert", "file"] },
+ { argv = ["vpt", "stat-file", "packages/b/dist/index.html", "--assert", "file"] },
+]
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md
new file mode 100644
index 0000000000..b396a601da
--- /dev/null
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md
@@ -0,0 +1,53 @@
+# migration_workspace_members
+
+## `vp migrate --no-interactive --no-hooks --no-agent --no-editor`
+
+migrate a workspace without a lockfile or package-manager declaration
+
+```
+VITE+ - The Unified Toolchain for the Web
+
+Formatting code...
+
+Code formatted
+◇ Migrated . to Vite+
+• Node pnpm
+✓ Dependencies installed in
+• 1 config update applied
+```
+
+## `vpt print-file pnpm-workspace.yaml`
+
+the selected pnpm manager retains the workspace members
+
+```
+packages:
+ - packages/*
+catalog:
+ vite: npm:@voidzero-dev/vite-plus-core@
+ vite-plus:
+overrides:
+ vite@*: "catalog:"
+peerDependencyRules:
+ allowAny:
+ - vite
+ allowedVersions:
+ vite: "*"
+```
+
+## `vp run -r build`
+
+both migrated workspace members remain runnable
+
+
+## `vpt stat-file packages/a/dist/index.html --assert file`
+
+```
+packages/a/dist/index.html: file
+```
+
+## `vpt stat-file packages/b/dist/index.html --assert file`
+
+```
+packages/b/dist/index.html: file
+```
diff --git a/packages/cli/src/migration/__tests__/migrator.spec.ts b/packages/cli/src/migration/__tests__/migrator.spec.ts
index 5f2b4839a0..b833fc2399 100644
--- a/packages/cli/src/migration/__tests__/migrator.spec.ts
+++ b/packages/cli/src/migration/__tests__/migrator.spec.ts
@@ -1866,6 +1866,61 @@ function readJson(filePath: string): Record {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
+describe('first migration preserves pnpm workspace membership', () => {
+ let project: string;
+
+ beforeEach(() => {
+ project = fs.mkdtempSync(path.join(os.tmpdir(), 'vp-workspace-members-'));
+ fs.writeFileSync(
+ path.join(project, 'package.json'),
+ JSON.stringify({
+ name: 'root',
+ private: true,
+ workspaces: ['packages/*', '!packages/fixtures'],
+ }),
+ );
+ });
+
+ afterEach(() => {
+ fs.rmSync(project, { recursive: true, force: true });
+ });
+
+ it.each([undefined, 'catalog:\n example: ^1.0.0\n'])(
+ 'writes detected globs when the workspace file has no packages: %s',
+ (existing) => {
+ const workspaceFile = path.join(project, 'pnpm-workspace.yaml');
+ if (existing !== undefined) {
+ fs.writeFileSync(workspaceFile, existing);
+ }
+ const workspace = makeWorkspaceInfo(project, PackageManager.pnpm, '11.24.0');
+ workspace.isMonorepo = true;
+ workspace.workspacePatterns = ['packages/*', '!packages/fixtures'];
+
+ rewriteMonorepo(workspace, true, true);
+
+ expect(readYamlObject(workspaceFile).packages).toEqual(workspace.workspacePatterns);
+ if (existing !== undefined) {
+ expect(readYamlObject(workspaceFile).catalog).toMatchObject({ example: '^1.0.0' });
+ }
+ const migrated = fs.readFileSync(workspaceFile, 'utf8');
+ rewriteMonorepo(workspace, true, true);
+ expect(fs.readFileSync(workspaceFile, 'utf8')).toBe(migrated);
+ },
+ );
+
+ it('preserves an existing packages field', () => {
+ const workspaceFile = path.join(project, 'pnpm-workspace.yaml');
+ fs.writeFileSync(workspaceFile, 'packages:\n - apps/*\n');
+ const workspace = makeWorkspaceInfo(project, PackageManager.pnpm);
+ workspace.isMonorepo = true;
+ workspace.workspacePatterns = ['packages/*'];
+
+ rewriteMonorepo(workspace, true, true);
+
+ expect(readYamlObject(workspaceFile).packages).toEqual(['apps/*']);
+ });
+});
+
function readYaml(filePath: string): string {
return fs.readFileSync(filePath, 'utf8');
}
diff --git a/packages/cli/src/migration/migrator/orchestrators.ts b/packages/cli/src/migration/migrator/orchestrators.ts
index d5ebc609e7..269f5cb191 100644
--- a/packages/cli/src/migration/migrator/orchestrators.ts
+++ b/packages/cli/src/migration/migrator/orchestrators.ts
@@ -17,6 +17,7 @@ import {
dropDeadOxlintPluginsDependency,
dropRemovePackageOverrideKeys,
ensurePnpmWorkspaceExoticSubdepsSetting,
+ ensurePnpmWorkspacePackages,
findYarnWorkspaceHoisting,
hasDirectVitePlusInstallEntry,
hasOwnWebdriverioDependency,
@@ -438,6 +439,7 @@ export function rewriteMonorepo(
providerCatalogAdditions,
usesWebdriverio,
);
+ ensurePnpmWorkspacePackages(workspaceInfo.rootDir, workspaceInfo.workspacePatterns);
if (usePnpmWorkspaceSettings && isForceOverrideMode()) {
migratePnpmOverridesToWorkspaceYaml(workspaceInfo.rootDir, {
[VITE_PLUS_NAME]: VITE_PLUS_VERSION,
From b3b9aba340cda6503ac933d94e7b4f2d2304e6af Mon Sep 17 00:00:00 2001
From: Sakana <15715093608@163.com>
Date: Sat, 17 Oct 2026 14:56:12 +0800
Subject: [PATCH 2/2] test(migrate): refresh workspace member migration
snapshot
---
.../snapshots/migration_workspace_members.md | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md
index b396a601da..8add5c6b23 100644
--- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md
+++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_workspace_members/snapshots/migration_workspace_members.md
@@ -7,9 +7,8 @@ migrate a workspace without a lockfile or package-manager declaration
```
VITE+ - The Unified Toolchain for the Web
-Formatting code...
-
-Code formatted
+● Formatting code...
+● Code formatted
◇ Migrated . to Vite+
• Node pnpm
✓ Dependencies installed in