Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ Please manually merge tsdown.config.ts into vite.config.ts, see https://viteplus
• tsup config migrated to tsdown (`vp pack`)
! Warnings:
- tsup.config.ts is shared by packages/a, packages/b. It was preserved and must be migrated manually.
→ Manual follow-up:
- Please manually merge tsdown.config.ts into vite.config.ts, see https://viteplus.dev/guide/migrate#tsdown
```

## `vpt stat-file tsup.config.ts --assert file`
Expand Down
80 changes: 80 additions & 0 deletions packages/cli/src/migration/__tests__/migrator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8796,6 +8796,7 @@ describe('existing Vite+ core migration finalization', () => {
scripts: true,
tsconfigTypes: true,
imports: true,
tsdownConfig: false,
});

const pkg = readJson(path.join(tmpDir, 'package.json')) as {
Expand Down Expand Up @@ -8850,6 +8851,85 @@ describe('existing Vite+ core migration finalization', () => {
};
expect(appPkg.scripts.dev).toBe('vp dev');
});

it('makes a leftover tsdown config discoverable in an existing Vite+ project', () => {
fs.writeFileSync(
path.join(tmpDir, 'package.json'),
JSON.stringify({ name: 'test', devDependencies: { 'vite-plus': 'latest' } }, null, 2),
);
fs.writeFileSync(
path.join(tmpDir, 'tsdown.config.ts'),
`import { defineConfig } from 'tsdown';

export default defineConfig({
entry: { index: 'src/index.ts', utils: 'src/utils.ts' },
});
`,
);

const workspaceInfo = makeWorkspaceInfo(tmpDir, PackageManager.pnpm);
expect(finalizeCoreMigrationForExistingVitePlus(workspaceInfo, true)).toEqual({
scripts: false,
tsconfigTypes: false,
imports: true,
tsdownConfig: true,
});
expect(fs.readFileSync(path.join(tmpDir, 'vite.config.ts'), 'utf8')).toContain(
"import tsdownConfig from './tsdown.config.js';",
);
expect(fs.readFileSync(path.join(tmpDir, 'vite.config.ts'), 'utf8')).toContain(
'pack: tsdownConfig',
);
expect(fs.readFileSync(path.join(tmpDir, 'tsdown.config.ts'), 'utf8')).toContain(
"from 'vite-plus/pack'",
);

expect(finalizeCoreMigrationForExistingVitePlus(workspaceInfo, true)).toEqual({
scripts: false,
tsconfigTypes: false,
imports: false,
tsdownConfig: false,
});
});

it('preserves a tsdown config already wired to pack under a different import name', () => {
fs.writeFileSync(
path.join(tmpDir, 'package.json'),
JSON.stringify({ name: 'test', devDependencies: { 'vite-plus': 'latest' } }, null, 2),
);
fs.writeFileSync(
path.join(tmpDir, 'vite.config.ts'),
`import packConfig from './tsdown.config.js';

export default { pack: packConfig({}) };
`,
);
fs.writeFileSync(
path.join(tmpDir, 'tsdown.config.ts'),
`import { defineConfig } from 'tsdown';

export default defineConfig({ entry: 'src/index.ts' });
`,
);

const originalViteConfig = fs.readFileSync(path.join(tmpDir, 'vite.config.ts'), 'utf8');
const report = createMigrationReport();
const result = finalizeCoreMigrationForExistingVitePlus(
makeWorkspaceInfo(tmpDir, PackageManager.pnpm),
true,
report,
);

expect(result).toEqual({
scripts: false,
tsconfigTypes: false,
imports: true,
tsdownConfig: false,
});
expect(fs.readFileSync(path.join(tmpDir, 'vite.config.ts'), 'utf8')).toBe(originalViteConfig);
expect(report.tsdownImportCount).toBe(0);
expect(report.manualSteps).toEqual([]);
});
});

// Regression: templates such as `create-fate` ship a populated vite.config.ts
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/migration/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,8 @@ async function main() {
if (
coreMigrationResult.scripts ||
coreMigrationResult.tsconfigTypes ||
coreMigrationResult.imports
coreMigrationResult.imports ||
coreMigrationResult.tsdownConfig
) {
didMigrate = true;
}
Expand Down
16 changes: 15 additions & 1 deletion packages/cli/src/migration/migrator/core-finalization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { rewriteScripts } from '../../../binding/index.js';
import { type WorkspacePackage } from '../../types/index.ts';
import { editJsonFile, readJsonFile } from '../../utils/json.ts';
import { rulesDir } from '../../utils/path.ts';
import { hasTsconfigTypesToRewrite, rewriteAllImports, rewriteTsconfigTypes } from '../migrator.ts';
import {
hasTsconfigTypesToRewrite,
mergeTsdownConfigFile,
rewriteAllImports,
rewriteTsconfigTypes,
} from '../migrator.ts';
import { type MigrationReport } from '../report.ts';

const RULES_YAML_PATH = path.join(rulesDir, 'vite-tools.yml');
Expand Down Expand Up @@ -76,6 +81,7 @@ export type CoreMigrationFinalizationResult = {
scripts: boolean;
tsconfigTypes: boolean;
imports: boolean;
tsdownConfig: boolean;
};

function getCoreMigrationProjectPaths(workspaceInfo: CoreMigrationWorkspace): string[] {
Expand Down Expand Up @@ -140,6 +146,7 @@ export function finalizeCoreMigrationForExistingVitePlus(
scripts: false,
tsconfigTypes: false,
imports: false,
tsdownConfig: false,
};

if (pending.scripts) {
Expand All @@ -157,5 +164,12 @@ export function finalizeCoreMigrationForExistingVitePlus(

result.imports = rewriteAllImports(workspaceInfo.rootDir, silent, report, true);

// Partial migrations can already have a Vite+ dependency while leaving
// tsdown.config.* undiscoverable by vp pack. Finalize those configs on the
// existing-Vite+ path just as the fresh migration path does.
for (const projectPath of projectPaths) {
result.tsdownConfig = mergeTsdownConfigFile(projectPath, silent, report) || result.tsdownConfig;
}

return result;
}
31 changes: 28 additions & 3 deletions packages/cli/src/migration/migrator/vite-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,12 @@ export function mergeTsdownConfigFile(
projectPath: string,
silent = false,
report?: MigrationReport,
): void {
): boolean {
const configs = detectConfigs(projectPath);
if (!configs.tsdownConfig) {
return;
return false;
}
const createdViteConfig = !configs.viteConfig;
const viteConfig = ensureViteConfig(projectPath, configs, silent, report);

const fullViteConfigPath = path.join(projectPath, viteConfig);
Expand All @@ -187,11 +188,34 @@ export function mergeTsdownConfigFile(
// For JSON files, merge content directly and delete the file
if (configs.tsdownConfig.endsWith('.json')) {
mergeAndRemoveJsonConfig(projectPath, viteConfig, configs.tsdownConfig, 'pack', silent, report);
return;
return createdViteConfig || !fs.existsSync(fullTsdownConfigPath);
}

// For TS/JS files, import the config file
const tsdownRelativePath = `./${configs.tsdownConfig}`;
// Do not prepend a second `pack` key when the config is already wired under
// a different local import name. If a pack config exists but does not import
// this tsdown config, leave both files untouched and keep the manual follow-up.
if (hasConfigKey(fullViteConfigPath, 'pack')) {
const viteConfigContent = fs.readFileSync(fullViteConfigPath, 'utf8');
const runtimeImportPath = tsdownRelativePath
.replace(/\.mts$/, '.mjs')
.replace(/\.cts$/, '.cjs')
.replace(/\.ts$/, '.js');
const importsTsdownConfig = [tsdownRelativePath, runtimeImportPath].some(
(importPath) =>
viteConfigContent.includes(`from '${importPath}'`) ||
viteConfigContent.includes(`from "${importPath}"`),
);
if (!importsTsdownConfig) {
infoMigration(
`Please manually merge ${displayRelative(fullTsdownConfigPath)} into ${displayRelative(fullViteConfigPath)}, see https://viteplus.dev/guide/migrate#tsdown`,
report,
);
}
return false;
}

const result = mergeTsdownConfig(fullViteConfigPath, tsdownRelativePath);
if (result.updated) {
fs.writeFileSync(fullViteConfigPath, result.content);
Expand All @@ -209,6 +233,7 @@ export function mergeTsdownConfigFile(
`Please manually merge ${displayRelative(fullTsdownConfigPath)} into ${displayRelative(fullViteConfigPath)}, see https://viteplus.dev/guide/migrate#tsdown`,
report,
);
return createdViteConfig || result.updated;
}

/**
Expand Down
Loading