diff --git a/packages/nuxi/src/commands/add-template.ts b/packages/nuxi/src/commands/add-template.ts index 7f20261f..7f322b75 100644 --- a/packages/nuxi/src/commands/add-template.ts +++ b/packages/nuxi/src/commands/add-template.ts @@ -1,5 +1,3 @@ -import type { TemplateName } from '../utils/templates/names' - import { existsSync, promises as fsp } from 'node:fs' import process from 'node:process' @@ -15,6 +13,28 @@ import { templates } from '../utils/templates/index' import { templateNames } from '../utils/templates/names' import { cwdArgs, logLevelArgs } from './_shared' +async function loadNuxtConfigWithModules(cwd: string) { + const kit = await loadKit(cwd) + const nuxt = await kit.loadNuxt({ cwd, ready: false }).catch(() => null) + + if (!nuxt) { + return { config: await kit.loadNuxtConfig({ cwd }) } + } + + try { + await nuxt.ready() + await nuxt.hooks.callHook('templates:extend', templates) + } + catch { + // module setup may fail; fall through with built-in templates only + } + finally { + await nuxt.close() + } + + return { config: nuxt.options } +} + export default defineCommand({ meta: { name: 'add-template', @@ -45,16 +65,7 @@ export default defineCommand({ intro(colors.cyan('Adding template...')) - const templateName = ctx.args.template as TemplateName - - // Validate template name - if (!templateNames.includes(templateName)) { - const templateNames = Object.keys(templates).map(name => colors.cyan(name)) - const lastTemplateName = templateNames.pop() - logger.error(`Template ${colors.cyan(templateName)} is not supported.`) - logger.info(`Possible values are ${templateNames.join(', ')} or ${lastTemplateName}.`) - process.exit(1) - } + const templateName = ctx.args.template // Validate options const ext = extname(ctx.args.name) @@ -69,12 +80,19 @@ export default defineCommand({ } // Load config in order to respect srcDir - const kit = await loadKit(cwd) - const config = await kit.loadNuxtConfig({ cwd }) + const { config } = await loadNuxtConfigWithModules(cwd) - // Resolve template - const template = templates[templateName as keyof typeof templates] + // Validate template name + const template = templates[templateName] + if (!template) { + const templateNames = Object.keys(templates).map(name => colors.cyan(name)) + const lastTemplateName = templateNames.pop() + logger.error(`Template ${colors.cyan(templateName)} is not supported.`) + logger.info(`Possible values are ${templateNames.join(', ')} or ${lastTemplateName}.`) + process.exit(1) + } + // Resolve template const res = template({ name, args: ctx.args, nuxtOptions: config }) // Ensure not overriding user code diff --git a/packages/nuxi/src/main.ts b/packages/nuxi/src/main.ts index 3e630a9e..528dece6 100644 --- a/packages/nuxi/src/main.ts +++ b/packages/nuxi/src/main.ts @@ -1,5 +1,4 @@ import type { CommandDef } from 'citty' -import type { TemplateName } from './utils/templates/names' import nodeCrypto from 'node:crypto' import { builtinModules, createRequire } from 'node:module' @@ -17,8 +16,6 @@ import { runCommand } from './run' import { setupGlobalConsole } from './utils/console' import { checkEngines } from './utils/engines' import { debug, logger } from './utils/logger' -import { templateNames } from './utils/templates/names' - // globalThis.crypto support for Node.js 18 if (!globalThis.crypto) { globalThis.crypto = nodeCrypto.webcrypto as unknown as Crypto @@ -67,7 +64,7 @@ const _main = defineCommand({ await backgroundTasks } - if (command === 'add' && ctx.rawArgs[1] && templateNames.includes(ctx.rawArgs[1] as TemplateName)) { + if (command === 'add' && ctx.rawArgs[1]) { logger.warn(`${colors.yellow('Deprecated:')} Using ${colors.cyan('nuxt add