diff --git a/packages/cli/src/command.js b/packages/cli/src/command.js
index fbc9552871..d1908f46ac 100644
--- a/packages/cli/src/command.js
+++ b/packages/cli/src/command.js
@@ -1,19 +1,26 @@
import parseArgs from 'minimist'
-import wrapAnsi from 'wrap-ansi'
import { name, version } from '../package.json'
-import { loadNuxtConfig, indent, indentLines, foldLines } from './utils'
-import { options as Options, defaultOptions as DefaultOptions } from './options'
+import { loadNuxtConfig, indent, foldLines } from './utils'
import * as imports from './imports'
-const startSpaces = 6
+const startSpaces = 2
const optionSpaces = 2
const maxCharsPerLine = 80
export default class NuxtCommand {
- constructor({ description, usage, options } = {}) {
+ constructor({ name, description, usage, options, run } = {}) {
+ this.name = name || ''
this.description = description || ''
this.usage = usage || ''
- this.options = Array.from(new Set((options || []).concat(DefaultOptions)))
+ this.options = Object.assign({}, options)
+ this._run = run
+ }
+
+ static from(options) {
+ if (options instanceof NuxtCommand) {
+ return options
+ }
+ return new NuxtCommand(options)
}
_getMinimistOptions() {
@@ -24,8 +31,8 @@ export default class NuxtCommand {
default: {}
}
- for (const name of this.options) {
- const option = Options[name]
+ for (const name of Object.keys(this.options)) {
+ const option = this.options[name]
if (option.alias) {
minimistOptions.alias[option.alias] = name
@@ -54,13 +61,17 @@ export default class NuxtCommand {
return argv
}
+ run() {
+ return this._run(this)
+ }
+
async getNuxtConfig(argv, extraOptions) {
const config = await loadNuxtConfig(argv)
const options = Object.assign(config, extraOptions || {})
- for (const name of this.options) {
- if (Options[name].handle) {
- Options[name].handle(options, argv)
+ for (const name of Object.keys(this.options)) {
+ if (this.options[name].prepare) {
+ this.options[name].prepare(this, options, argv)
}
}
@@ -86,38 +97,37 @@ export default class NuxtCommand {
_getHelp() {
const options = []
-
let maxOptionLength = 0
- // For consistency Options determines order
- for (const name in Options) {
- const option = Options[name]
- if (this.options.includes(name)) {
- let optionHelp = '--'
- optionHelp += option.type === 'boolean' && option.default ? 'no-' : ''
- optionHelp += name
- if (option.alias) {
- optionHelp += `, -${option.alias}`
- }
- maxOptionLength = Math.max(maxOptionLength, optionHelp.length)
- options.push([ optionHelp, option.description ])
+ for (const name in this.options) {
+ const option = this.options[name]
+
+ let optionHelp = '--'
+ optionHelp += option.type === 'boolean' && option.default ? 'no-' : ''
+ optionHelp += name
+ if (option.alias) {
+ optionHelp += `, -${option.alias}`
}
+
+ maxOptionLength = Math.max(maxOptionLength, optionHelp.length)
+ options.push([ optionHelp, option.description ])
}
- const optionStr = options.map(([option, description]) => {
- const line = option +
- indent(maxOptionLength + optionSpaces - option.length) +
- wrapAnsi(description, maxCharsPerLine - startSpaces - maxOptionLength - optionSpaces)
- return indentLines(line, startSpaces + maxOptionLength + optionSpaces, startSpaces)
+ const _opts = options.map(([option, description]) => {
+ const i = indent(maxOptionLength + optionSpaces - option.length)
+ return foldLines(
+ option + i + description,
+ maxCharsPerLine,
+ startSpaces + maxOptionLength + optionSpaces * 2,
+ startSpaces + optionSpaces
+ )
}).join('\n')
+ const usage = foldLines(`Usage: nuxt ${this.usage} [options]`, maxCharsPerLine, startSpaces)
const description = foldLines(this.description, maxCharsPerLine, startSpaces)
+ const opts = foldLines(`Options:`, maxCharsPerLine, startSpaces) + '\n\n' + _opts
- return `
- Description\n${description}
- Usage
- $ nuxt ${this.usage}
- Options\n${optionStr}\n\n`
+ return `${usage}\n\n${description}\n\n${opts}\n\n`
}
showVersion() {
diff --git a/packages/cli/src/commands/build.js b/packages/cli/src/commands/build.js
index 2868b81ab8..c55e45b0a0 100644
--- a/packages/cli/src/commands/build.js
+++ b/packages/cli/src/commands/build.js
@@ -1,46 +1,77 @@
import consola from 'consola'
-import NuxtCommand from '../command'
+import { common } from '../options'
-export default async function build() {
- const nuxtCmd = new NuxtCommand({
- description: 'Compiles the application for production deployment',
- usage: 'build
',
- options: [ 'analyze', 'quiet' ]
- })
-
- const argv = nuxtCmd.getArgv()
-
- // Create production build when calling `nuxt build` (dev: false)
- const nuxt = await nuxtCmd.getNuxt(
- await nuxtCmd.getNuxtConfig(argv, { dev: false })
- )
-
- // Setup hooks
- nuxt.hook('error', err => consola.fatal(err))
-
- let builderOrGenerator
- if (nuxt.options.mode !== 'spa' || argv.generate === false) {
- // Build only
- builderOrGenerator = (await nuxtCmd.getBuilder(nuxt)).build()
- } else {
- // Build + Generate for static deployment
- builderOrGenerator = (await nuxtCmd.getGenerator(nuxt)).generate({
- build: true
- })
- }
-
- return builderOrGenerator
- .then(() => {
- // In analyze mode wait for plugin
- // emitting assets and opening browser
- if (
- nuxt.options.build.analyze === true ||
- typeof nuxt.options.build.analyze === 'object'
- ) {
- return
+export default {
+ name: 'build',
+ description: 'Compiles the application for production deployment',
+ usage: 'build ',
+ options: {
+ ...common,
+ analyze: {
+ alias: 'a',
+ type: 'boolean',
+ description: 'Launch webpack-bundle-analyzer to optimize your bundles',
+ prepare(cmd, options, argv) {
+ // Analyze option
+ options.build = options.build || {}
+ if (argv.analyze && typeof options.build.analyze !== 'object') {
+ options.build.analyze = 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',
+ handle(options, argv) {
+ // Silence output when using --quiet
+ options.build = options.build || {}
+ if (argv.quiet) {
+ options.build.quiet = !!argv.quiet
+ }
+ }
+ }
+ },
+ async run(nuxtCmd) {
+ const argv = nuxtCmd.getArgv()
- process.exit(0)
- })
- .catch(err => consola.fatal(err))
+ // Create production build when calling `nuxt build` (dev: false)
+ const nuxt = await nuxtCmd.getNuxt(
+ await nuxtCmd.getNuxtConfig(argv, { dev: false })
+ )
+
+ // Setup hooks
+ nuxt.hook('error', err => consola.fatal(err))
+
+ let builderOrGenerator
+ if (nuxt.options.mode !== 'spa' || argv.generate === false) {
+ // Build only
+ builderOrGenerator = (await nuxtCmd.getBuilder(nuxt)).build()
+ } else {
+ // Build + Generate for static deployment
+ builderOrGenerator = (await nuxtCmd.getGenerator(nuxt)).generate({
+ build: true
+ })
+ }
+
+ return builderOrGenerator
+ .then(() => {
+ // In analyze mode wait for plugin
+ // emitting assets and opening browser
+ if (
+ nuxt.options.build.analyze === true ||
+ typeof nuxt.options.build.analyze === 'object'
+ ) {
+ return
+ }
+
+ process.exit(0)
+ })
+ .catch(err => consola.fatal(err))
+ }
}
diff --git a/packages/cli/src/commands/dev.js b/packages/cli/src/commands/dev.js
index d6e0f23772..c6c81594d9 100644
--- a/packages/cli/src/commands/dev.js
+++ b/packages/cli/src/commands/dev.js
@@ -1,59 +1,62 @@
import consola from 'consola'
-import NuxtCommand from '../command'
+import { common, server } from '../options'
-export default async function dev() {
- const nuxtCmd = new NuxtCommand({
- description: 'Start the application in development mode (e.g. hot-code reloading, error reporting)',
- usage: 'dev -p -H ',
- options: [ 'hostname', 'port' ]
- })
+export default {
+ name: 'dev',
+ description: 'Start the application in development mode (e.g. hot-code reloading, error reporting)',
+ usage: 'dev ',
+ options: {
+ ...common,
+ ...server
+ },
+ async run(cmd) {
+ const argv = cmd.getArgv()
- const argv = nuxtCmd.getArgv()
-
- const errorHandler = (err, instance) => {
- instance && instance.builder.watchServer()
- consola.error(err)
- }
-
- // Start dev
- async function startDev(oldInstance) {
- let nuxt, builder
-
- try {
- nuxt = await nuxtCmd.getNuxt(
- await nuxtCmd.getNuxtConfig(argv, { dev: true })
- )
- builder = await nuxtCmd.getBuilder(nuxt)
- nuxt.hook('watch:fileChanged', async (builder, fname) => {
- consola.debug(`[${fname}] changed, Rebuilding the app...`)
- await startDev({ nuxt: builder.nuxt, builder })
- })
- } catch (err) {
- return errorHandler(err, oldInstance)
+ const errorHandler = (err, instance) => {
+ instance && instance.builder.watchServer()
+ consola.error(err)
}
- return (
- Promise.resolve()
- .then(() => oldInstance && oldInstance.nuxt.clearHook('watch:fileChanged'))
- .then(() => oldInstance && oldInstance.builder.unwatch())
- // Start build
- .then(() => builder.build())
- // Close old nuxt no matter if build successfully
- .catch((err) => {
- oldInstance && oldInstance.nuxt.close()
- // Jump to errorHandler
- throw err
- })
- .then(() => oldInstance && oldInstance.nuxt.close())
- // Start listening
- .then(() => nuxt.listen())
- // Show ready message first time, others will be shown through WebpackBar
- .then(() => !oldInstance && nuxt.showReady(false))
- .then(() => builder.watchServer())
- // Handle errors
- .catch(err => errorHandler(err, { builder, nuxt }))
- )
- }
+ // Start dev
+ async function startDev(oldInstance) {
+ let nuxt, builder
- await startDev()
+ try {
+ nuxt = await cmd.getNuxt(
+ await cmd.getNuxtConfig(argv, { dev: true })
+ )
+ builder = await cmd.getBuilder(nuxt)
+ nuxt.hook('watch:fileChanged', async (builder, fname) => {
+ consola.debug(`[${fname}] changed, Rebuilding the app...`)
+ await startDev({ nuxt: builder.nuxt, builder })
+ })
+ } catch (err) {
+ return errorHandler(err, oldInstance)
+ }
+
+ return (
+ Promise.resolve()
+ .then(() => oldInstance && oldInstance.nuxt.clearHook('watch:fileChanged'))
+ .then(() => oldInstance && oldInstance.builder.unwatch())
+ // Start build
+ .then(() => builder.build())
+ // Close old nuxt no matter if build successfully
+ .catch((err) => {
+ oldInstance && oldInstance.nuxt.close()
+ // Jump to errorHandler
+ throw err
+ })
+ .then(() => oldInstance && oldInstance.nuxt.close())
+ // Start listening
+ .then(() => nuxt.listen())
+ // Show ready message first time, others will be shown through WebpackBar
+ .then(() => !oldInstance && nuxt.showReady(false))
+ .then(() => builder.watchServer())
+ // Handle errors
+ .catch(err => errorHandler(err, { builder, nuxt }))
+ )
+ }
+
+ await startDev()
+ }
}
diff --git a/packages/cli/src/commands/generate.js b/packages/cli/src/commands/generate.js
index a2d79697ed..c2e406f96c 100644
--- a/packages/cli/src/commands/generate.js
+++ b/packages/cli/src/commands/generate.js
@@ -1,25 +1,32 @@
import consola from 'consola'
-import NuxtCommand from '../command'
+import { common } from '../options'
-export default async function generate() {
- const nuxtCmd = new NuxtCommand({
- description: 'Generate a static web application (server-rendered)',
- usage: 'generate ',
- options: [ 'build' ]
- })
+export default {
+ name: 'generate',
+ description: 'Generate a static web application (server-rendered)',
+ usage: 'generate ',
+ options: {
+ ...common,
+ build: {
+ type: 'boolean',
+ default: true,
+ description: 'Only generate pages for dynamic routes. Nuxt has to be built once before using this option'
+ }
+ },
+ async run(cmd) {
+ const argv = cmd.getArgv()
- const argv = nuxtCmd.getArgv()
-
- const generator = await nuxtCmd.getGenerator(
- await nuxtCmd.getNuxt(
- await nuxtCmd.getNuxtConfig(argv, { dev: false })
+ const generator = await cmd.getGenerator(
+ await cmd.getNuxt(
+ await cmd.getNuxtConfig(argv, { dev: false })
+ )
)
- )
- return generator.generate({
- init: true,
- build: argv.build
- }).then(() => {
- process.exit(0)
- }).catch(err => consola.fatal(err))
+ return generator.generate({
+ init: true,
+ build: argv.build
+ }).then(() => {
+ process.exit(0)
+ }).catch(err => consola.fatal(err))
+ }
}
diff --git a/packages/cli/src/commands/start.js b/packages/cli/src/commands/start.js
index 2498a06a87..e08e08ffcc 100644
--- a/packages/cli/src/commands/start.js
+++ b/packages/cli/src/commands/start.js
@@ -1,49 +1,52 @@
import fs from 'fs'
import path from 'path'
import consola from 'consola'
-import NuxtCommand from '../command'
+import { common, server } from '../options'
-export default async function start() {
- const nuxtCmd = new NuxtCommand({
- description: 'Start the application in production mode (the application should be compiled with `nuxt build` first)',
- usage: 'start -p -H ',
- options: [ 'hostname', 'port', 'unix-socket' ]
- })
+export default {
+ name: 'start',
+ description: 'Start the application in production mode (the application should be compiled with `nuxt build` first)',
+ usage: 'start ',
+ options: {
+ ...common,
+ ...server
+ },
+ async run(cmd) {
+ const argv = cmd.getArgv()
- const argv = nuxtCmd.getArgv()
-
- // Create production build when calling `nuxt build`
- const nuxt = await nuxtCmd.getNuxt(
- await nuxtCmd.getNuxtConfig(argv, { dev: false })
- )
-
- // Setup hooks
- nuxt.hook('error', err => consola.fatal(err))
-
- // Check if project is built for production
- const distDir = path.resolve(
- nuxt.options.rootDir,
- nuxt.options.buildDir || '.nuxt',
- 'dist',
- 'server'
- )
- if (!fs.existsSync(distDir)) {
- consola.fatal(
- 'No build files found, please run `nuxt build` before launching `nuxt start`'
+ // Create production build when calling `nuxt build`
+ const nuxt = await cmd.getNuxt(
+ await cmd.getNuxtConfig(argv, { dev: false })
)
- }
- // Check if SSR Bundle is required
- if (nuxt.options.render.ssr === true) {
- const ssrBundlePath = path.resolve(distDir, 'server-bundle.json')
- if (!fs.existsSync(ssrBundlePath)) {
+ // Setup hooks
+ nuxt.hook('error', err => consola.fatal(err))
+
+ // Check if project is built for production
+ const distDir = path.resolve(
+ nuxt.options.rootDir,
+ nuxt.options.buildDir || '.nuxt',
+ 'dist',
+ 'server'
+ )
+ if (!fs.existsSync(distDir)) {
consola.fatal(
- 'No SSR build! Please start with `nuxt start --spa` or build using `nuxt build --universal`'
+ 'No build files found, please run `nuxt build` before launching `nuxt start`'
)
}
- }
- return nuxt.listen().then(() => {
- nuxt.showReady(false)
- })
+ // Check if SSR Bundle is required
+ if (nuxt.options.render.ssr === true) {
+ const ssrBundlePath = path.resolve(distDir, 'server-bundle.json')
+ if (!fs.existsSync(ssrBundlePath)) {
+ consola.fatal(
+ 'No SSR build! Please start with `nuxt start --spa` or build using `nuxt build --universal`'
+ )
+ }
+ }
+
+ return nuxt.listen().then(() => {
+ nuxt.showReady(false)
+ })
+ }
}
diff --git a/packages/cli/src/index.js b/packages/cli/src/index.js
index 5c39b23a97..3ee655ce7c 100644
--- a/packages/cli/src/index.js
+++ b/packages/cli/src/index.js
@@ -4,7 +4,7 @@ import * as _imports from './imports'
export const commands = _commands
export const imports = _imports
+export { default as NuxtCommand } from './command'
export { default as setup } from './setup'
export { default as run } from './run'
-
export { loadNuxtConfig } from './utils'
diff --git a/packages/cli/src/options.js b/packages/cli/src/options.js
deleted file mode 100644
index 2afd911650..0000000000
--- a/packages/cli/src/options.js
+++ /dev/null
@@ -1,101 +0,0 @@
-import consola from 'consola'
-
-export const defaultOptions = [
- 'spa',
- 'universal',
- 'config-file',
- 'version',
- 'help'
-]
-
-export const options = {
- port: {
- alias: 'p',
- type: 'string',
- description: 'Port number on which to start the application',
- handle(options, argv) {
- if (argv.port) {
- options.server.port = +argv.port
- }
- }
- },
- hostname: {
- alias: 'H',
- type: 'string',
- description: 'Hostname on which to start the application',
- handle(options, argv) {
- if (argv.hostname === '') {
- consola.fatal('Provided hostname argument has no value')
- }
- }
- },
- 'unix-socket': {
- alias: 'n',
- type: 'string',
- description: 'Path to a UNIX socket'
- },
- analyze: {
- alias: 'a',
- type: 'boolean',
- description: 'Launch webpack-bundle-analyzer to optimize your bundles',
- handle(options, argv) {
- // Analyze option
- options.build = options.build || {}
- if (argv.analyze && typeof options.build.analyze !== 'object') {
- options.build.analyze = true
- }
- }
- },
- build: {
- type: 'boolean',
- default: true,
- description: 'Only generate pages for dynamic routes. Nuxt has to be built once before using this option'
- },
- generate: {
- type: 'boolean',
- default: true,
- description: 'Don\'t generate static version for SPA mode (useful for nuxt start)'
- },
- 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: 'nuxt.config.js',
- description: 'Path to Nuxt.js config file (default: nuxt.config.js)'
- },
- quiet: {
- alias: 'q',
- type: 'boolean',
- description: 'Disable output except for errors',
- handle(options, argv) {
- // Silence output when using --quiet
- options.build = options.build || {}
- if (argv.quiet) {
- options.build.quiet = !!argv.quiet
- }
- }
- },
- verbose: {
- alias: 'v',
- type: 'boolean',
- description: 'Show debug information'
- },
- version: {
- type: 'boolean',
- description: 'Display the Nuxt version'
- },
- help: {
- alias: 'h',
- type: 'boolean',
- description: 'Display this message'
- }
-}
diff --git a/packages/cli/src/options/common.js b/packages/cli/src/options/common.js
new file mode 100644
index 0000000000..a1565a0950
--- /dev/null
+++ b/packages/cli/src/options/common.js
@@ -0,0 +1,27 @@
+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: 'nuxt.config.js',
+ description: 'Path to Nuxt.js config file (default: nuxt.config.js)'
+ },
+ version: {
+ type: 'boolean',
+ description: 'Display the Nuxt version'
+ },
+ help: {
+ alias: 'h',
+ type: 'boolean',
+ description: 'Display this message'
+ }
+}
diff --git a/packages/cli/src/options/index.js b/packages/cli/src/options/index.js
new file mode 100644
index 0000000000..347fa2c72a
--- /dev/null
+++ b/packages/cli/src/options/index.js
@@ -0,0 +1,2 @@
+export { default as common } from './common'
+export { default as server } from './server'
diff --git a/packages/cli/src/options/server.js b/packages/cli/src/options/server.js
new file mode 100644
index 0000000000..91aad77c68
--- /dev/null
+++ b/packages/cli/src/options/server.js
@@ -0,0 +1,29 @@
+import consola from 'consola'
+
+export default {
+ port: {
+ alias: 'p',
+ type: 'string',
+ description: 'Port number on which to start the application',
+ prepare(cmd, options, argv) {
+ if (argv.port) {
+ options.server.port = +argv.port
+ }
+ }
+ },
+ hostname: {
+ alias: 'H',
+ type: 'string',
+ description: 'Hostname on which to start the application',
+ prepare(cmd, options, argv) {
+ if (argv.hostname === '') {
+ consola.fatal('Provided hostname argument has no value')
+ }
+ }
+ },
+ 'unix-socket': {
+ alias: 'n',
+ type: 'string',
+ description: 'Path to a UNIX socket'
+ }
+}
diff --git a/packages/cli/src/run.js b/packages/cli/src/run.js
index 97c322b53b..97976d71b6 100644
--- a/packages/cli/src/run.js
+++ b/packages/cli/src/run.js
@@ -1,4 +1,5 @@
import consola from 'consola'
+import NuxtCommand from './command'
import * as commands from './commands'
import setup from './setup'
@@ -26,7 +27,9 @@ export default function run() {
})
return commands[cmd]() // eslint-disable-line import/namespace
- .then(m => m.default())
+ .then(m => m.default)
+ .then(options => NuxtCommand.from(options))
+ .then(command => command.run())
.catch((error) => {
consola.fatal(error)
})
diff --git a/packages/cli/src/utils.js b/packages/cli/src/utils.js
index 5810e4d792..6b609005bf 100644
--- a/packages/cli/src/utils.js
+++ b/packages/cli/src/utils.js
@@ -76,11 +76,11 @@ export function indentLines(string, spaces, firstLineSpaces) {
}
if (lines.length) {
const i = indent(spaces)
- s += '\n' + lines.map(l => i + l.trim()).join('\n')
+ s += '\n' + lines.map(l => i + l).join('\n')
}
return s
}
export function foldLines(string, maxCharsPerLine, spaces, firstLineSpaces) {
- return indentLines(wrapAnsi(string, maxCharsPerLine), spaces, firstLineSpaces)
+ return indentLines(wrapAnsi(string, maxCharsPerLine, { trim: false }), spaces, firstLineSpaces)
}
diff --git a/packages/cli/test/unit/__snapshots__/command.test.js.snap b/packages/cli/test/unit/__snapshots__/command.test.js.snap
new file mode 100644
index 0000000000..20ef9648a3
--- /dev/null
+++ b/packages/cli/test/unit/__snapshots__/command.test.js.snap
@@ -0,0 +1,23 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`cli/command builds help text 1`] = `
+" Usage: nuxt this is how you do it [options]
+
+ a very long description that is longer than 80 chars and should wrap to the next
+ line while keeping indentation
+
+ Options:
+
+ --spa, -s Launch in SPA mode
+ --universal, -u Launch in Universal mode (default)
+ --config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
+ --version Display the Nuxt version
+ --help, -h Display this message
+ --port, -p Port number on which to start the application
+ --hostname, -H Hostname on which to start the application
+ --unix-socket, -n Path to a UNIX socket
+ --foo very long option that is longer than 80 chars and should wrap
+ to the next line while keeping indentation
+
+"
+`;
diff --git a/packages/cli/test/unit/build.test.js b/packages/cli/test/unit/build.test.js
index 5c501804ec..1ebc3ea7b4 100644
--- a/packages/cli/test/unit/build.test.js
+++ b/packages/cli/test/unit/build.test.js
@@ -1,25 +1,18 @@
-import { consola, mockGetNuxt, mockGetBuilder, mockGetGenerator } from '../utils'
+import { consola, mockGetNuxt, mockGetBuilder, mockGetGenerator, NuxtCommand } from '../utils'
describe('build', () => {
let build
beforeAll(async () => {
- build = await import('../../src/commands/build')
- build = build.default
-
+ build = await import('../../src/commands/build').then(m => m.default)
jest.spyOn(process, 'exit').mockImplementation(code => code)
})
- afterAll(() => {
- process.exit.mockRestore()
- })
+ afterAll(() => process.exit.mockRestore())
+ afterEach(() => jest.resetAllMocks())
- afterEach(() => {
- jest.resetAllMocks()
- })
-
- test('is function', () => {
- expect(typeof build).toBe('function')
+ test('has run function', () => {
+ expect(typeof build.run).toBe('function')
})
test('builds on universal mode', async () => {
@@ -31,7 +24,7 @@ describe('build', () => {
})
const builder = mockGetBuilder(Promise.resolve())
- await build()
+ await NuxtCommand.from(build).run()
expect(builder).toHaveBeenCalled()
})
@@ -45,7 +38,7 @@ describe('build', () => {
})
const generate = mockGetGenerator(Promise.resolve())
- await build()
+ await NuxtCommand.from(build).run()
expect(generate).toHaveBeenCalled()
expect(process.exit).toHaveBeenCalled()
@@ -55,7 +48,7 @@ describe('build', () => {
mockGetNuxt({ mode: 'universal' })
mockGetBuilder(Promise.reject(new Error('Builder Error')))
- await build()
+ await NuxtCommand.from(build).run()
expect(consola.fatal).toHaveBeenCalledWith(new Error('Builder Error'))
})
diff --git a/packages/cli/test/unit/cli.test.js b/packages/cli/test/unit/cli.test.js
index fa283776bd..8f597e7ba4 100644
--- a/packages/cli/test/unit/cli.test.js
+++ b/packages/cli/test/unit/cli.test.js
@@ -10,9 +10,7 @@ const readDir = promisify(readdir)
jest.mock('../../src/commands')
describe('cli', () => {
- afterEach(() => {
- jest.resetAllMocks()
- })
+ afterEach(() => jest.resetAllMocks())
test('exports for all commands defined', async () => {
const cmds = await readDir(resolve(__dirname, '..', '..', 'src', 'commands'))
@@ -32,12 +30,14 @@ describe('cli', () => {
test('calls expected method', async () => {
const argv = process.argv
process.argv = ['', '', 'dev']
- const defaultExport = jest.fn().mockImplementation(() => Promise.resolve())
+ const defaultExport = {
+ run: jest.fn().mockImplementation(() => Promise.resolve())
+ }
commands.dev.mockImplementationOnce(() => Promise.resolve({ default: defaultExport }))
await run()
- expect(defaultExport).toHaveBeenCalled()
+ expect(defaultExport.run).toHaveBeenCalled()
process.argv = argv
})
diff --git a/packages/cli/test/unit/command.test.js b/packages/cli/test/unit/command.test.js
index cb0c05af7e..07cbec1058 100644
--- a/packages/cli/test/unit/command.test.js
+++ b/packages/cli/test/unit/command.test.js
@@ -1,39 +1,31 @@
import Command from '../../src/command'
-import { options as Options } from '../../src/options'
+import { common, server } from '../../src/options'
import { consola } from '../utils'
jest.mock('@nuxt/core')
jest.mock('@nuxt/builder')
jest.mock('@nuxt/generator')
+const allOptions = {
+ ...common,
+ ...server
+}
+
describe('cli/command', () => {
- beforeEach(() => {
- jest.restoreAllMocks()
- })
-
- test('adds default options', () => {
- const cmd = new Command()
-
- expect(cmd.options.length).not.toBe(0)
- })
+ beforeEach(() => jest.restoreAllMocks())
test('builds minimist options', () => {
- const cmd = new Command({
- options: Object.keys(Options)
- })
-
+ const cmd = new Command({ options: allOptions })
const minimistOptions = cmd._getMinimistOptions()
expect(minimistOptions.string.length).toBe(4)
- expect(minimistOptions.boolean.length).toBe(9)
+ expect(minimistOptions.boolean.length).toBe(4)
expect(minimistOptions.alias.c).toBe('config-file')
- expect(minimistOptions.default.c).toBe(Options['config-file'].default)
+ expect(minimistOptions.default.c).toBe(common['config-file'].default)
})
test('parses args', () => {
- const cmd = new Command({
- options: Object.keys(Options)
- })
+ const cmd = new Command({ options: { ...common, ...server } })
let args = ['-c', 'test-file', '-s', '-p', '3001']
let argv = cmd.getArgv(args)
@@ -41,7 +33,6 @@ describe('cli/command', () => {
expect(argv['config-file']).toBe(args[1])
expect(argv.spa).toBe(true)
expect(argv.universal).toBe(false)
- expect(argv.build).toBe(true)
expect(argv.port).toBe('3001')
args = ['--no-build']
@@ -61,7 +52,7 @@ describe('cli/command', () => {
})
test('prints help automatically', () => {
- const cmd = new Command()
+ const cmd = new Command({ options: allOptions })
cmd.showHelp = jest.fn()
const args = ['-h']
@@ -71,9 +62,7 @@ describe('cli/command', () => {
})
test('returns nuxt config', async () => {
- const cmd = new Command({
- options: Object.keys(Options)
- })
+ const cmd = new Command({ options: allOptions })
const args = ['-c', 'test-file', '-a', '-p', '3001', '-q', '-H']
const argv = cmd.getArgv(args)
@@ -83,8 +72,6 @@ describe('cli/command', () => {
expect(options.testOption).toBe(true)
expect(options.server.port).toBe(3001)
- expect(options.build.quiet).toBe(true)
- expect(options.build.analyze).toBe(true)
expect(consola.fatal).toHaveBeenCalledWith('Provided hostname argument has no value') // hostname check
})
@@ -117,26 +104,17 @@ describe('cli/command', () => {
description: 'a very long description that is longer than 80 chars and ' +
'should wrap to the next line while keeping indentation',
usage: 'this is how you do it',
- options: ['build']
+ options: {
+ ...allOptions,
+ foo: {
+ type: 'boolean',
+ description: 'very long option that is longer than 80 chars and ' +
+ 'should wrap to the next line while keeping indentation'
+ }
+ }
})
- const expectedText = `
- Description
- a very long description that is longer than 80 chars and should wrap to the next
- line while keeping indentation
- Usage
- $ nuxt this is how you do it
- Options
- --no-build Only generate pages for dynamic routes. Nuxt has to be
- built once before using this option
- --spa, -s Launch in SPA mode
- --universal, -u Launch in Universal mode (default)
- --config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
- --version Display the Nuxt version
- --help, -h Display this message
-
-`
- expect(cmd._getHelp()).toBe(expectedText)
+ expect(cmd._getHelp()).toMatchSnapshot()
})
test('show version prints to stdout and exits', () => {
diff --git a/packages/cli/test/unit/dev.test.js b/packages/cli/test/unit/dev.test.js
index 30a623b350..dad9e2011b 100644
--- a/packages/cli/test/unit/dev.test.js
+++ b/packages/cli/test/unit/dev.test.js
@@ -1,26 +1,23 @@
-import { consola, mockNuxt, mockBuilder, mockGetNuxtConfig } from '../utils'
+import { consola, mockNuxt, mockBuilder, mockGetNuxtConfig, NuxtCommand } from '../utils'
describe('dev', () => {
let dev
beforeAll(async () => {
- dev = await import('../../src/commands/dev')
- dev = dev.default
+ dev = await import('../../src/commands/dev').then(m => m.default)
})
- afterEach(() => {
- jest.clearAllMocks()
- })
+ afterEach(() => jest.clearAllMocks())
- test('is function', () => {
- expect(typeof dev).toBe('function')
+ test('has run function', () => {
+ expect(typeof dev.run).toBe('function')
})
test('reloads on fileChanged hook', async () => {
const Nuxt = mockNuxt()
const Builder = mockBuilder()
- await dev()
+ await NuxtCommand.from(dev).run()
expect(consola.error).not.toHaveBeenCalled()
@@ -51,7 +48,7 @@ describe('dev', () => {
const Nuxt = mockNuxt()
const Builder = mockBuilder()
- await dev()
+ await NuxtCommand.from(dev).run()
jest.clearAllMocks()
// Test error on second build so we cover oldInstance stuff
@@ -68,7 +65,7 @@ describe('dev', () => {
const Nuxt = mockNuxt()
const Builder = mockBuilder()
- await dev()
+ await NuxtCommand.from(dev).run()
jest.clearAllMocks()
const builder = new Builder()
@@ -84,7 +81,7 @@ describe('dev', () => {
const Nuxt = mockNuxt()
const Builder = mockBuilder()
- await dev()
+ await NuxtCommand.from(dev).run()
jest.clearAllMocks()
mockGetNuxtConfig().mockImplementationOnce(() => {
@@ -106,7 +103,7 @@ describe('dev', () => {
})
mockBuilder()
- await dev()
+ await NuxtCommand.from(dev).run()
expect(consola.error).toHaveBeenCalledWith(new Error('Listen Error'))
})
diff --git a/packages/cli/test/unit/generate.test.js b/packages/cli/test/unit/generate.test.js
index 42b8f0d141..4e4cd9bfee 100644
--- a/packages/cli/test/unit/generate.test.js
+++ b/packages/cli/test/unit/generate.test.js
@@ -1,33 +1,26 @@
-import { consola, mockGetNuxt, mockGetGenerator } from '../utils'
+import { consola, mockGetNuxt, mockGetGenerator, NuxtCommand } from '../utils'
import Command from '../../src/command'
describe('generate', () => {
let generate
beforeAll(async () => {
- generate = await import('../../src/commands/generate')
- generate = generate.default
-
+ generate = await import('../../src/commands/generate').then(m => m.default)
jest.spyOn(process, 'exit').mockImplementation(code => code)
})
- afterAll(() => {
- process.exit.mockRestore()
- })
+ afterAll(() => process.exit.mockRestore())
+ afterEach(() => jest.resetAllMocks())
- afterEach(() => {
- jest.resetAllMocks()
- })
-
- test('is function', () => {
- expect(typeof generate).toBe('function')
+ test('has run function', () => {
+ expect(typeof generate.run).toBe('function')
})
test('builds by default', async () => {
mockGetNuxt()
const generator = mockGetGenerator(Promise.resolve())
- await generate()
+ await NuxtCommand.from(generate).run()
expect(generator).toHaveBeenCalled()
expect(generator.mock.calls[0][0].build).toBe(true)
@@ -46,7 +39,7 @@ describe('generate', () => {
})
const generator = mockGetGenerator(Promise.resolve())
- await generate()
+ await NuxtCommand.from(generate).run()
expect(generator).toHaveBeenCalled()
expect(generator.mock.calls[0][0].build).toBe(false)
@@ -57,7 +50,7 @@ describe('generate', () => {
mockGetNuxt()
mockGetGenerator(Promise.reject(new Error('Generator Error')))
- await generate()
+ await NuxtCommand.from(generate).run()
expect(consola.fatal).toHaveBeenCalledWith(new Error('Generator Error'))
})
diff --git a/packages/cli/test/unit/start.test.js b/packages/cli/test/unit/start.test.js
index 876b50eb6b..4568ac0eca 100644
--- a/packages/cli/test/unit/start.test.js
+++ b/packages/cli/test/unit/start.test.js
@@ -1,29 +1,27 @@
import fs from 'fs'
-import { consola, mockGetNuxtStart, mockGetNuxtConfig } from '../utils'
+import { consola, mockGetNuxtStart, mockGetNuxtConfig, NuxtCommand } from '../utils'
describe('start', () => {
let start
beforeAll(async () => {
- start = await import('../../src/commands/start')
- start = start.default
+ start = await import('../../src/commands/start').then(m => m.default)
})
afterEach(() => {
if (fs.existsSync.mockRestore) {
fs.existsSync.mockRestore()
}
-
jest.resetAllMocks()
})
- test('is function', () => {
- expect(typeof start).toBe('function')
+ test('has run function', () => {
+ expect(typeof start.run).toBe('function')
})
test('starts listening and calls showReady', async () => {
const { listen, showReady } = mockGetNuxtStart()
- await start()
+ await NuxtCommand.from(start).run()
expect(listen).toHaveBeenCalled()
expect(showReady).toHaveBeenCalled()
@@ -34,7 +32,7 @@ describe('start', () => {
mockGetNuxtConfig()
jest.spyOn(fs, 'existsSync').mockImplementationOnce(() => true)
- await start()
+ await NuxtCommand.from(start).run()
expect(consola.fatal).not.toHaveBeenCalled()
})
@@ -43,7 +41,7 @@ describe('start', () => {
mockGetNuxtStart()
jest.spyOn(fs, 'existsSync').mockImplementationOnce(() => false)
- await start()
+ await NuxtCommand.from(start).run()
expect(consola.fatal).toHaveBeenCalledWith('No build files found, please run `nuxt build` before launching `nuxt start`')
})
@@ -53,7 +51,7 @@ describe('start', () => {
mockGetNuxtConfig()
jest.spyOn(fs, 'existsSync').mockImplementation(() => true)
- await start()
+ await NuxtCommand.from(start).run()
expect(consola.fatal).not.toHaveBeenCalled()
})
@@ -62,7 +60,7 @@ describe('start', () => {
mockGetNuxtStart(true)
jest.spyOn(fs, 'existsSync').mockImplementation(() => false)
- await start()
+ await NuxtCommand.from(start).run()
expect(consola.fatal).toHaveBeenCalledWith('No SSR build! Please start with `nuxt start --spa` or build using `nuxt build --universal`')
})
diff --git a/packages/cli/test/unit/utils.test.js b/packages/cli/test/unit/utils.test.js
index e7a5cd50e1..b1a1bf00c5 100644
--- a/packages/cli/test/unit/utils.test.js
+++ b/packages/cli/test/unit/utils.test.js
@@ -3,9 +3,7 @@ import { consola } from '../utils'
import * as utils from '../../src/utils'
describe('cli/utils', () => {
- afterEach(() => {
- jest.resetAllMocks()
- })
+ afterEach(() => jest.resetAllMocks())
test('loadNuxtConfig: defaults', async () => {
const argv = {
diff --git a/packages/cli/test/utils/index.js b/packages/cli/test/utils/index.js
index e31e09d6c0..ba9acd8c08 100644
--- a/packages/cli/test/utils/index.js
+++ b/packages/cli/test/utils/index.js
@@ -1,5 +1,6 @@
import consola from 'consola'
export * from './mocking'
+export { NuxtCommand } from '../../src'
jest.mock('consola')