Skip to content
Merged
1 change: 1 addition & 0 deletions knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"confbox",
"consola",
"copy-paste",
"debug",
"defu",
"exsolve",
"fuse.js",
Expand Down
3 changes: 0 additions & 3 deletions packages/create-nuxt/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { provider } from 'std-env'

import init from '../../nuxi/src/commands/init'
import { setupInitCompletions } from '../../nuxi/src/completions-init'
import { setupGlobalConsole } from '../../nuxi/src/utils/console'
import { checkEngines } from '../../nuxi/src/utils/engines'
import { logger } from '../../nuxi/src/utils/logger'
import { description, name, version } from '../package.json'
Expand All @@ -22,8 +21,6 @@ const _main = defineCommand({
return
}

setupGlobalConsole({ dev: false })

// Check Node.js version and CLI updates in background
if (provider !== 'stackblitz') {
await checkEngines().catch(err => logger.error(err))
Expand Down
4 changes: 3 additions & 1 deletion packages/nuxi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@
},
"devDependencies": {
"@bomb.sh/tab": "^0.0.9",
"@clack/prompts": "^1.0.0-alpha.6",
"@clack/prompts": "1.0.0-alpha.6",
"@nuxt/kit": "^4.2.0",
"@nuxt/schema": "^4.2.0",
"@nuxt/test-utils": "^3.20.1",
"@types/copy-paste": "^2.1.0",
"@types/debug": "^4.1.12",
"@types/node": "^24.10.0",
"@types/semver": "^7.7.1",
"c12": "^3.3.1",
"citty": "^0.1.6",
"confbox": "^0.2.2",
"consola": "^3.4.2",
"copy-paste": "^2.2.0",
"debug": "^4.4.3",
"defu": "^6.1.4",
"exsolve": "^1.0.7",
"fuse.js": "^7.1.0",
Expand Down
26 changes: 15 additions & 11 deletions packages/nuxi/src/commands/add.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { existsSync, promises as fsp } from 'node:fs'
import process from 'node:process'

import { cancel, intro, outro } from '@clack/prompts'
import { defineCommand } from 'citty'
import { colors } from 'consola/utils'
import { dirname, extname, resolve } from 'pathe'

import { loadKit } from '../utils/kit'
import { logger } from '../utils/logger'
import { relativeToProcess } from '../utils/paths'
import { templates } from '../utils/templates'
import { cwdArgs, logLevelArgs } from './_shared'

Expand Down Expand Up @@ -39,15 +42,16 @@ export default defineCommand({
async run(ctx) {
const cwd = resolve(ctx.args.cwd)

intro(colors.cyan('Adding template...'))

const templateName = ctx.args.template

// Validate template name
if (!templateNames.includes(templateName)) {
logger.error(
`Template ${templateName} is not supported. Possible values: ${Object.keys(
templates,
).join(', ')}`,
)
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)
}

Expand All @@ -59,7 +63,7 @@ export default defineCommand({
: ctx.args.name

if (!name) {
logger.error('name argument is missing!')
cancel('name argument is missing!')
process.exit(1)
}

Expand All @@ -74,16 +78,15 @@ export default defineCommand({

// Ensure not overriding user code
if (!ctx.args.force && existsSync(res.path)) {
logger.error(
`File exists: ${res.path} . Use --force to override or use a different name.`,
)
logger.error(`File exists at ${colors.cyan(relativeToProcess(res.path))}.`)
logger.info(`Use ${colors.cyan('--force')} to override or use a different name.`)
process.exit(1)
}

// Ensure parent directory exists
const parentDir = dirname(res.path)
if (!existsSync(parentDir)) {
logger.info('Creating directory', parentDir)
logger.step(`Creating directory ${colors.cyan(relativeToProcess(parentDir))}.`)
if (templateName === 'page') {
logger.info('This enables vue-router functionality!')
}
Expand All @@ -92,6 +95,7 @@ export default defineCommand({

// Write file
await fsp.writeFile(res.path, `${res.contents.trim()}\n`)
logger.info(`πŸͺ„ Generated a new ${templateName} in ${res.path}`)
logger.success(`Created ${colors.cyan(relativeToProcess(res.path))}.`)
outro(`Generated a new ${colors.cyan(templateName)}!`)
},
})
28 changes: 20 additions & 8 deletions packages/nuxi/src/commands/analyze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import type { NuxtAnalyzeMeta } from '@nuxt/schema'
import { promises as fsp } from 'node:fs'
import process from 'node:process'

import { intro, note, outro, taskLog } from '@clack/prompts'
import { defineCommand } from 'citty'
import { colors } from 'consola/utils'
import { defu } from 'defu'
import { H3, lazyEventHandler } from 'h3-next'
import { join, resolve } from 'pathe'
Expand All @@ -13,6 +15,7 @@ import { overrideEnv } from '../utils/env'
import { clearDir } from '../utils/fs'
import { loadKit } from '../utils/kit'
import { logger } from '../utils/logger'
import { relativeToProcess } from '../utils/paths'
import { cwdArgs, dotEnvArgs, extendsArgs, legacyRootDirArgs, logLevelArgs } from './_shared'

const indexHtml = `
Expand Down Expand Up @@ -65,6 +68,8 @@ export default defineCommand({
const name = ctx.args.name || 'default'
const slug = name.trim().replace(/[^\w-]/g, '_')

intro(colors.cyan('Analyzing bundle size...'))

const startTime = Date.now()

const { loadNuxt, buildNuxt } = await loadKit(cwd)
Expand Down Expand Up @@ -105,8 +110,17 @@ export default defineCommand({
filename: join(analyzeDir, 'client.html'),
})

const tasklog = taskLog({
title: 'Building Nuxt with analysis enabled',
retainLog: false,
limit: 1,
})

tasklog.message('Clearing analyze directory...')
await clearDir(analyzeDir)
tasklog.message('Building Nuxt...')
await buildNuxt(nuxt)
tasklog.success('Build complete')

const endTime = Date.now()

Expand All @@ -121,14 +135,9 @@ export default defineCommand({
}

await nuxt.callHook('build:analyze:done', meta)
await fsp.writeFile(
join(analyzeDir, 'meta.json'),
JSON.stringify(meta, null, 2),
'utf-8',
)
await fsp.writeFile(join(analyzeDir, 'meta.json'), JSON.stringify(meta, null, 2), 'utf-8')

logger.info(`Analyze results are available at: \`${analyzeDir}\``)
logger.warn('Do not deploy analyze results! Use `nuxi build` before deploying.')
note(`${relativeToProcess(analyzeDir)}\n\nDo not deploy analyze results! Use ${colors.cyan('nuxt build')} before deploying.`, 'Build location')

if (ctx.args.serve !== false && !process.env.CI) {
const app = new H3()
Expand All @@ -139,13 +148,16 @@ export default defineCommand({
return () => new Response(contents, opts)
})

logger.info('Starting stats server...')
logger.step('Starting stats server...')

app.use('/client', serveFile(join(analyzeDir, 'client.html')))
app.use('/nitro', serveFile(join(analyzeDir, 'nitro.html')))
app.use(() => new Response(indexHtml, opts))

await serve(app).serve()
}
else {
outro('✨ Analysis build complete!')
}
},
})
20 changes: 12 additions & 8 deletions packages/nuxi/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import type { Nitro } from 'nitropack'

import process from 'node:process'

import { intro, outro } from '@clack/prompts'
import { defineCommand } from 'citty'
import { colors } from 'consola/utils'
import { relative, resolve } from 'pathe'

import { showVersions } from '../utils/banner'
Expand Down Expand Up @@ -38,6 +40,8 @@ export default defineCommand({

const cwd = resolve(ctx.args.cwd || ctx.args.rootDir)

intro(colors.cyan('Building Nuxt for production...'))

const kit = await loadKit(cwd)

await showVersions(cwd, kit)
Expand Down Expand Up @@ -67,7 +71,7 @@ export default defineCommand({
// Use ? for backward compatibility for Nuxt <= RC.10
nitro = kit.useNitro?.()
if (nitro) {
logger.info(`Building for Nitro preset: \`${nitro.options.preset}\``)
logger.info(`Nitro preset: ${colors.cyan(nitro.options.preset)}`)
}
}
catch {
Expand All @@ -79,24 +83,24 @@ export default defineCommand({
await kit.writeTypes(nuxt)

nuxt.hook('build:error', (err) => {
logger.error('Nuxt Build Error:', err)
logger.error(`Nuxt build error: ${err}`)
process.exit(1)
})

await kit.buildNuxt(nuxt)

if (ctx.args.prerender) {
if (!nuxt.options.ssr) {
logger.warn(
'HTML content not prerendered because `ssr: false` was set. You can read more in `https://nuxt.com/docs/getting-started/deployment#static-hosting`.',
)
logger.warn(`HTML content not prerendered because ${colors.cyan('ssr: false')} was set.`)
logger.info(`You can read more in ${colors.cyan('https://nuxt.com/docs/getting-started/deployment#static-hosting')}.`)
}
// TODO: revisit later if/when nuxt build --prerender will output hybrid
const dir = nitro?.options.output.publicDir
const publicDir = dir ? relative(process.cwd(), dir) : '.output/public'
logger.success(
`You can now deploy \`${publicDir}\` to any static hosting!`,
)
outro(`✨ You can now deploy ${colors.cyan(publicDir)} to any static hosting!`)
}
else {
outro('✨ Build complete!')
}
},
})
3 changes: 3 additions & 0 deletions packages/nuxi/src/commands/cleanup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineCommand } from 'citty'
import { resolve } from 'pathe'

import { loadKit } from '../utils/kit'
import { logger } from '../utils/logger'
import { cleanupNuxtDirs } from '../utils/nuxt'
import { cwdArgs, legacyRootDirArgs } from './_shared'

Expand All @@ -19,5 +20,7 @@ export default defineCommand({
const { loadNuxtConfig } = await loadKit(cwd)
const nuxtOptions = await loadNuxtConfig({ cwd, overrides: { dev: true } })
await cleanupNuxtDirs(nuxtOptions.rootDir, nuxtOptions.buildDir)

logger.success('Cleanup complete!')
},
})
9 changes: 5 additions & 4 deletions packages/nuxi/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { NuxtDevContext } from '../dev/utils'
import process from 'node:process'

import { defineCommand } from 'citty'
import { colors } from 'consola/utils'
import { getArgs as getListhenArgs } from 'listhen/cli'
import { resolve } from 'pathe'
import { satisfies } from 'semver'
Expand All @@ -12,7 +13,7 @@ import { isBun, isTest } from 'std-env'
import { initialize } from '../dev'
import { ForkPool } from '../dev/pool'
import { overrideEnv } from '../utils/env'
import { logger } from '../utils/logger'
import { debug, logger } from '../utils/logger'
import { cwdArgs, dotEnvArgs, envNameArgs, extendsArgs, legacyRootDirArgs, logLevelArgs } from './_shared'

const startTime: number | undefined = Date.now()
Expand Down Expand Up @@ -106,7 +107,7 @@ const command = defineCommand({
onReady((_address) => {
pool.startWarming()
if (startTime) {
logger.debug(`Dev server ready for connections in ${Date.now() - startTime}ms`)
debug(`Dev server ready for connections in ${Date.now() - startTime}ms`)
}
})

Expand All @@ -124,15 +125,15 @@ const command = defineCommand({
// Handle IPC messages from the fork
if (message.type === 'nuxt:internal:dev:ready') {
if (startTime) {
logger.debug(`Dev server ready for connections in ${Date.now() - startTime}ms`)
debug(`Dev server ready for connections in ${Date.now() - startTime}ms`)
}
}
else if (message.type === 'nuxt:internal:dev:restart') {
// Fork is requesting another restart
void restartWithFork()
}
else if (message.type === 'nuxt:internal:dev:rejection') {
logger.info(`Restarting Nuxt due to error: \`${message.message}\``)
logger.info(`Restarting Nuxt due to error: ${colors.cyan(message.message)}`)
void restartWithFork()
}
})
Expand Down
3 changes: 2 additions & 1 deletion packages/nuxi/src/commands/devtools.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import process from 'node:process'

import { defineCommand } from 'citty'
import { colors } from 'consola/utils'
import { resolve } from 'pathe'
import { x } from 'tinyexec'

Expand All @@ -25,7 +26,7 @@ export default defineCommand({
const cwd = resolve(ctx.args.cwd || ctx.args.rootDir)

if (!['enable', 'disable'].includes(ctx.args.command)) {
logger.error(`Unknown command \`${ctx.args.command}\`.`)
logger.error(`Unknown command ${colors.cyan(ctx.args.command)}.`)
process.exit(1)
}

Expand Down
Loading