#!/usr/bin/env node /* eslint-disable no-console */ const _ = require('lodash') const debug = require('debug')('nuxt:build') debug.color = 2 // force green color const fs = require('fs') const parseArgs = require('minimist') const { Nuxt, Builder, Utils } = require('..') const chokidar = require('chokidar') const path = require('path') const resolve = path.resolve const pkg = require(path.join('..', 'package.json')) const argv = parseArgs(process.argv.slice(2), { alias: { h: 'help', H: 'hostname', p: 'port', c: 'config-file', s: 'spa', u: 'universal', v: 'version' }, boolean: ['h', 's', 'u', 'v'], string: ['H', 'c'], default: { c: 'nuxt.config.js' } }) if (argv.version) { console.log(pkg.version) process.exit(0) } if (argv.hostname === '') { Utils.fatalError('Provided hostname argument has no value') } if (argv.help) { console.log(` Description Starts the application in development mode (hot-code reloading, error reporting, etc) Usage $ nuxt dev -p -H Options --port, -p A port number on which to start the application --hostname, -H Hostname on which to start the application --spa Launch in SPA mode --universal Launch in Universal mode (default) --config-file, -c Path to Nuxt.js config file (default: nuxt.config.js) --help, -h Displays this message `) process.exit(0) } const rootDir = resolve(argv._[0] || '.') const nuxtConfigFile = resolve(rootDir, argv['config-file']) // Load config once for chokidar const nuxtConfig = loadNuxtConfig() _.defaultsDeep(nuxtConfig, { watchers: { chokidar: { ignoreInitial: true } } }) // Start dev let dev = startDev() let needToRestart = false // Start watching for nuxt.config.js changes chokidar.watch(nuxtConfigFile, nuxtConfig.watchers.chokidar).on('all', () => { debug('[nuxt.config.js] changed') needToRestart = true dev = dev.then(instance => { if (needToRestart === false) return instance needToRestart = false debug('Rebuilding the app...') return startDev(instance) }) }) function startDev(oldInstance) { // Get latest environment variables const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host // Error handler const onError = (err, instance) => { Utils.printError(err) return Promise.resolve(instance) // Wait for next reload } // Load options let options = {} try { options = loadNuxtConfig() } catch (err) { return onError(err, oldInstance) } // Create nuxt and builder instance let nuxt let builder let instance try { nuxt = new Nuxt(options) builder = new Builder(nuxt) instance = { nuxt: nuxt, builder: builder } } catch (err) { return onError(err, instance || oldInstance) } return ( Promise.resolve() .then( () => oldInstance && oldInstance.builder ? oldInstance.builder.unwatch() : Promise.resolve() ) // Start build .then(() => builder.build()) // Close old nuxt after successful build .then( () => oldInstance && oldInstance.nuxt ? oldInstance.nuxt.close() : Promise.resolve() ) // Start listening .then(() => nuxt.listen(port, host)) // Pass new nuxt to watch chain .then(() => instance) // Handle errors .catch(err => onError(err, instance)) ) } function loadNuxtConfig() { let options = {} if (fs.existsSync(nuxtConfigFile)) { delete require.cache[nuxtConfigFile] options = require(nuxtConfigFile) } else if (argv['config-file'] !== 'nuxt.config.js') { Utils.fatalError('Could not load config file: ' + argv['config-file']) } if (typeof options.rootDir !== 'string') { options.rootDir = rootDir } // Force development mode for add hot reloading and watching changes options.dev = true // Nuxt Mode options.mode = (argv['spa'] && 'spa') || (argv['universal'] && 'universal') || options.mode return options }