mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-31 07:40:33 +00:00
chore: remove legacy cli from codebase
This commit is contained in:
parent
588e09cf10
commit
acc76ed2df
@ -1,250 +0,0 @@
|
|||||||
|
|
||||||
import path from 'path'
|
|
||||||
import consola from 'consola'
|
|
||||||
import minimist, { Opts as MinimistOptions, ParsedArgs } from 'minimist'
|
|
||||||
import Hookable from 'hookable'
|
|
||||||
|
|
||||||
import { Builder } from 'src/builder'
|
|
||||||
import { CliConfiguration } from 'src/config/options'
|
|
||||||
import { Nuxt } from 'src/core'
|
|
||||||
|
|
||||||
import { name, version } from '../../package.json'
|
|
||||||
|
|
||||||
import { forceExit } from './utils'
|
|
||||||
import { loadNuxtConfig } from './utils/config'
|
|
||||||
import { indent, foldLines, colorize } from './utils/formatting'
|
|
||||||
import { startSpaces, optionSpaces, forceExitTimeout } from './utils/constants'
|
|
||||||
|
|
||||||
export interface Command {
|
|
||||||
name: string
|
|
||||||
usage: string
|
|
||||||
description: string
|
|
||||||
options?: Record<string, any>
|
|
||||||
run?: (nuxt: NuxtCommand) => any | Promise<any>
|
|
||||||
}
|
|
||||||
|
|
||||||
type Hooks = Parameters<Hookable['addHooks']>[0]
|
|
||||||
|
|
||||||
export default class NuxtCommand extends Hookable {
|
|
||||||
_argv: string[]
|
|
||||||
_parsedArgv: null | ParsedArgs
|
|
||||||
_lockRelease?: () => Promise<any>
|
|
||||||
|
|
||||||
cmd: Command & { options: Command['options'] }
|
|
||||||
|
|
||||||
constructor (cmd: Command = { name: '', usage: '', description: '' }, argv = process.argv.slice(2), hooks: Hooks = {}) {
|
|
||||||
super(consola)
|
|
||||||
this.addHooks(hooks)
|
|
||||||
|
|
||||||
if (!cmd.options) {
|
|
||||||
cmd.options = {}
|
|
||||||
}
|
|
||||||
this.cmd = cmd as Command & { options: Command['options'] }
|
|
||||||
|
|
||||||
this._argv = Array.from(argv)
|
|
||||||
this._parsedArgv = null // Lazy evaluate
|
|
||||||
}
|
|
||||||
|
|
||||||
static run (cmd: Command, argv: NodeJS.Process['argv'], hooks: Hooks) {
|
|
||||||
return NuxtCommand.from(cmd, argv, hooks).run()
|
|
||||||
}
|
|
||||||
|
|
||||||
static from (cmd: Command, argv: NodeJS.Process['argv'], hooks: Hooks) {
|
|
||||||
if (cmd instanceof NuxtCommand) {
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
return new NuxtCommand(cmd, argv, hooks)
|
|
||||||
}
|
|
||||||
|
|
||||||
async run () {
|
|
||||||
await this.callHook('run:before', {
|
|
||||||
argv: this._argv,
|
|
||||||
cmd: this.cmd,
|
|
||||||
rootDir: path.resolve(this.argv._[0] || '.')
|
|
||||||
})
|
|
||||||
|
|
||||||
if (this.argv.help) {
|
|
||||||
this.showHelp()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.argv.version) {
|
|
||||||
this.showVersion()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(this.cmd.run instanceof Function)) {
|
|
||||||
throw new TypeError('Invalid command! Commands should at least implement run() function.')
|
|
||||||
}
|
|
||||||
|
|
||||||
let cmdError: any
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.cmd.run(this)
|
|
||||||
} catch (e) {
|
|
||||||
cmdError = e
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.argv.lock) {
|
|
||||||
await this.releaseLock()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.argv['force-exit']) {
|
|
||||||
const forceExitByUser = this.isUserSuppliedArg('force-exit')
|
|
||||||
if (cmdError) {
|
|
||||||
consola.fatal(cmdError)
|
|
||||||
}
|
|
||||||
forceExit(this.cmd.name, forceExitByUser ? false : forceExitTimeout)
|
|
||||||
if (forceExitByUser) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmdError) {
|
|
||||||
throw cmdError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showVersion () {
|
|
||||||
process.stdout.write(`${name} v${version}\n`)
|
|
||||||
}
|
|
||||||
|
|
||||||
showHelp () {
|
|
||||||
process.stdout.write(this._getHelp())
|
|
||||||
}
|
|
||||||
|
|
||||||
get argv () {
|
|
||||||
if (!this._parsedArgv) {
|
|
||||||
const minimistOptions = this._getMinimistOptions()
|
|
||||||
this._parsedArgv = minimist(this._argv, minimistOptions)
|
|
||||||
}
|
|
||||||
return this._parsedArgv
|
|
||||||
}
|
|
||||||
|
|
||||||
async getNuxtConfig (extraOptions: Partial<CliConfiguration> = {}) {
|
|
||||||
// Flag to indicate nuxt is running with CLI (not programmatic)
|
|
||||||
extraOptions._cli = true
|
|
||||||
|
|
||||||
const context = {
|
|
||||||
command: this.cmd.name,
|
|
||||||
dev: !!extraOptions.dev
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = await loadNuxtConfig(this.argv, context)
|
|
||||||
const options = Object.assign(config, extraOptions)
|
|
||||||
|
|
||||||
for (const name of Object.keys(this.cmd.options)) {
|
|
||||||
this.cmd.options[name].prepare && this.cmd.options[name].prepare(this, options, this.argv)
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.callHook('config', options)
|
|
||||||
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
||||||
async getNuxt (options: CliConfiguration) {
|
|
||||||
const nuxt = new Nuxt(options)
|
|
||||||
await nuxt.ready()
|
|
||||||
|
|
||||||
return nuxt
|
|
||||||
}
|
|
||||||
|
|
||||||
getBuilder (nuxt: Nuxt) {
|
|
||||||
return new Builder(nuxt)
|
|
||||||
}
|
|
||||||
|
|
||||||
async setLock (lockRelease?: () => Promise<any>) {
|
|
||||||
if (lockRelease) {
|
|
||||||
if (this._lockRelease) {
|
|
||||||
consola.warn(`A previous unreleased lock was found, this shouldn't happen and is probably an error in 'nuxt ${this.cmd.name}' command. The lock will be removed but be aware of potential strange results`)
|
|
||||||
|
|
||||||
await this.releaseLock()
|
|
||||||
this._lockRelease = lockRelease
|
|
||||||
} else {
|
|
||||||
this._lockRelease = lockRelease
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async releaseLock () {
|
|
||||||
if (this._lockRelease) {
|
|
||||||
await this._lockRelease()
|
|
||||||
this._lockRelease = undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isUserSuppliedArg (option: string) {
|
|
||||||
return this._argv.includes(`--${option}`) || this._argv.includes(`--no-${option}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
_getDefaultOptionValue<T, Option extends { default: ((cmd: Command) => T) | T }>(option: Option) {
|
|
||||||
return option.default instanceof Function ? option.default(this.cmd) : option.default
|
|
||||||
}
|
|
||||||
|
|
||||||
_getMinimistOptions () {
|
|
||||||
const minimistOptions: MinimistOptions = {
|
|
||||||
alias: {},
|
|
||||||
boolean: [],
|
|
||||||
string: [],
|
|
||||||
default: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const name of Object.keys(this.cmd.options)) {
|
|
||||||
const option = this.cmd.options[name]
|
|
||||||
|
|
||||||
if (option.alias) {
|
|
||||||
minimistOptions.alias[option.alias] = name
|
|
||||||
}
|
|
||||||
if (option.type) {
|
|
||||||
minimistOptions[option.type].push(option.alias || name)
|
|
||||||
}
|
|
||||||
if (option.default) {
|
|
||||||
minimistOptions.default[option.alias || name] = this._getDefaultOptionValue(option)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return minimistOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
_getHelp () {
|
|
||||||
const options: [string, string][] = []
|
|
||||||
let maxOptionLength = 0
|
|
||||||
|
|
||||||
for (const name in this.cmd.options) {
|
|
||||||
const option = this.cmd.options[name]
|
|
||||||
|
|
||||||
let optionHelp = '--'
|
|
||||||
optionHelp += option.type === 'boolean' && this._getDefaultOptionValue(option) ? 'no-' : ''
|
|
||||||
optionHelp += name
|
|
||||||
if (option.alias) {
|
|
||||||
optionHelp += `, -${option.alias}`
|
|
||||||
}
|
|
||||||
|
|
||||||
maxOptionLength = Math.max(maxOptionLength, optionHelp.length)
|
|
||||||
options.push([optionHelp, option.description])
|
|
||||||
}
|
|
||||||
|
|
||||||
const _opts = options.map(([option, description]) => {
|
|
||||||
const i = indent(maxOptionLength + optionSpaces - option.length)
|
|
||||||
return foldLines(
|
|
||||||
option + i + description,
|
|
||||||
startSpaces + maxOptionLength + optionSpaces * 2,
|
|
||||||
startSpaces + optionSpaces
|
|
||||||
)
|
|
||||||
}).join('\n')
|
|
||||||
|
|
||||||
const usage = foldLines(`Usage: nuxt ${this.cmd.usage} [options]`, startSpaces)
|
|
||||||
const description = foldLines(this.cmd.description, startSpaces)
|
|
||||||
const opts = foldLines('Options:', startSpaces) + '\n\n' + _opts
|
|
||||||
|
|
||||||
let helpText = colorize(`${usage}\n\n`)
|
|
||||||
if (this.cmd.description) {
|
|
||||||
helpText += colorize(`${description}\n\n`)
|
|
||||||
}
|
|
||||||
if (options.length) {
|
|
||||||
helpText += colorize(`${opts}\n\n`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return helpText
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,94 +0,0 @@
|
|||||||
import consola from 'consola'
|
|
||||||
import { MODES, TARGETS } from 'src/utils'
|
|
||||||
import type { ParsedArgs } from 'minimist'
|
|
||||||
import NuxtCommand from '../command'
|
|
||||||
import { common, locking } from '../options'
|
|
||||||
import { createLock } from '../utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'build',
|
|
||||||
description: 'Compiles the application for production deployment',
|
|
||||||
usage: 'build <dir>',
|
|
||||||
options: {
|
|
||||||
...common,
|
|
||||||
...locking,
|
|
||||||
analyze: {
|
|
||||||
alias: 'a',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Launch webpack-bundle-analyzer to optimize your bundles',
|
|
||||||
prepare (_cmd: NuxtCommand, options, argv: ParsedArgs) {
|
|
||||||
// Analyze option
|
|
||||||
options.build = options.build || {}
|
|
||||||
if (argv.analyze && typeof options.build.analyze !== 'object') {
|
|
||||||
options.build.analyze = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
devtools: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Enable Vue devtools',
|
|
||||||
prepare (_cmd: NuxtCommand, options, argv: ParsedArgs) {
|
|
||||||
options.vue = options.vue || {}
|
|
||||||
options.vue.config = options.vue.config || {}
|
|
||||||
if (argv.devtools) {
|
|
||||||
options.vue.config.devtools = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
generate: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: true,
|
|
||||||
description: 'Don\'t generate static version for SPA mode (useful for nuxt start)'
|
|
||||||
},
|
|
||||||
quiet: {
|
|
||||||
alias: 'q',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Disable output except for errors',
|
|
||||||
prepare (_cmd: NuxtCommand, options, argv: ParsedArgs) {
|
|
||||||
// Silence output when using --quiet
|
|
||||||
options.build = options.build || {}
|
|
||||||
if (argv.quiet) {
|
|
||||||
options.build.quiet = Boolean(argv.quiet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
standalone: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Bundle all server dependencies (useful for nuxt-start)',
|
|
||||||
prepare (_cmd: NuxtCommand, options, argv: ParsedArgs) {
|
|
||||||
if (argv.standalone) {
|
|
||||||
options.build.standalone = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
const config = await cmd.getNuxtConfig({ dev: false, server: false, _build: true })
|
|
||||||
config.server = (config.mode === MODES.spa || config.ssr === false) && cmd.argv.generate !== false
|
|
||||||
const nuxt = await cmd.getNuxt(config)
|
|
||||||
|
|
||||||
if (cmd.argv.lock) {
|
|
||||||
await cmd.setLock(await createLock({
|
|
||||||
id: 'build',
|
|
||||||
dir: nuxt.options.buildDir,
|
|
||||||
root: config.rootDir
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: remove if in Nuxt 3
|
|
||||||
if (nuxt.options.mode === MODES.spa && nuxt.options.target === TARGETS.server && cmd.argv.generate !== false) {
|
|
||||||
// Build + Generate for static deployment
|
|
||||||
const generator = await cmd.getGenerator(nuxt)
|
|
||||||
await generator.generate({ build: true })
|
|
||||||
} else {
|
|
||||||
// Build only
|
|
||||||
const builder = await cmd.getBuilder(nuxt)
|
|
||||||
await builder.build()
|
|
||||||
|
|
||||||
const nextCommand = nuxt.options.target === TARGETS.static ? 'nuxt export' : 'nuxt start'
|
|
||||||
consola.info('Ready to run `' + (nextCommand) + '`')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
import consola from 'consola'
|
|
||||||
import chalk from 'chalk'
|
|
||||||
import opener from 'opener'
|
|
||||||
import type { ParsedArgs } from 'minimist'
|
|
||||||
|
|
||||||
import { Nuxt } from 'src/core'
|
|
||||||
|
|
||||||
import type NuxtCommand from '../command'
|
|
||||||
import { common, server } from '../options'
|
|
||||||
import { eventsMapping, formatPath } from '../utils'
|
|
||||||
import { showBanner } from '../utils/banner'
|
|
||||||
import { showMemoryUsage } from '../utils/memory'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'dev',
|
|
||||||
description: 'Start the application in development mode (e.g. hot-code reloading, error reporting)',
|
|
||||||
usage: 'dev <dir>',
|
|
||||||
options: {
|
|
||||||
...common,
|
|
||||||
...server,
|
|
||||||
open: {
|
|
||||||
alias: 'o',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Opens the server listeners url in the default browser'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
const { argv } = cmd
|
|
||||||
|
|
||||||
await this.startDev(cmd, argv, argv.open)
|
|
||||||
},
|
|
||||||
|
|
||||||
async startDev (cmd: NuxtCommand, argv) {
|
|
||||||
let nuxt
|
|
||||||
try {
|
|
||||||
nuxt = await this._listenDev(cmd, argv)
|
|
||||||
} catch (error) {
|
|
||||||
consola.fatal(error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this._buildDev(cmd, argv, nuxt)
|
|
||||||
} catch (error) {
|
|
||||||
await nuxt.callHook('cli:buildError', error)
|
|
||||||
consola.error(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nuxt
|
|
||||||
},
|
|
||||||
|
|
||||||
async _listenDev (cmd: NuxtCommand, argv: ParsedArgs) {
|
|
||||||
const config = await cmd.getNuxtConfig({ dev: true, _build: true })
|
|
||||||
const nuxt = await cmd.getNuxt(config)
|
|
||||||
|
|
||||||
// Setup hooks
|
|
||||||
nuxt.hook('watch:restart', payload => this.onWatchRestart(payload, { nuxt, cmd, argv }))
|
|
||||||
nuxt.hook('bundler:change', changedFileName => this.onBundlerChange(changedFileName))
|
|
||||||
|
|
||||||
// Wait for nuxt to be ready
|
|
||||||
await nuxt.ready()
|
|
||||||
|
|
||||||
// Start listening
|
|
||||||
await nuxt.server.listen()
|
|
||||||
|
|
||||||
// Show banner when listening
|
|
||||||
showBanner(nuxt, false)
|
|
||||||
|
|
||||||
// Opens the server listeners url in the default browser (only once)
|
|
||||||
if (argv.open) {
|
|
||||||
argv.open = false
|
|
||||||
const openerPromises = nuxt.server.listeners.map(listener => opener(listener.url))
|
|
||||||
await Promise.all(openerPromises)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return instance
|
|
||||||
return nuxt
|
|
||||||
},
|
|
||||||
|
|
||||||
async _buildDev (cmd: NuxtCommand, _argv: ParsedArgs, nuxt: Nuxt) {
|
|
||||||
// Create builder instance
|
|
||||||
const builder = await cmd.getBuilder(nuxt)
|
|
||||||
|
|
||||||
// Start Build
|
|
||||||
await builder.build()
|
|
||||||
|
|
||||||
// Print memory usage
|
|
||||||
showMemoryUsage()
|
|
||||||
|
|
||||||
// Display server urls after the build
|
|
||||||
for (const listener of nuxt.server.listeners) {
|
|
||||||
consola.info(chalk.bold('Listening on: ') + listener.url)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return instance
|
|
||||||
return nuxt
|
|
||||||
},
|
|
||||||
|
|
||||||
logChanged ({ event, path }: { event: keyof typeof eventsMapping, path: string }) {
|
|
||||||
const { icon, color, action } = eventsMapping[event] || eventsMapping.change
|
|
||||||
|
|
||||||
consola.log({
|
|
||||||
type: event,
|
|
||||||
icon: chalk[color].bold(icon),
|
|
||||||
message: `${action} ${chalk.cyan(formatPath(path))}`
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
async onWatchRestart ({ event, path }, { nuxt, cmd, argv }) {
|
|
||||||
this.logChanged({ event, path })
|
|
||||||
|
|
||||||
await nuxt.close()
|
|
||||||
|
|
||||||
await this.startDev(cmd, argv)
|
|
||||||
},
|
|
||||||
|
|
||||||
onBundlerChange (path: string) {
|
|
||||||
this.logChanged({ event: 'change', path })
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import path from 'path'
|
|
||||||
import consola from 'consola'
|
|
||||||
import { TARGETS } from 'src/utils'
|
|
||||||
import type NuxtCommand from '../command'
|
|
||||||
import { common, locking } from '../options'
|
|
||||||
import { createLock } from '../utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'export',
|
|
||||||
description: 'Export a static generated web application',
|
|
||||||
usage: 'export <dir>',
|
|
||||||
options: {
|
|
||||||
...common,
|
|
||||||
...locking,
|
|
||||||
'fail-on-error': {
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Exit with non-zero status code if there are errors when exporting pages'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
const config = await cmd.getNuxtConfig({
|
|
||||||
dev: false,
|
|
||||||
target: TARGETS.static,
|
|
||||||
_export: true
|
|
||||||
})
|
|
||||||
const nuxt = await cmd.getNuxt(config)
|
|
||||||
|
|
||||||
if (cmd.argv.lock) {
|
|
||||||
await cmd.setLock(await createLock({
|
|
||||||
id: 'export',
|
|
||||||
dir: nuxt.options.generate.dir,
|
|
||||||
root: config.rootDir
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const generator = await cmd.getGenerator(nuxt)
|
|
||||||
await nuxt.server.listen(0)
|
|
||||||
|
|
||||||
const { errors } = await generator.generate({
|
|
||||||
init: true,
|
|
||||||
build: false
|
|
||||||
})
|
|
||||||
|
|
||||||
await nuxt.close()
|
|
||||||
if (cmd.argv['fail-on-error'] && errors.length > 0) {
|
|
||||||
throw new Error('Error exporting pages, exiting with non-zero code')
|
|
||||||
}
|
|
||||||
consola.info('Ready to run `nuxt serve` or deploy `' + path.basename(nuxt.options.generate.dir) + '/` directory')
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
import { TARGETS } from 'src/utils'
|
|
||||||
import type { ParsedArgs } from 'minimist'
|
|
||||||
import type NuxtCommand from '../command'
|
|
||||||
import { common, locking } from '../options'
|
|
||||||
import { normalizeArg, createLock } from '../utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'generate',
|
|
||||||
description: 'Generate a static web application (server-rendered)',
|
|
||||||
usage: 'generate <dir>',
|
|
||||||
options: {
|
|
||||||
...common,
|
|
||||||
...locking,
|
|
||||||
build: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: true,
|
|
||||||
description: 'Only generate pages for dynamic routes, used for incremental builds. Generate has to be run once without this option before using it'
|
|
||||||
},
|
|
||||||
devtools: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Enable Vue devtools',
|
|
||||||
prepare (_cmd: NuxtCommand, options, argv: ParsedArgs) {
|
|
||||||
options.vue = options.vue || {}
|
|
||||||
options.vue.config = options.vue.config || {}
|
|
||||||
if (argv.devtools) {
|
|
||||||
options.vue.config.devtools = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
quiet: {
|
|
||||||
alias: 'q',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Disable output except for errors',
|
|
||||||
prepare (_cmd: NuxtCommand, options, argv: ParsedArgs) {
|
|
||||||
// Silence output when using --quiet
|
|
||||||
options.build = options.build || {}
|
|
||||||
if (argv.quiet) {
|
|
||||||
options.build.quiet = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modern: {
|
|
||||||
...common.modern,
|
|
||||||
description: 'Generate app in modern build (modern mode can be only client)',
|
|
||||||
prepare (_cmd: NuxtCommand, options, argv: ParsedArgs) {
|
|
||||||
if (normalizeArg(argv.modern)) {
|
|
||||||
options.modern = 'client'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'fail-on-error': {
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Exit with non-zero status code if there are errors when generating pages'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
const config = await cmd.getNuxtConfig({
|
|
||||||
dev: false,
|
|
||||||
_build: cmd.argv.build,
|
|
||||||
_generate: true
|
|
||||||
})
|
|
||||||
|
|
||||||
if (config.target === TARGETS.static) {
|
|
||||||
throw new Error("Please use `nuxt export` when using `target: 'static'`")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forcing static target anyway
|
|
||||||
config.target = TARGETS.static
|
|
||||||
|
|
||||||
// Disable analyze if set by the nuxt config
|
|
||||||
config.build = config.build || {}
|
|
||||||
config.build.analyze = false
|
|
||||||
|
|
||||||
// Set flag to keep the prerendering behaviour
|
|
||||||
config._legacyGenerate = true
|
|
||||||
|
|
||||||
const nuxt = await cmd.getNuxt(config)
|
|
||||||
|
|
||||||
if (cmd.argv.lock) {
|
|
||||||
await cmd.setLock(await createLock({
|
|
||||||
id: 'build',
|
|
||||||
dir: nuxt.options.buildDir,
|
|
||||||
root: config.rootDir
|
|
||||||
}))
|
|
||||||
|
|
||||||
nuxt.hook('build:done', async () => {
|
|
||||||
await cmd.releaseLock()
|
|
||||||
|
|
||||||
await cmd.setLock(await createLock({
|
|
||||||
id: 'generate',
|
|
||||||
dir: nuxt.options.generate.dir,
|
|
||||||
root: config.rootDir
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const generator = await cmd.getGenerator(nuxt)
|
|
||||||
await nuxt.server.listen(0)
|
|
||||||
|
|
||||||
const { errors } = await generator.generate({
|
|
||||||
init: true,
|
|
||||||
build: cmd.argv.build
|
|
||||||
})
|
|
||||||
|
|
||||||
await nuxt.close()
|
|
||||||
if (cmd.argv['fail-on-error'] && errors.length > 0) {
|
|
||||||
throw new Error('Error generating pages, exiting with non-zero code')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
import consola from 'consola'
|
|
||||||
import listCommands from '../list'
|
|
||||||
import { common } from '../options'
|
|
||||||
import NuxtCommand from '../command'
|
|
||||||
import getCommand from '.'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'help',
|
|
||||||
description: 'Shows help for <command>',
|
|
||||||
usage: 'help <command>',
|
|
||||||
options: {
|
|
||||||
help: common.help,
|
|
||||||
version: common.version
|
|
||||||
},
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
const [name] = cmd._argv
|
|
||||||
if (!name) {
|
|
||||||
return listCommands()
|
|
||||||
}
|
|
||||||
const command = await getCommand(name)
|
|
||||||
|
|
||||||
if (!command) {
|
|
||||||
consola.info(`Unknown command: ${name}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
NuxtCommand.from(command).showHelp()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
const _commands = {
|
|
||||||
start: () => import('./start'),
|
|
||||||
serve: () => import('./serve'),
|
|
||||||
dev: () => import('./dev'),
|
|
||||||
build: () => import('./build'),
|
|
||||||
generate: () => import('./generate'),
|
|
||||||
export: () => import('./export'),
|
|
||||||
webpack: () => import('./webpack'),
|
|
||||||
help: () => import('./help')
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function getCommand (name: keyof typeof _commands) {
|
|
||||||
if (!_commands[name]) {
|
|
||||||
return Promise.resolve(null)
|
|
||||||
}
|
|
||||||
return _commands[name]().then(m => m.default)
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
import { promises as fs } from 'fs'
|
|
||||||
import { join, extname, basename } from 'path'
|
|
||||||
import express from 'express'
|
|
||||||
import serveStatic from 'serve-static'
|
|
||||||
import compression from 'compression'
|
|
||||||
import { getNuxtConfig } from 'src/config'
|
|
||||||
import { TARGETS } from 'src/utils'
|
|
||||||
import { Listener } from 'src/server'
|
|
||||||
import { Nuxt } from 'src/core'
|
|
||||||
import { common, server } from '../options'
|
|
||||||
import { showBanner } from '../utils/banner'
|
|
||||||
import type NuxtCommand from '../command'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'serve',
|
|
||||||
description: 'Serve the exported static application (should be compiled with `nuxt build` and `nuxt export` first)',
|
|
||||||
usage: 'serve <dir>',
|
|
||||||
options: {
|
|
||||||
'config-file': common['config-file'],
|
|
||||||
version: common.version,
|
|
||||||
help: common.help,
|
|
||||||
...server
|
|
||||||
},
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
let options = await cmd.getNuxtConfig({ dev: false })
|
|
||||||
// add default options
|
|
||||||
options = getNuxtConfig(options)
|
|
||||||
try {
|
|
||||||
// overwrites with build config
|
|
||||||
const buildConfig = require(join(options.buildDir, 'nuxt/config.json'))
|
|
||||||
options.target = buildConfig.target
|
|
||||||
} catch (err) {}
|
|
||||||
|
|
||||||
if (options.target === TARGETS.server) {
|
|
||||||
throw new Error('You cannot use `nuxt serve` with ' + TARGETS.server + ' target, please use `nuxt start`')
|
|
||||||
}
|
|
||||||
const distStat = await fs.stat(options.generate.dir).catch(_err => null) // eslint-disable-line handle-callback-err
|
|
||||||
if (!distStat || !distStat.isDirectory()) {
|
|
||||||
throw new Error('Output directory `' + basename(options.generate.dir) + '/` does not exists, please run `nuxt export` before `nuxt serve`.')
|
|
||||||
}
|
|
||||||
const app = express()
|
|
||||||
app.use(compression({ threshold: 0 }))
|
|
||||||
app.use(
|
|
||||||
options.router.base,
|
|
||||||
serveStatic(options.generate.dir, {
|
|
||||||
extensions: ['html']
|
|
||||||
})
|
|
||||||
)
|
|
||||||
if (options.generate.fallback) {
|
|
||||||
const fallbackFile = await fs.readFile(join(options.generate.dir, options.generate.fallback), 'utf-8')
|
|
||||||
app.use((req, res, next) => {
|
|
||||||
const ext = extname(req.url) || '.html'
|
|
||||||
|
|
||||||
if (ext !== '.html') {
|
|
||||||
return next()
|
|
||||||
}
|
|
||||||
res.writeHeader(200, {
|
|
||||||
'Content-Type': 'text/html'
|
|
||||||
})
|
|
||||||
res.write(fallbackFile)
|
|
||||||
res.end()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const { port, host, socket, https } = options.server
|
|
||||||
const listener = new Listener({
|
|
||||||
port,
|
|
||||||
host,
|
|
||||||
socket,
|
|
||||||
https,
|
|
||||||
app,
|
|
||||||
dev: true, // try another port if taken
|
|
||||||
baseURL: options.router.base
|
|
||||||
})
|
|
||||||
await listener.listen()
|
|
||||||
showBanner({
|
|
||||||
constructor: Nuxt,
|
|
||||||
options,
|
|
||||||
server: {
|
|
||||||
listeners: [listener]
|
|
||||||
}
|
|
||||||
}, false)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
import { TARGETS } from 'src/utils'
|
|
||||||
|
|
||||||
import type NuxtCommand from '../command'
|
|
||||||
import { common, server } from '../options'
|
|
||||||
import { showBanner } from '../utils/banner'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'start',
|
|
||||||
description: 'Start the application in production mode (the application should be compiled with `nuxt build` first)',
|
|
||||||
usage: 'start <dir>',
|
|
||||||
options: {
|
|
||||||
...common,
|
|
||||||
...server
|
|
||||||
},
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
const config = await cmd.getNuxtConfig({ dev: false, _start: true })
|
|
||||||
if (config.target === TARGETS.static) {
|
|
||||||
throw new Error('You cannot use `nuxt start` with ' + TARGETS.static + ' target, please use `nuxt export` and `nuxt serve`')
|
|
||||||
}
|
|
||||||
const nuxt = await cmd.getNuxt(config)
|
|
||||||
|
|
||||||
// Listen and show ready banner
|
|
||||||
await nuxt.server.listen()
|
|
||||||
showBanner(nuxt)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
import util from 'util'
|
|
||||||
import consola from 'consola'
|
|
||||||
import get from 'lodash/get'
|
|
||||||
|
|
||||||
import type NuxtCommand from '../command'
|
|
||||||
import { common } from '../options'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'webpack',
|
|
||||||
description: 'Inspect Nuxt webpack config',
|
|
||||||
usage: 'webpack [query...]',
|
|
||||||
options: {
|
|
||||||
...common,
|
|
||||||
name: {
|
|
||||||
alias: 'n',
|
|
||||||
type: 'string',
|
|
||||||
default: 'client',
|
|
||||||
description: 'Webpack bundle name: server, client, modern'
|
|
||||||
},
|
|
||||||
depth: {
|
|
||||||
alias: 'd',
|
|
||||||
type: 'string',
|
|
||||||
default: 2,
|
|
||||||
description: 'Inspection depth'
|
|
||||||
},
|
|
||||||
colors: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: process.stdout.isTTY,
|
|
||||||
description: 'Output with ANSI colors'
|
|
||||||
},
|
|
||||||
dev: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Inspect development mode webpack config'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async run (cmd: NuxtCommand) {
|
|
||||||
const { name } = cmd.argv
|
|
||||||
const queries = [...cmd.argv._]
|
|
||||||
|
|
||||||
const config = await cmd.getNuxtConfig({ dev: cmd.argv.dev, server: false })
|
|
||||||
const nuxt = await cmd.getNuxt(config)
|
|
||||||
const builder = await cmd.getBuilder(nuxt)
|
|
||||||
const { bundleBuilder } = builder
|
|
||||||
const webpackConfig = bundleBuilder.getWebpackConfig(name)
|
|
||||||
|
|
||||||
let queryError
|
|
||||||
const match = queries.reduce((result, query) => {
|
|
||||||
const m = advancedGet(result, query)
|
|
||||||
if (m === undefined) {
|
|
||||||
queryError = query
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}, webpackConfig)
|
|
||||||
|
|
||||||
const serialized = formatObj(match, {
|
|
||||||
depth: parseInt(cmd.argv.depth),
|
|
||||||
colors: cmd.argv.colors
|
|
||||||
})
|
|
||||||
|
|
||||||
consola.log(serialized + '\n')
|
|
||||||
|
|
||||||
if (serialized.includes('[Object]' || serialized.includes('[Array'))) {
|
|
||||||
consola.info('You can use `--depth` or add more queries to inspect `[Object]` and `[Array]` fields.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryError) {
|
|
||||||
consola.warn(`No match in webpack config for \`${queryError}\``)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function advancedGet (obj = {}, query = '') {
|
|
||||||
let result = obj
|
|
||||||
|
|
||||||
if (!query || !result) {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
const [l, r] = query.split('=')
|
|
||||||
|
|
||||||
if (!Array.isArray(result)) {
|
|
||||||
return typeof result === 'object' ? get(result, l) : result
|
|
||||||
}
|
|
||||||
|
|
||||||
result = result.filter((i) => {
|
|
||||||
const v = get(i, l)
|
|
||||||
|
|
||||||
if (!v) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(v === r) ||
|
|
||||||
(typeof v.test === 'function' && v.test(r)) ||
|
|
||||||
(typeof v.match === 'function' && v.match(r)) ||
|
|
||||||
(r && r.match(v))
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if (result.length === 1) {
|
|
||||||
return result[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.length ? result : undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatObj (obj, formatOptions) {
|
|
||||||
if (!util.formatWithOptions) {
|
|
||||||
return util.format(obj)
|
|
||||||
}
|
|
||||||
return util.formatWithOptions(formatOptions, obj)
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import * as commands from './commands'
|
|
||||||
import * as options from './options'
|
|
||||||
|
|
||||||
export {
|
|
||||||
commands,
|
|
||||||
options
|
|
||||||
}
|
|
||||||
|
|
||||||
export { default as NuxtCommand } from './command'
|
|
||||||
export { default as setup } from './setup'
|
|
||||||
export { default as run } from './run'
|
|
||||||
export { loadNuxtConfig } from './utils/config'
|
|
||||||
export { getWebpackConfig } from './utils/webpack'
|
|
@ -1,35 +0,0 @@
|
|||||||
import chalk from 'chalk'
|
|
||||||
import { indent, foldLines, colorize } from './utils/formatting'
|
|
||||||
import { startSpaces, optionSpaces } from './utils/constants'
|
|
||||||
import getCommand from './commands'
|
|
||||||
|
|
||||||
export default async function listCommands () {
|
|
||||||
const commandsOrder = ['dev', 'build', 'generate', 'start', 'help'] as const
|
|
||||||
|
|
||||||
// Load all commands
|
|
||||||
const _commands = await Promise.all(
|
|
||||||
commandsOrder.map(cmd => getCommand(cmd))
|
|
||||||
)
|
|
||||||
|
|
||||||
let maxLength = 0
|
|
||||||
const commandsHelp = []
|
|
||||||
|
|
||||||
for (const command of _commands) {
|
|
||||||
commandsHelp.push([command.usage, command.description])
|
|
||||||
maxLength = Math.max(maxLength, command.usage.length)
|
|
||||||
}
|
|
||||||
|
|
||||||
const _cmds = commandsHelp.map(([cmd, description]) => {
|
|
||||||
const i = indent(maxLength + optionSpaces - cmd.length)
|
|
||||||
return foldLines(
|
|
||||||
chalk.green(cmd) + i + description,
|
|
||||||
startSpaces + maxLength + optionSpaces * 2,
|
|
||||||
startSpaces + optionSpaces
|
|
||||||
)
|
|
||||||
}).join('\n')
|
|
||||||
|
|
||||||
const usage = foldLines('Usage: nuxt <command> [--help|-h]', startSpaces)
|
|
||||||
const cmds = foldLines('Commands:', startSpaces) + '\n\n' + _cmds
|
|
||||||
|
|
||||||
process.stderr.write(colorize(`${usage}\n\n${cmds}\n\n`))
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
import { defaultNuxtConfigFile } from 'src/config'
|
|
||||||
import { normalizeArg } from '../utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
spa: {
|
|
||||||
alias: 's',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Launch in SPA mode'
|
|
||||||
},
|
|
||||||
universal: {
|
|
||||||
alias: 'u',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Launch in Universal mode (default)'
|
|
||||||
},
|
|
||||||
'config-file': {
|
|
||||||
alias: 'c',
|
|
||||||
type: 'string',
|
|
||||||
default: defaultNuxtConfigFile,
|
|
||||||
description: `Path to Nuxt.js config file (default: \`${defaultNuxtConfigFile}\`)`
|
|
||||||
},
|
|
||||||
modern: {
|
|
||||||
alias: 'm',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Build/Start app for modern browsers, e.g. server, client and false',
|
|
||||||
prepare (_cmd, options, argv) {
|
|
||||||
if (argv.modern !== undefined) {
|
|
||||||
options.modern = normalizeArg(argv.modern)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
target: {
|
|
||||||
alias: 't',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Build/start app for a different target, e.g. server, serverless and static',
|
|
||||||
prepare (_cmd, options, argv) {
|
|
||||||
if (argv.target) {
|
|
||||||
options.target = argv.target
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'force-exit': {
|
|
||||||
type: 'boolean',
|
|
||||||
default (cmd) {
|
|
||||||
return ['build', 'generate', 'export'].includes(cmd.name)
|
|
||||||
},
|
|
||||||
description: 'Whether Nuxt.js should force exit after the command has finished'
|
|
||||||
},
|
|
||||||
version: {
|
|
||||||
alias: 'v',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Display the Nuxt version'
|
|
||||||
},
|
|
||||||
help: {
|
|
||||||
alias: 'h',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Display this message'
|
|
||||||
},
|
|
||||||
processenv: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: true,
|
|
||||||
description: 'Disable reading from `process.env` and updating it with dotenv'
|
|
||||||
},
|
|
||||||
dotenv: {
|
|
||||||
type: 'string',
|
|
||||||
default: '.env',
|
|
||||||
description: 'Specify path to dotenv file (default: `.env`). Use `false` to disable'
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import common from './common'
|
|
||||||
import server from './server'
|
|
||||||
import locking from './locking'
|
|
||||||
|
|
||||||
export {
|
|
||||||
common,
|
|
||||||
server,
|
|
||||||
locking
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
export default {
|
|
||||||
lock: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: true,
|
|
||||||
description: 'Do not set a lock on the project when building'
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
import consola from 'consola'
|
|
||||||
import type { ParsedArgs } from 'minimist'
|
|
||||||
|
|
||||||
import { Configuration } from 'src/config/options'
|
|
||||||
|
|
||||||
import NuxtCommand from '../command'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
port: {
|
|
||||||
alias: 'p',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Port number on which to start the application',
|
|
||||||
prepare (_cmd: NuxtCommand, options: Configuration, argv: ParsedArgs) {
|
|
||||||
if (argv.port) {
|
|
||||||
options.server.port = +argv.port
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hostname: {
|
|
||||||
alias: 'H',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Hostname on which to start the application',
|
|
||||||
prepare (_cmd: NuxtCommand, _options: any, argv: ParsedArgs) {
|
|
||||||
if (argv.hostname === '') {
|
|
||||||
consola.fatal('Provided hostname argument has no value')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'unix-socket': {
|
|
||||||
alias: 'n',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Path to a UNIX socket'
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
import fs from 'fs'
|
|
||||||
import execa from 'execa'
|
|
||||||
import { name as pkgName } from '../../package.json'
|
|
||||||
import NuxtCommand from './command'
|
|
||||||
import setup from './setup'
|
|
||||||
import getCommand from './commands'
|
|
||||||
|
|
||||||
function packageExists (name: string) {
|
|
||||||
try {
|
|
||||||
require.resolve(name)
|
|
||||||
return true
|
|
||||||
} catch (e) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function run (_argv: NodeJS.Process['argv'], hooks = {}) {
|
|
||||||
// Check for not installing both nuxt and nuxt-edge
|
|
||||||
const dupPkg = '@nuxt/' + (pkgName === '@nuxt/cli-edge' ? 'cli' : 'cli-edge')
|
|
||||||
if (packageExists(dupPkg)) {
|
|
||||||
throw new Error('Both `nuxt` and `nuxt-edge` dependencies are installed! This is unsupported, please choose one and remove the other one from dependencies.')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read from process.argv
|
|
||||||
const argv = _argv ? Array.from(_argv) : process.argv.slice(2)
|
|
||||||
|
|
||||||
// Check for internal command
|
|
||||||
let cmd = await getCommand(argv[0] as any)
|
|
||||||
|
|
||||||
// Matching `nuxt` or `nuxt [dir]` or `nuxt -*` for `nuxt dev` shortcut
|
|
||||||
if (!cmd && (!argv[0] || argv[0][0] === '-' || (argv[0] !== 'static' && fs.existsSync(argv[0])))) {
|
|
||||||
argv.unshift('dev')
|
|
||||||
cmd = await getCommand('dev')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for dev
|
|
||||||
const dev = argv[0] === 'dev'
|
|
||||||
|
|
||||||
// Setup env
|
|
||||||
setup({ dev })
|
|
||||||
|
|
||||||
// Try internal command
|
|
||||||
if (cmd) {
|
|
||||||
return NuxtCommand.run(cmd, argv.slice(1), hooks)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try external command
|
|
||||||
try {
|
|
||||||
await execa(`nuxt-${argv[0]}`, argv.slice(1), {
|
|
||||||
stdout: process.stdout,
|
|
||||||
stderr: process.stderr,
|
|
||||||
stdin: process.stdin
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
if (error.exitCode === 2) {
|
|
||||||
throw String(`Command not found: nuxt-${argv[0]}`)
|
|
||||||
}
|
|
||||||
throw String(`Failed to run command \`nuxt-${argv[0]}\`:\n${error}`)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
import consola from 'consola'
|
|
||||||
import exit from 'exit'
|
|
||||||
import { fatalBox } from './utils/formatting'
|
|
||||||
|
|
||||||
let _setup = false
|
|
||||||
|
|
||||||
export default function setup ({ dev }: { dev: boolean }) {
|
|
||||||
// Apply default NODE_ENV if not provided
|
|
||||||
if (!process.env.NODE_ENV) {
|
|
||||||
process.env.NODE_ENV = dev ? 'development' : 'production'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_setup) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_setup = true
|
|
||||||
|
|
||||||
// Global error handler
|
|
||||||
/* istanbul ignore next */
|
|
||||||
process.on('unhandledRejection', (err) => {
|
|
||||||
consola.error(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Exit process on fatal errors
|
|
||||||
/* istanbul ignore next */
|
|
||||||
consola.addReporter({
|
|
||||||
log (logObj) {
|
|
||||||
if (logObj.type === 'fatal') {
|
|
||||||
const errorMessage = String(logObj.args[0])
|
|
||||||
process.stderr.write(fatalBox(errorMessage))
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Wrap all console logs with consola for better DX
|
|
||||||
consola.wrapConsole()
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
import consola from 'consola'
|
|
||||||
import env from 'std-env'
|
|
||||||
import chalk from 'chalk'
|
|
||||||
|
|
||||||
import { Nuxt } from 'src/core'
|
|
||||||
import { successBox } from './formatting'
|
|
||||||
import { getFormattedMemoryUsage } from './memory'
|
|
||||||
|
|
||||||
export function showBanner (nuxt: Nuxt, showMemoryUsage = true) {
|
|
||||||
if (env.test) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env.minimalCLI) {
|
|
||||||
for (const listener of nuxt.server.listeners) {
|
|
||||||
consola.info('Listening on: ' + listener.url)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const titleLines = []
|
|
||||||
const messageLines = []
|
|
||||||
|
|
||||||
// Name and version
|
|
||||||
const { bannerColor, badgeMessages } = nuxt.options.cli
|
|
||||||
titleLines.push(`${chalk[bannerColor].bold('Nuxt.js')} @ ${nuxt.constructor.version || 'exotic'}\n`)
|
|
||||||
|
|
||||||
const label = (name: string) => chalk.bold.cyan(`▸ ${name}:`)
|
|
||||||
|
|
||||||
// Environment
|
|
||||||
const isDev = nuxt.options.dev
|
|
||||||
let _env = isDev ? 'development' : 'production'
|
|
||||||
if (process.env.NODE_ENV !== _env) {
|
|
||||||
_env += ` (${chalk.cyan(process.env.NODE_ENV)})`
|
|
||||||
}
|
|
||||||
titleLines.push(`${label('Environment')} ${_env}`)
|
|
||||||
|
|
||||||
// Rendering
|
|
||||||
const isSSR = nuxt.options.render.ssr
|
|
||||||
const rendering = isSSR ? 'server-side' : 'client-side'
|
|
||||||
titleLines.push(`${label('Rendering')} ${rendering}`)
|
|
||||||
|
|
||||||
// Target
|
|
||||||
const target = nuxt.options.target || 'server'
|
|
||||||
titleLines.push(`${label('Target')} ${target}`)
|
|
||||||
|
|
||||||
if (showMemoryUsage) {
|
|
||||||
titleLines.push('\n' + getFormattedMemoryUsage())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listeners
|
|
||||||
for (const listener of nuxt.server.listeners) {
|
|
||||||
messageLines.push(chalk.bold('Listening: ') + chalk.underline.blue(listener.url))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add custom badge messages
|
|
||||||
if (badgeMessages.length) {
|
|
||||||
messageLines.push('', ...badgeMessages)
|
|
||||||
}
|
|
||||||
|
|
||||||
process.stdout.write(successBox(messageLines.join('\n'), titleLines.join('\n')))
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
import path from 'path'
|
|
||||||
import defaultsDeep from 'lodash/defaultsDeep'
|
|
||||||
import { loadNuxtConfig as _loadNuxtConfig, getDefaultNuxtConfig } from 'src/config'
|
|
||||||
import { MODES } from 'src/utils'
|
|
||||||
import type { ParsedArgs } from 'minimist'
|
|
||||||
|
|
||||||
export async function loadNuxtConfig (argv: ParsedArgs, configContext) {
|
|
||||||
const rootDir = path.resolve(argv._[0] || '.')
|
|
||||||
const configFile = argv['config-file']
|
|
||||||
|
|
||||||
// Load config
|
|
||||||
const options = await _loadNuxtConfig({
|
|
||||||
rootDir,
|
|
||||||
configFile,
|
|
||||||
configContext,
|
|
||||||
envConfig: {
|
|
||||||
dotenv: argv.dotenv === 'false' ? false : argv.dotenv,
|
|
||||||
env: argv.processenv ? process.env : {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Nuxt Mode
|
|
||||||
options.mode =
|
|
||||||
(argv.spa && MODES.spa) || (argv.universal && MODES.universal) || options.mode
|
|
||||||
|
|
||||||
// Server options
|
|
||||||
options.server = defaultsDeep({
|
|
||||||
port: argv.port || undefined,
|
|
||||||
host: argv.hostname || undefined,
|
|
||||||
socket: argv['unix-socket'] || undefined
|
|
||||||
}, options.server || {}, getDefaultNuxtConfig().server)
|
|
||||||
|
|
||||||
return options
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
export const forceExitTimeout = 5
|
|
||||||
|
|
||||||
export const startSpaces = 2
|
|
||||||
export const optionSpaces = 2
|
|
||||||
|
|
||||||
// 80% of terminal column width
|
|
||||||
// this is a fn because console width can have changed since startup
|
|
||||||
export const maxCharsPerLine = () => (process.stdout.columns || 100) * 80 / 100
|
|
@ -1,69 +0,0 @@
|
|||||||
import wrapAnsi from 'wrap-ansi'
|
|
||||||
import chalk from 'chalk'
|
|
||||||
import boxen from 'boxen'
|
|
||||||
import { maxCharsPerLine } from './constants'
|
|
||||||
|
|
||||||
export function indent (count: number, chr = ' ') {
|
|
||||||
return chr.repeat(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function indentLines (string: string | string[], spaces: number, firstLineSpaces?: number) {
|
|
||||||
const lines = Array.isArray(string) ? string : string.split('\n')
|
|
||||||
let s = ''
|
|
||||||
if (lines.length) {
|
|
||||||
const i0 = indent(firstLineSpaces === undefined ? spaces : firstLineSpaces)
|
|
||||||
s = i0 + lines.shift()
|
|
||||||
}
|
|
||||||
if (lines.length) {
|
|
||||||
const i = indent(spaces)
|
|
||||||
s += '\n' + lines.map(l => i + l).join('\n')
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
export function foldLines (string: string, spaces: number, firstLineSpaces?: number, charsPerLine = maxCharsPerLine()) {
|
|
||||||
return indentLines(wrapAnsi(string, charsPerLine), spaces, firstLineSpaces)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function colorize (text: string) {
|
|
||||||
return text
|
|
||||||
.replace(/\[[^ ]+]/g, m => chalk.grey(m))
|
|
||||||
.replace(/<[^ ]+>/g, m => chalk.green(m))
|
|
||||||
.replace(/ (-[-\w,]+)/g, m => chalk.bold(m))
|
|
||||||
.replace(/`([^`]+)`/g, (_, m) => chalk.bold.cyan(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
export function box (message: string, title: string, options?: boxen.Options) {
|
|
||||||
return boxen([
|
|
||||||
title || chalk.white('Nuxt Message'),
|
|
||||||
'',
|
|
||||||
chalk.white(foldLines(message, 0, 0, maxCharsPerLine()))
|
|
||||||
].join('\n'), Object.assign({
|
|
||||||
borderColor: 'white',
|
|
||||||
borderStyle: 'round',
|
|
||||||
padding: 1,
|
|
||||||
margin: 1
|
|
||||||
}, options)) + '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function successBox (message: string, title?: string) {
|
|
||||||
return box(message, title || chalk.green('✔ Nuxt Success'), {
|
|
||||||
borderColor: 'green'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function warningBox (message: string, title?: string) {
|
|
||||||
return box(message, title || chalk.yellow('⚠ Nuxt Warning'), {
|
|
||||||
borderColor: 'yellow'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function errorBox (message: string, title?: string) {
|
|
||||||
return box(message, title || chalk.red('✖ Nuxt Error'), {
|
|
||||||
borderColor: 'red'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fatalBox (message: string, title?: string) {
|
|
||||||
return errorBox(message, title || chalk.red('✖ Nuxt Fatal Error'))
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
import path from 'path'
|
|
||||||
import exit from 'exit'
|
|
||||||
|
|
||||||
import { lock } from 'src/utils'
|
|
||||||
import chalk from 'chalk'
|
|
||||||
import env from 'std-env'
|
|
||||||
import { warningBox } from './formatting'
|
|
||||||
|
|
||||||
export const eventsMapping = {
|
|
||||||
add: { icon: '+', color: 'green', action: 'Created' },
|
|
||||||
change: { icon: env.windows ? '»' : '↻', color: 'blue', action: 'Updated' },
|
|
||||||
unlink: { icon: '-', color: 'red', action: 'Removed' }
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formatPath (filePath: string) {
|
|
||||||
if (!filePath) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return filePath.replace(process.cwd() + path.sep, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalize string argument in command
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @param {String} argument
|
|
||||||
* @param {*} defaultValue
|
|
||||||
* @returns formatted argument
|
|
||||||
*/
|
|
||||||
export function normalizeArg (arg: boolean | 'true' | '' | 'false', defaultValue?: boolean) {
|
|
||||||
switch (arg) {
|
|
||||||
case 'true': arg = true; break
|
|
||||||
case '': arg = true; break
|
|
||||||
case 'false': arg = false; break
|
|
||||||
case undefined: arg = defaultValue; break
|
|
||||||
}
|
|
||||||
return arg
|
|
||||||
}
|
|
||||||
|
|
||||||
export function forceExit (cmdName: string, timeout: number | false) {
|
|
||||||
if (timeout !== false) {
|
|
||||||
const exitTimeout = setTimeout(() => {
|
|
||||||
const msg = `The command 'nuxt ${cmdName}' finished but did not exit after ${timeout}s
|
|
||||||
This is most likely not caused by a bug in Nuxt.js
|
|
||||||
Make sure to cleanup all timers and listeners you or your plugins/modules start.
|
|
||||||
Nuxt.js will now force exit
|
|
||||||
|
|
||||||
${chalk.bold('DeprecationWarning: Starting with Nuxt version 3 this will be a fatal error')}`
|
|
||||||
|
|
||||||
// TODO: Change this to a fatal error in v3
|
|
||||||
process.stderr.write(warningBox(msg))
|
|
||||||
exit(0)
|
|
||||||
}, timeout * 1000)
|
|
||||||
exitTimeout.unref()
|
|
||||||
} else {
|
|
||||||
exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// An immediate export throws an error when mocking with jest
|
|
||||||
// TypeError: Cannot set property createLock of #<Object> which has only a getter
|
|
||||||
export function createLock (...args: Parameters<typeof lock>) {
|
|
||||||
return lock(...args)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
import chalk from 'chalk'
|
|
||||||
import consola from 'consola'
|
|
||||||
import prettyBytes from 'pretty-bytes'
|
|
||||||
|
|
||||||
export function getMemoryUsage () {
|
|
||||||
// https://nodejs.org/api/process.html#process_process_memoryusage
|
|
||||||
const { heapUsed, rss } = process.memoryUsage()
|
|
||||||
return { heap: heapUsed, rss }
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getFormattedMemoryUsage () {
|
|
||||||
const { heap, rss } = getMemoryUsage()
|
|
||||||
return `Memory usage: ${chalk.bold(prettyBytes(heap))} (RSS: ${prettyBytes(rss)})`
|
|
||||||
}
|
|
||||||
|
|
||||||
export function showMemoryUsage () {
|
|
||||||
consola.info(getFormattedMemoryUsage())
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import { loadNuxt } from 'src/core'
|
|
||||||
import { getBuilder } from 'src/builder'
|
|
||||||
|
|
||||||
export async function getWebpackConfig (name = 'client', loadOptions = {}) {
|
|
||||||
const nuxt = await loadNuxt(loadOptions)
|
|
||||||
const builder = await getBuilder(nuxt)
|
|
||||||
const { bundleBuilder } = builder
|
|
||||||
return bundleBuilder.getWebpackConfig(name)
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user