From 55ce0982f5d0e3fe3434ac5352a7121b967b2541 Mon Sep 17 00:00:00 2001 From: Hugo Richard Date: Tue, 13 May 2025 14:10:49 +0200 Subject: [PATCH 1/5] feat: skip already handled modules by `@nuxt/ui` --- packages/nuxi/src/commands/init.ts | 45 ++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts index c020f07a0..837fff333 100644 --- a/packages/nuxi/src/commands/init.ts +++ b/packages/nuxi/src/commands/init.ts @@ -1,3 +1,4 @@ +import type { SelectPromptOptions } from 'consola' import type { DownloadTemplateResult } from 'giget' import type { PackageManagerName } from 'nypm' @@ -168,13 +169,31 @@ export default defineCommand({ process.exit(1) } + function detectCurrentPackageManager() { + const userAgent = process.env.npm_config_user_agent + if (!userAgent) { + return + } + const [name] = userAgent.split('/') + if (packageManagerOptions.includes(name as PackageManagerName)) { + return name as PackageManagerName + } + } + + const currentPackageManager = detectCurrentPackageManager() // Resolve package manager const packageManagerArg = ctx.args.packageManager as PackageManagerName + const packageManagerSelectOptions = packageManagerOptions.map(pm => ({ + label: pm, + value: pm, + hint: currentPackageManager === pm ? 'current' : undefined, + } satisfies SelectPromptOptions['options'][number])) const selectedPackageManager = packageManagerOptions.includes(packageManagerArg) ? packageManagerArg : await logger.prompt('Which package manager would you like to use?', { type: 'select', - options: packageManagerOptions, + options: packageManagerSelectOptions, + initial: currentPackageManager, cancel: 'reject', }).catch(() => process.exit(1)) @@ -264,8 +283,28 @@ export default defineCommand({ process.exit(1) } - if (selectedOfficialModules.length > 0) { - modulesToAdd.push(...(selectedOfficialModules as unknown as string[])) + if (selectedOfficialModules.length) { + const modules = selectedOfficialModules as unknown as string[] + if (!modules.includes('@nuxt/ui')) { + modulesToAdd.push(...modules) + } + else { + const implicit = new Set(['@nuxt/fonts', '@nuxt/icon']) + const toInstall = [] + const skipped = [] + for (const mod of modules) { + if (mod === '@nuxt/ui' || !implicit.has(mod)) { + toInstall.push(mod) + } + else { + skipped.push(mod) + } + } + if (skipped.length) { + logger.info(`The following modules are already included in @nuxt/ui and will not be installed separately: ${skipped.join(', ')}`) + } + modulesToAdd.push(...toInstall) + } } } From 72a9e2fc94c94b48f0fef416632ccbc03af9f57c Mon Sep 17 00:00:00 2001 From: HugoRCD Date: Tue, 13 May 2025 14:30:20 +0200 Subject: [PATCH 2/5] up --- packages/nuxi/src/commands/init.ts | 65 +++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts index 837fff333..885d836b7 100644 --- a/packages/nuxi/src/commands/init.ts +++ b/packages/nuxi/src/commands/init.ts @@ -33,6 +33,43 @@ const pms: Record = { // this is for type safety to prompt updating code in nuxi when nypm adds a new package manager const packageManagerOptions = Object.keys(pms) as PackageManagerName[] +async function getModuleDependencies(moduleName: string) { + try { + const response = await $fetch(`https://registry.npmjs.org/${moduleName}/latest`) + const dependencies = response.dependencies || {} + return Object.keys(dependencies) + } + catch (err) { + logger.warn(`Could not get dependencies for ${moduleName}: ${err}`) + return [] + } +} + +function filterModules(modules: string[], allDependencies: Record) { + const result = { + toInstall: [] as string[], + skipped: [] as string[], + } + + for (const module of modules) { + const isDependency = modules.some((otherModule) => { + if (otherModule === module) + return false + const deps = allDependencies[otherModule] || [] + return deps.includes(module) + }) + + if (isDependency) { + result.skipped.push(module) + } + else { + result.toInstall.push(module) + } + } + + return result +} + export default defineCommand({ meta: { name: 'init', @@ -285,26 +322,18 @@ export default defineCommand({ if (selectedOfficialModules.length) { const modules = selectedOfficialModules as unknown as string[] - if (!modules.includes('@nuxt/ui')) { - modulesToAdd.push(...modules) + + const allDependencies: Record = {} + for (const module of modules) { + allDependencies[module] = await getModuleDependencies(module) } - else { - const implicit = new Set(['@nuxt/fonts', '@nuxt/icon']) - const toInstall = [] - const skipped = [] - for (const mod of modules) { - if (mod === '@nuxt/ui' || !implicit.has(mod)) { - toInstall.push(mod) - } - else { - skipped.push(mod) - } - } - if (skipped.length) { - logger.info(`The following modules are already included in @nuxt/ui and will not be installed separately: ${skipped.join(', ')}`) - } - modulesToAdd.push(...toInstall) + + const { toInstall, skipped } = filterModules(modules, allDependencies) + + if (skipped.length) { + logger.info(`The following modules are already included as dependencies and will not be installed: ${skipped.join(', ')}`) } + modulesToAdd.push(...toInstall) } } From e666fba65c16eb801e10ea711613ff00cb3caa52 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 10 Jun 2025 11:33:35 +0100 Subject: [PATCH 3/5] perf: fetch module dependencies in parallel --- packages/nuxi/src/commands/init.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts index bec1a50a4..a1f16ea73 100644 --- a/packages/nuxi/src/commands/init.ts +++ b/packages/nuxi/src/commands/init.ts @@ -336,10 +336,11 @@ export default defineCommand({ if (selectedOfficialModules.length > 0) { const modules = selectedOfficialModules as unknown as string[] - const allDependencies: Record = {} - for (const module of modules) { - allDependencies[module] = await getModuleDependencies(module) - } + const allDependencies = Object.fromEntries( + await Promise.all(modules.map(async module => + [module, await getModuleDependencies(module)] as const, + )), + ) const { toInstall, skipped } = filterModules(modules, allDependencies) From 0e28b7935fde983586aaed67345f45af0e6be201 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 10 Jun 2025 11:34:17 +0100 Subject: [PATCH 4/5] fix: highlight modules in cyan --- packages/nuxi/src/commands/init.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts index a1f16ea73..7dcda7afe 100644 --- a/packages/nuxi/src/commands/init.ts +++ b/packages/nuxi/src/commands/init.ts @@ -345,7 +345,7 @@ export default defineCommand({ const { toInstall, skipped } = filterModules(modules, allDependencies) if (skipped.length) { - logger.info(`The following modules are already included as dependencies and will not be installed: ${skipped.join(', ')}`) + logger.info(`The following modules are already included as dependencies and will not be installed: ${skipped.map(m => colors.cyan(m)).join(', ')}`) } modulesToAdd.push(...toInstall) } From 10fa58e7ac22092b9a4780e0b0889fde82bf1718 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 10 Jun 2025 11:35:05 +0100 Subject: [PATCH 5/5] chore: update wording --- packages/nuxi/src/commands/init.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts index 7dcda7afe..4d1cbf74d 100644 --- a/packages/nuxi/src/commands/init.ts +++ b/packages/nuxi/src/commands/init.ts @@ -345,7 +345,7 @@ export default defineCommand({ const { toInstall, skipped } = filterModules(modules, allDependencies) if (skipped.length) { - logger.info(`The following modules are already included as dependencies and will not be installed: ${skipped.map(m => colors.cyan(m)).join(', ')}`) + logger.info(`The following modules are already included as dependencies of another module and will not be installed: ${skipped.map(m => colors.cyan(m)).join(', ')}`) } modulesToAdd.push(...toInstall) }