Skip to content

Commit b9a4cc6

Browse files
authored
feat(create-vite): add hint for external CLIs (#19157)
1 parent a6b9587 commit b9a4cc6

File tree

1 file changed

+50
-29
lines changed

1 file changed

+50
-29
lines changed

packages/create-vite/src/index.ts

+50-29
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const {
1010
blue,
1111
blueBright,
1212
cyan,
13+
gray,
1314
green,
1415
greenBright,
1516
magenta,
@@ -311,6 +312,7 @@ async function init() {
311312
}
312313

313314
let targetDir = argTargetDir || defaultTargetDir
315+
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
314316
const getProjectName = () => path.basename(path.resolve(targetDir))
315317

316318
let result: prompts.Answers<
@@ -402,9 +404,16 @@ async function init() {
402404
choices: (framework: Framework) =>
403405
framework.variants.map((variant) => {
404406
const variantColor = variant.color
407+
const command = variant.customCommand
408+
? getFullCustomCommand(variant.customCommand, pkgInfo).replace(
409+
/ TARGET_DIR$/,
410+
'',
411+
)
412+
: undefined
405413
return {
406414
title: variantColor(variant.display || variant.name),
407415
value: variant.name,
416+
description: command ? gray(command) : undefined,
408417
}
409418
}),
410419
},
@@ -439,40 +448,13 @@ async function init() {
439448
template = template.replace('-swc', '')
440449
}
441450

442-
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
443451
const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
444-
const isYarn1 = pkgManager === 'yarn' && pkgInfo?.version.startsWith('1.')
445452

446453
const { customCommand } =
447454
FRAMEWORKS.flatMap((f) => f.variants).find((v) => v.name === template) ?? {}
448455

449456
if (customCommand) {
450-
const fullCustomCommand = customCommand
451-
.replace(/^npm create /, () => {
452-
// `bun create` uses it's own set of templates,
453-
// the closest alternative is using `bun x` directly on the package
454-
if (pkgManager === 'bun') {
455-
return 'bun x create-'
456-
}
457-
return `${pkgManager} create `
458-
})
459-
// Only Yarn 1.x doesn't support `@version` in the `create` command
460-
.replace('@latest', () => (isYarn1 ? '' : '@latest'))
461-
.replace(/^npm exec/, () => {
462-
// Prefer `pnpm dlx`, `yarn dlx`, or `bun x`
463-
if (pkgManager === 'pnpm') {
464-
return 'pnpm dlx'
465-
}
466-
if (pkgManager === 'yarn' && !isYarn1) {
467-
return 'yarn dlx'
468-
}
469-
if (pkgManager === 'bun') {
470-
return 'bun x'
471-
}
472-
// Use `npm exec` in all other cases,
473-
// including Yarn 1.x and other custom npm clients.
474-
return 'npm exec'
475-
})
457+
const fullCustomCommand = getFullCustomCommand(customCommand, pkgInfo)
476458

477459
const [command, ...args] = fullCustomCommand.split(' ')
478460
// we replace TARGET_DIR here because targetDir may include a space
@@ -595,7 +577,12 @@ function emptyDir(dir: string) {
595577
}
596578
}
597579

598-
function pkgFromUserAgent(userAgent: string | undefined) {
580+
interface PkgInfo {
581+
name: string
582+
version: string
583+
}
584+
585+
function pkgFromUserAgent(userAgent: string | undefined): PkgInfo | undefined {
599586
if (!userAgent) return undefined
600587
const pkgSpec = userAgent.split(' ')[0]
601588
const pkgSpecArr = pkgSpec.split('/')
@@ -625,6 +612,40 @@ function editFile(file: string, callback: (content: string) => string) {
625612
fs.writeFileSync(file, callback(content), 'utf-8')
626613
}
627614

615+
function getFullCustomCommand(customCommand: string, pkgInfo?: PkgInfo) {
616+
const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
617+
const isYarn1 = pkgManager === 'yarn' && pkgInfo?.version.startsWith('1.')
618+
619+
return (
620+
customCommand
621+
.replace(/^npm create /, () => {
622+
// `bun create` uses it's own set of templates,
623+
// the closest alternative is using `bun x` directly on the package
624+
if (pkgManager === 'bun') {
625+
return 'bun x create-'
626+
}
627+
return `${pkgManager} create `
628+
})
629+
// Only Yarn 1.x doesn't support `@version` in the `create` command
630+
.replace('@latest', () => (isYarn1 ? '' : '@latest'))
631+
.replace(/^npm exec/, () => {
632+
// Prefer `pnpm dlx`, `yarn dlx`, or `bun x`
633+
if (pkgManager === 'pnpm') {
634+
return 'pnpm dlx'
635+
}
636+
if (pkgManager === 'yarn' && !isYarn1) {
637+
return 'yarn dlx'
638+
}
639+
if (pkgManager === 'bun') {
640+
return 'bun x'
641+
}
642+
// Use `npm exec` in all other cases,
643+
// including Yarn 1.x and other custom npm clients.
644+
return 'npm exec'
645+
})
646+
)
647+
}
648+
628649
init().catch((e) => {
629650
console.error(e)
630651
})

0 commit comments

Comments
 (0)