Skip to content

Commit 5d3da91

Browse files
committed
refactor(cli/create): collapse install-and-migrate into single helper
Simplify follow-up: the standalone and monorepo branches in vp create were each carrying the same 7-step block (setPackageManager → yarn .yarnrc.yml → progress update → runViteInstall → migrate prompts), differing only in the install cwd. The yarn caveat comment was duplicated verbatim in both blocks. Fold both blocks plus the previously separate `migrateLintFmtTools` arrow into a single `installAndMigrate(installCwd)` closure. The WHY comments live once above the helper. Net -26 lines in create/bin.ts with no behavior change; all four package managers (pnpm/npm/yarn/bun) still migrate `vite@9.0.5 --template react-ts` correctly end-to-end.
1 parent 01f1254 commit 5d3da91

1 file changed

Lines changed: 32 additions & 58 deletions

File tree

packages/cli/src/create/bin.ts

Lines changed: 32 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -899,23 +899,6 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
899899
});
900900
resumeCreateProgress();
901901

902-
// Auto-migrate ESLint → Oxlint and Prettier → Oxfmt after install #1 so
903-
// `@oxlint/migrate` can resolve imports from eslint.config.js, but before
904-
// the vite-plus rewrite so the generated .oxlintrc/.oxfmtrc get merged
905-
// into vite.config.ts — matching `vp migrate`. Always non-interactive;
906-
// Vite+ is opinionated about oxlint/oxfmt. Gated on install success so
907-
// VP_SKIP_INSTALL snap tests don't hit ERR_MODULE_NOT_FOUND.
908-
const migrateLintFmtTools = async (installed: boolean) => {
909-
if (!installed) {
910-
return;
911-
}
912-
updateCreateProgress('Migrating lint and format tools');
913-
pauseCreateProgress();
914-
await promptEslintMigration(fullPath, /* interactive */ false);
915-
await promptPrettierMigration(fullPath, /* interactive */ false);
916-
resumeCreateProgress();
917-
};
918-
919902
// The migrate-before-rewrite reorder is only needed when the template
920903
// actually ships ESLint or Prettier (e.g. `create-vite --template
921904
// react-ts`). Builtin templates (vite:library, vite:application,
@@ -926,6 +909,36 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
926909
detectEslintProject(fullPath).hasDependency || detectPrettierProject(fullPath).hasDependency;
927910

928911
let installSummary: CommandRunSummary | undefined;
912+
913+
// For templates that ship ESLint/Prettier, install template deps first so
914+
// `@oxlint/migrate` can resolve eslint.config.js's plugin imports, then
915+
// migrate before the vite-plus rewrite so the generated .oxlintrc/.oxfmtrc
916+
// get merged into vite.config.ts — matching `vp migrate`. Pin the
917+
// packageManager field (vite_install hardcodes pnpm in CI/non-TTY when no
918+
// signal is present) and force yarn's classic node_modules layout (PnP
919+
// zip entries break @oxlint/migrate's fileURLToPath resolution).
920+
const installAndMigrate = async (installCwd: string) => {
921+
setPackageManager(fullPath, workspaceInfo.downloadPackageManager);
922+
if (workspaceInfo.packageManager === PackageManager.yarn) {
923+
const yarnrcPath = path.join(fullPath, '.yarnrc.yml');
924+
if (!fs.existsSync(yarnrcPath)) {
925+
fs.writeFileSync(yarnrcPath, 'nodeLinker: node-modules\n');
926+
}
927+
}
928+
updateCreateProgress('Installing dependencies');
929+
installSummary = await runViteInstall(installCwd, options.interactive, installArgs, {
930+
silent: compactOutput,
931+
});
932+
if (installSummary.status !== 'installed') {
933+
return;
934+
}
935+
updateCreateProgress('Migrating lint and format tools');
936+
pauseCreateProgress();
937+
await promptEslintMigration(fullPath, /* interactive */ false);
938+
await promptPrettierMigration(fullPath, /* interactive */ false);
939+
resumeCreateProgress();
940+
};
941+
929942
if (isMonorepo) {
930943
if (!compactOutput) {
931944
prompts.log.step('Monorepo integration...');
@@ -991,28 +1004,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
9911004

9921005
updateWorkspaceConfig(projectDir, workspaceInfo);
9931006
if (shouldMigrateLintFmtTools) {
994-
// Pin the packageManager field before install so `vp install` honors
995-
// the user's `--package-manager` choice instead of falling back to
996-
// pnpm (the hardcoded non-interactive/CI default in vite_install).
997-
setPackageManager(fullPath, workspaceInfo.downloadPackageManager);
998-
// Yarn Berry's default Plug'n'Play stores deps inside .yarn/cache/*.zip,
999-
// which @oxlint/migrate can't resolve (ESM's fileURLToPath over a zip
1000-
// entry throws MODULE_NOT_FOUND). Force classic node_modules layout so
1001-
// the migration step can import the template's ESLint plugins.
1002-
if (workspaceInfo.packageManager === PackageManager.yarn) {
1003-
const yarnrcPath = path.join(fullPath, '.yarnrc.yml');
1004-
if (!fs.existsSync(yarnrcPath)) {
1005-
fs.writeFileSync(yarnrcPath, 'nodeLinker: node-modules\n');
1006-
}
1007-
}
1008-
updateCreateProgress('Installing dependencies');
1009-
installSummary = await runViteInstall(
1010-
workspaceInfo.rootDir,
1011-
options.interactive,
1012-
installArgs,
1013-
{ silent: compactOutput },
1014-
);
1015-
await migrateLintFmtTools(installSummary.status === 'installed');
1007+
await installAndMigrate(workspaceInfo.rootDir);
10161008
}
10171009
updateCreateProgress('Integrating into monorepo');
10181010
rewriteMonorepoProject(fullPath, workspaceInfo.packageManager, undefined, compactOutput);
@@ -1031,25 +1023,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
10311023
});
10321024
} else {
10331025
if (shouldMigrateLintFmtTools) {
1034-
// Pin the packageManager field before install so `vp install` honors
1035-
// the user's `--package-manager` choice instead of falling back to
1036-
// pnpm (the hardcoded non-interactive/CI default in vite_install).
1037-
setPackageManager(fullPath, workspaceInfo.downloadPackageManager);
1038-
// Yarn Berry's default Plug'n'Play stores deps inside .yarn/cache/*.zip,
1039-
// which @oxlint/migrate can't resolve (ESM's fileURLToPath over a zip
1040-
// entry throws MODULE_NOT_FOUND). Force classic node_modules layout so
1041-
// the migration step can import the template's ESLint plugins.
1042-
if (workspaceInfo.packageManager === PackageManager.yarn) {
1043-
const yarnrcPath = path.join(fullPath, '.yarnrc.yml');
1044-
if (!fs.existsSync(yarnrcPath)) {
1045-
fs.writeFileSync(yarnrcPath, 'nodeLinker: node-modules\n');
1046-
}
1047-
}
1048-
updateCreateProgress('Installing dependencies');
1049-
installSummary = await runViteInstall(fullPath, options.interactive, installArgs, {
1050-
silent: compactOutput,
1051-
});
1052-
await migrateLintFmtTools(installSummary.status === 'installed');
1026+
await installAndMigrate(fullPath);
10531027
}
10541028
updateCreateProgress('Applying Vite+ project setup');
10551029
rewriteStandaloneProject(fullPath, workspaceInfo, undefined, compactOutput);

0 commit comments

Comments
 (0)