Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/test-vp-create.yml
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,9 @@ jobs:
PACKAGE_MANAGER: ${{ matrix.package-manager }}
run: |
# Issue 1: packages/utils inherits `vite-plus: ^x.y.z` from the
# library template. In catalog-supporting monorepos (pnpm/yarn/bun)
# the migrator must normalize it so siblings don't drift.
# library template. The migrator must normalize it so siblings don't
# drift: to `catalog:` with catalogs, and to the concrete version
# without them (npm).
# Issue 2: apps/website is scaffolded by create-vite which ships
# `vite` (and sometimes `vitest`) in devDependencies. After
# migration the scripts are rewritten to `vp ...` and `vite-plus`
Expand Down Expand Up @@ -425,7 +426,7 @@ jobs:
process.exit(1);
}

if (pm !== 'npm' && appDev['vite-plus'] !== utilsDev['vite-plus']) {
if (appDev['vite-plus'] !== utilsDev['vite-plus']) {
console.error('✗ vite-plus spec drift: apps/website=' + appDev['vite-plus'] + ' packages/utils=' + utilsDev['vite-plus']);
process.exit(1);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "migration-bun-old-no-top-level-catalog",
"workspaces": [],
"devDependencies": {
"vite": "^7.0.0"
},
"devEngines": {
"packageManager": {
"name": "bun",
"version": "1.2.20",
"onFail": "download"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[[case]]
name = "migration_bun_old_no_top_level_catalog"
vp = "global"
comment = "Bun before 1.2.21 reads only `workspaces.catalog`, so a top-level `catalog` would fail to resolve."
steps = [
{ argv = ["vp", "migrate", "--no-interactive"], comment = "an empty-workspaces bun 1.2.20 project without Vite+ migrates", continue-on-failure = true },
{ argv = ["vpt", "print-file", "package.json"], comment = "toolchain specs stay concrete and no top-level catalog is written", continue-on-failure = true },
{ argv = ["vp", "migrate", "--no-interactive"], comment = "a second run converges to the already-migrated fast exit", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# migration_bun_old_no_top_level_catalog

Bun before 1.2.21 reads only `workspaces.catalog`, so a top-level `catalog` would fail to resolve.

## `vp migrate --no-interactive`

an empty-workspaces bun 1.2.20 project without Vite+ migrates

```
VITE+ - The Unified Toolchain for the Web

◇ Migrated . to Vite+ <version>
• Node <version> bun <version>
• 2 config updates applied
```

## `vpt print-file package.json`

toolchain specs stay concrete and no top-level catalog is written

```
{
"name": "migration-bun-old-no-top-level-catalog",
"workspaces": [],
"devDependencies": {
"vite": "npm:@voidzero-dev/vite-plus-core@<version>",
"vite-plus": "<version>"
},
"devEngines": {
"packageManager": {
"name": "bun",
"version": "<version>",
"onFail": "download"
}
},
"overrides": {
"vite": "npm:@voidzero-dev/vite-plus-core@<version>"
},
"scripts": {
"prepare": "vp config"
}
}
```

## `vp migrate --no-interactive`

a second run converges to the already-migrated fast exit

```
VITE+ - The Unified Toolchain for the Web

This project is already using Vite+! Happy coding!
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "migration-upgrade-bun-empty-workspaces-catalog",
"devDependencies": {
"vite-plus": "catalog:",
"vitest": "catalog:"
},
"overrides": {
"vite": "catalog:",
"vitest": "catalog:"
},
"devEngines": {
"packageManager": {
"name": "bun",
"version": "1.4.0",
"onFail": "download"
}
},
"workspaces": {
"packages": [],
"catalog": {
"vite-plus": "^0.1.20",
"vitest": "4.1.9"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[[case]]
name = "migration_upgrade_bun_empty_workspaces_catalog"
vp = "global"
comment = "Bun resolves catalogs whenever the root package.json has a `workspaces` field, even with an empty package list (#3375)."
steps = [
{ argv = ["vp", "migrate", "--no-interactive"], comment = "a single-package bun project with an empty workspaces.packages keeps its catalog", continue-on-failure = true },
{ argv = ["vpt", "print-file", "package.json"], comment = "toolchain specs stay catalog: and the workspaces.catalog is rewritten in place", continue-on-failure = true },
{ argv = ["vp", "migrate", "--no-interactive"], comment = "a second run converges to the already-migrated fast exit", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# migration_upgrade_bun_empty_workspaces_catalog

Bun resolves catalogs whenever the root package.json has a `workspaces` field, even with an empty package list (#3375).

## `vp migrate --no-interactive`

a single-package bun project with an empty workspaces.packages keeps its catalog

```
VITE+ - The Unified Toolchain for the Web

◇ Updated . to Vite+ <version>
• Node <version> bun <version>
• Dependencies:
vite-plus 0.1.20 → <version>
vite → <version>
• Package manager settings configured
```

## `vpt print-file package.json`

toolchain specs stay catalog: and the workspaces.catalog is rewritten in place

```
{
"name": "migration-upgrade-bun-empty-workspaces-catalog",
"devDependencies": {
"vite": "catalog:",
"vite-plus": "catalog:"
},
"overrides": {
"vite": "catalog:"
},
"devEngines": {
"packageManager": {
"name": "bun",
"version": "<version>",
"onFail": "download"
}
},
"workspaces": {
"packages": [],
"catalog": {
"vite-plus": "<version>",
"vite": "npm:@voidzero-dev/vite-plus-core@<version>"
}
}
}
```

## `vp migrate --no-interactive`

a second run converges to the already-migrated fast exit

```
VITE+ - The Unified Toolchain for the Web

This project is already using Vite+! Happy coding!
```
4 changes: 3 additions & 1 deletion docs/guide/migrate-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,9 @@ Migration converts the Volta `volta.node` pin to `.node-version`, because Vite+

### Bun

- Bun catalogs only resolve inside a workspace (a root `package.json` with a non-empty `workspaces`). In a bun workspace, existing top-level or workspace catalog locations and named catalog references are preserved. A standalone (single-package) bun project keeps concrete specs and gets no catalog field, because `bun install` cannot resolve `catalog:` outside a workspace.
- Bun catalogs only resolve inside a workspace, which is a root `package.json` with a `workspaces` field. An empty `workspaces` field also counts. In a bun workspace, existing top-level or workspace catalog locations and named catalog references are preserved. A standalone bun project without `workspaces` keeps concrete specs and gets no catalog field, because `bun install` cannot resolve `catalog:` outside a workspace.
- Bun before 1.2.21 reads only catalogs under `workspaces`. On those versions, migration uses catalogs only when the project already has one under `workspaces`, and keeps concrete specs otherwise.
- When an existing named catalog already owns `vite-plus`, `vite`, or `vitest`, migration adds missing toolchain entries to that catalog instead of creating a default catalog beside it.
- The core alias is mirrored as a direct `vite` dependency so Bun sees the peer provider before applying overrides.

## After the Migration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ describe('rewriteMonorepo bun catalog with file: protocol', () => {
overrides: Record<string, string>;
devDependencies: Record<string, string>;
};
expect(pkg.workspaces.catalog.vite).toBeUndefined();
expect(pkg.workspaces.catalog.vitest).toBeUndefined();
expect(pkg.workspaces.catalog?.vite).toBeUndefined();
expect(pkg.workspaces.catalog?.vitest).toBeUndefined();
expect(pkg.workspaces.catalogs.build.vite).toBe('^7.0.0');
expect(pkg.workspaces.catalogs.build.vitest).toBe('^4.0.0');
expect(pkg.workspaces.catalogs.build.tsdown).toBeUndefined();
Expand Down
Loading
Loading