Skip to content

Commit 3e09d5c

Browse files
committed
fix(cli): warn when object-form manualChunks is detected
1 parent ffc1638 commit 3e09d5c

3 files changed

Lines changed: 89 additions & 1 deletion

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { describe, expect, it } from 'vitest';
2+
3+
import { checkManualChunksCompat } from '../compat.js';
4+
import { createMigrationReport } from '../report.js';
5+
6+
describe('checkManualChunksCompat', () => {
7+
it('should warn when manualChunks is an object', () => {
8+
const report = createMigrationReport();
9+
checkManualChunksCompat({ manualChunks: { react: ['react', 'react-dom'] } }, report);
10+
expect(report.warnings).toHaveLength(1);
11+
expect(report.warnings[0]).toContain('Object-form');
12+
expect(report.warnings[0]).toContain('codeSplitting');
13+
});
14+
15+
it('should not warn when manualChunks is a function', () => {
16+
const report = createMigrationReport();
17+
checkManualChunksCompat({ manualChunks: () => undefined }, report);
18+
expect(report.warnings).toHaveLength(0);
19+
});
20+
21+
it('should not warn when manualChunks is not set', () => {
22+
const report = createMigrationReport();
23+
checkManualChunksCompat({}, report);
24+
expect(report.warnings).toHaveLength(0);
25+
});
26+
27+
it('should not warn when output is undefined', () => {
28+
const report = createMigrationReport();
29+
checkManualChunksCompat(undefined, report);
30+
expect(report.warnings).toHaveLength(0);
31+
});
32+
33+
it('should handle array of outputs', () => {
34+
const report = createMigrationReport();
35+
checkManualChunksCompat(
36+
[{ manualChunks: () => undefined }, { manualChunks: { vendor: ['lodash'] } }],
37+
report,
38+
);
39+
expect(report.warnings).toHaveLength(1);
40+
});
41+
42+
it('should only add one warning for multiple object-form outputs', () => {
43+
const report = createMigrationReport();
44+
checkManualChunksCompat(
45+
[{ manualChunks: { react: ['react'] } }, { manualChunks: { lodash: ['lodash'] } }],
46+
report,
47+
);
48+
expect(report.warnings).toHaveLength(1);
49+
});
50+
});

packages/cli/src/migration/bin.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,17 @@ function showMigrationSummary(options: {
539539
}
540540
}
541541

542+
async function checkRolldownCompatibility(rootDir: string, report: MigrationReport): Promise<void> {
543+
try {
544+
const { resolveViteConfig } = await import('../resolve-vite-config.js');
545+
const { checkManualChunksCompat } = await import('./compat.js');
546+
const config = await resolveViteConfig(rootDir);
547+
checkManualChunksCompat(config.build?.rollupOptions?.output, report);
548+
} catch {
549+
// Config resolution may fail — skip compatibility check silently
550+
}
551+
}
552+
542553
async function executeMigrationPlan(
543554
workspaceInfoOptional: WorkspaceInfoOptional,
544555
plan: MigrationPlan,
@@ -724,6 +735,11 @@ async function executeMigrationPlan(
724735
installArgs,
725736
{ silent: true },
726737
);
738+
739+
// 12. Check for Rolldown-incompatible config patterns
740+
updateMigrationProgress('Checking config compatibility');
741+
await checkRolldownCompatibility(workspaceInfo.rootDir, report);
742+
727743
clearMigrationProgress();
728744
return {
729745
installDurationMs: initialInstallSummary.durationMs + finalInstallSummary.durationMs,
@@ -823,7 +839,10 @@ async function main() {
823839
}
824840
}
825841

826-
if (didMigrate) {
842+
// Check for Rolldown-incompatible config patterns
843+
await checkRolldownCompatibility(workspaceInfoOptional.rootDir, report);
844+
845+
if (didMigrate || report.warnings.length > 0) {
827846
clearMigrationProgress();
828847
showMigrationSummary({
829848
projectRoot: workspaceInfoOptional.rootDir,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { addMigrationWarning, type MigrationReport } from './report.js';
2+
3+
/**
4+
* Check for Rolldown-incompatible manualChunks config patterns.
5+
*/
6+
export function checkManualChunksCompat(output: unknown, report: MigrationReport): void {
7+
const outputs = Array.isArray(output) ? output : output ? [output] : [];
8+
for (const out of outputs) {
9+
if (out.manualChunks != null && typeof out.manualChunks !== 'function') {
10+
addMigrationWarning(
11+
report,
12+
'Object-form `build.rollupOptions.output.manualChunks` is not supported by Rolldown. ' +
13+
'Convert it to function form or use `build.rolldownOptions.output.codeSplitting`. ' +
14+
'See: https://rolldown.rs/options/output#manualchunks and https://rolldown.rs/in-depth/manual-code-splitting',
15+
);
16+
break;
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)