Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
},
"devDependencies": {
"@vitejs/plugin-react": "^4.2.0",
"@vitest/browser-playwright": "^4.0.0",
"oxfmt": "1",
"oxlint": "1",
"vite": "^7.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dev": "vite"
},
"devDependencies": {
"@vitejs/plugin-react": "catalog:",
"vite": "catalog:"
},
"packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default defineConfig({
"prepare": "vp config"
},
"devDependencies": {
"@vitejs/plugin-react": "catalog:",
"vite": "catalog:",
"vite-plus": "catalog:"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"testnpm2": "1.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "catalog:",
"oxfmt": "catalog:",
"oxlint": "catalog:",
"vite": "catalog:",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ cat: .oxfmtrc.json: No such file or directory
"testnpm2": "1.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "catalog:",
"vite": "catalog:",
"vitest": "catalog:",
"vite-plus": "catalog:"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"testnpm2": "1.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "catalog:",
"oxfmt": "catalog:",
"oxlint": "catalog:",
"vite": "catalog:",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ cat: .oxlintrc.json: No such file or directory
"testnpm2": "1.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "catalog:",
"vite": "catalog:",
"vitest": "catalog:",
"vite-plus": "catalog:"
Expand Down
50 changes: 50 additions & 0 deletions packages/cli/src/migration/__tests__/compat.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { describe, expect, it } from 'vitest';

import { checkManualChunksCompat } from '../compat.js';
import { createMigrationReport } from '../report.js';

describe('checkManualChunksCompat', () => {
it('should warn when manualChunks is an object', () => {
const report = createMigrationReport();
checkManualChunksCompat({ manualChunks: { react: ['react', 'react-dom'] } }, report);
expect(report.warnings).toHaveLength(1);
expect(report.warnings[0]).toContain('Object-form');
expect(report.warnings[0]).toContain('codeSplitting');
});

it('should not warn when manualChunks is a function', () => {
const report = createMigrationReport();
checkManualChunksCompat({ manualChunks: () => undefined }, report);
expect(report.warnings).toHaveLength(0);
});

it('should not warn when manualChunks is not set', () => {
const report = createMigrationReport();
checkManualChunksCompat({}, report);
expect(report.warnings).toHaveLength(0);
});

it('should not warn when output is undefined', () => {
const report = createMigrationReport();
checkManualChunksCompat(undefined, report);
expect(report.warnings).toHaveLength(0);
});

it('should handle array of outputs', () => {
const report = createMigrationReport();
checkManualChunksCompat(
[{ manualChunks: () => undefined }, { manualChunks: { vendor: ['lodash'] } }],
report,
);
expect(report.warnings).toHaveLength(1);
});

it('should only add one warning for multiple object-form outputs', () => {
const report = createMigrationReport();
checkManualChunksCompat(
[{ manualChunks: { react: ['react'] } }, { manualChunks: { lodash: ['lodash'] } }],
report,
);
expect(report.warnings).toHaveLength(1);
});
});
28 changes: 26 additions & 2 deletions packages/cli/src/migration/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,22 @@ function showMigrationSummary(options: {
}
}

async function checkRolldownCompatibility(rootDir: string, report: MigrationReport): Promise<void> {
try {
const { resolveConfig } = await import('../index.js');
const { checkManualChunksCompat } = await import('./compat.js');
// Use 'runner' configLoader to avoid Rolldown bundling the config file,
// which prints UNRESOLVED_IMPORT warnings that cannot be suppressed via logLevel.
const config = await resolveConfig(
{ root: rootDir, logLevel: 'silent', configLoader: 'runner' },
Comment thread
fengmk2 marked this conversation as resolved.
'build',
);
checkManualChunksCompat(config.build?.rollupOptions?.output, report);
} catch {
// Config resolution may fail — skip compatibility check silently
}
}

async function executeMigrationPlan(
workspaceInfoOptional: WorkspaceInfoOptional,
plan: MigrationPlan,
Expand Down Expand Up @@ -637,7 +653,11 @@ async function executeMigrationPlan(
cancelAndExit('Vite+ cannot automatically migrate this project yet.', 1);
}

// 5. ESLint → Oxlint migration (before main rewrite so .oxlintrc.json gets picked up)
// 5. Check for Rolldown-incompatible config patterns
updateMigrationProgress('Checking config compatibility');
await checkRolldownCompatibility(workspaceInfo.rootDir, report);
Comment thread
fengmk2 marked this conversation as resolved.

// 6. ESLint → Oxlint migration (before main rewrite so .oxlintrc.json gets picked up)
if (plan.migrateEslint) {
updateMigrationProgress('Migrating ESLint');
const eslintOk = await migrateEslintToOxlint(
Expand Down Expand Up @@ -725,6 +745,7 @@ async function executeMigrationPlan(
installArgs,
{ silent: true },
);

clearMigrationProgress();
return {
installDurationMs: initialInstallSummary.durationMs + finalInstallSummary.durationMs,
Expand Down Expand Up @@ -825,7 +846,10 @@ async function main() {
}
}

if (didMigrate) {
// Check for Rolldown-incompatible config patterns
await checkRolldownCompatibility(workspaceInfoOptional.rootDir, report);

if (didMigrate || report.warnings.length > 0) {
clearMigrationProgress();
showMigrationSummary({
projectRoot: workspaceInfoOptional.rootDir,
Expand Down
19 changes: 19 additions & 0 deletions packages/cli/src/migration/compat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { addMigrationWarning, type MigrationReport } from './report.js';

/**
* Check for Rolldown-incompatible manualChunks config patterns.
*/
export function checkManualChunksCompat(output: unknown, report: MigrationReport): void {
const outputs = Array.isArray(output) ? output : output ? [output] : [];
for (const out of outputs) {
if (out.manualChunks != null && typeof out.manualChunks !== 'function') {
addMigrationWarning(
report,
'Object-form `build.rollupOptions.output.manualChunks` is not supported by Rolldown. ' +
'Convert it to function form or use `build.rolldownOptions.output.codeSplitting`. ' +
'See: https://rolldown.rs/options/output#manualchunks and https://rolldown.rs/in-depth/manual-code-splitting',
);
break;
}
}
}
Loading