chore: remove legacy cli from codebase

This commit is contained in:
Pooya Parsa 2021-01-20 14:29:56 +01:00
parent 588e09cf10
commit acc76ed2df
25 changed files with 0 additions and 1430 deletions

View File

@ -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
}
}

View File

@ -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) + '`')
}
}
}

View File

@ -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 })
}
}

View File

@ -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')
}
}

View File

@ -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')
}
}
}

View File

@ -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()
}
}

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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'

View File

@ -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`))
}

View File

@ -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'
}
}

View File

@ -1,9 +0,0 @@
import common from './common'
import server from './server'
import locking from './locking'
export {
common,
server,
locking
}

View File

@ -1,7 +0,0 @@
export default {
lock: {
type: 'boolean',
default: true,
description: 'Do not set a lock on the project when building'
}
}

View File

@ -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'
}
}

View File

@ -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}`)
}
}

View File

@ -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()
}

View File

@ -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')))
}

View File

@ -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
}

View File

@ -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

View File

@ -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'))
}

View File

@ -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)
}

View File

@ -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())
}

View File

@ -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)
}