UNPKG

4.25 kBPlain TextView Raw
1#!/usr/bin/env node
2/* eslint-disable no-console */
3
4// Show logs
5process.env.DEBUG = process.env.DEBUG || 'nuxt:*'
6
7const _ = require('lodash')
8const debug = require('debug')('nuxt:build')
9debug.color = 2 // force green color
10const fs = require('fs')
11const parseArgs = require('minimist')
12const { Nuxt, Builder } = require('../')
13const chokidar = require('chokidar')
14const path = require('path')
15const resolve = path.resolve
16const pkg = require(path.join('..', 'package.json'))
17
18const argv = parseArgs(process.argv.slice(2), {
19 alias: {
20 h: 'help',
21 H: 'hostname',
22 p: 'port',
23 c: 'config-file',
24 s: 'spa',
25 u: 'universal',
26 v: 'version'
27 },
28 boolean: ['h', 's', 'u', 'v'],
29 string: ['H', 'c'],
30 default: {
31 c: 'nuxt.config.js'
32 }
33})
34
35if (argv.version) {
36 console.log(pkg.version)
37 process.exit(0)
38}
39
40if (argv.hostname === '') {
41 console.error(`> Provided hostname argument has no value`)
42 process.exit(1)
43}
44
45if (argv.help) {
46 console.log(`
47 Description
48 Starts the application in development mode (hot-code reloading, error
49 reporting, etc)
50 Usage
51 $ nuxt dev <dir> -p <port number> -H <hostname>
52 Options
53 --port, -p A port number on which to start the application
54 --hostname, -H Hostname on which to start the application
55 --spa Launch in SPA mode
56 --universal Launch in Universal mode (default)
57 --config-file, -c Path to Nuxt.js config file (default: nuxt.config.js)
58 --help, -h Displays this message
59 `)
60 process.exit(0)
61}
62
63const rootDir = resolve(argv._[0] || '.')
64const nuxtConfigFile = resolve(rootDir, argv['config-file'])
65
66// Load config once for chokidar
67const nuxtConfig = loadNuxtConfig()
68_.defaultsDeep(nuxtConfig, { watchers: { chokidar: { ignoreInitial: true } } })
69
70// Start dev
71let dev = startDev()
72let needToRestart = false
73
74// Start watching for nuxt.config.js changes
75chokidar
76 .watch(nuxtConfigFile, nuxtConfig.watchers.chokidar)
77 .on('all', () => {
78 debug('[nuxt.config.js] changed')
79 needToRestart = true
80
81 dev = dev.then((instance) => {
82 if (needToRestart === false) return instance
83 needToRestart = false
84
85 debug('Rebuilding the app...')
86 return startDev(instance)
87 })
88 })
89
90function startDev(oldInstance) {
91 // Get latest environment variables
92 const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
93 const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
94
95 // Error handler
96 const onError = (err, instance) => {
97 debug('Error while reloading [nuxt.config.js]', err)
98 return Promise.resolve(instance) // Wait for next reload
99 }
100
101 // Load options
102 let options = {}
103 try {
104 options = loadNuxtConfig()
105 } catch (err) {
106 return onError(err, oldInstance)
107 }
108
109 // Create nuxt and builder instance
110 let nuxt
111 let builder
112 let instance
113 try {
114 nuxt = new Nuxt(options)
115 builder = new Builder(nuxt)
116 instance = { nuxt: nuxt, builder: builder }
117 } catch (err) {
118 return onError(err, instance || oldInstance)
119 }
120
121 return Promise.resolve()
122 .then(() => oldInstance && oldInstance.builder ? oldInstance.builder.unwatch() : Promise.resolve())
123 // Start build
124 .then(() => builder.build())
125 // Close old nuxt after successful build
126 .then(() => oldInstance && oldInstance.nuxt ? oldInstance.nuxt.close() : Promise.resolve())
127 // Start listening
128 .then(() => nuxt.listen(port, host))
129 // Pass new nuxt to watch chain
130 .then(() => instance)
131 // Handle errors
132 .catch((err) => onError(err, instance))
133}
134
135function loadNuxtConfig() {
136 let options = {}
137
138 if (fs.existsSync(nuxtConfigFile)) {
139 delete require.cache[nuxtConfigFile]
140 options = require(nuxtConfigFile)
141 } else if (argv['config-file'] !== 'nuxt.config.js') {
142 console.error(`> Could not load config file ${argv['config-file']}`)
143 process.exit(1)
144 }
145
146 if (typeof options.rootDir !== 'string') {
147 options.rootDir = rootDir
148 }
149
150 // Force development mode for add hot reloading and watching changes
151 options.dev = true
152
153 // Nuxt Mode
154 options.mode = (argv['spa'] && 'spa') || (argv['universal'] && 'universal') || options.mode
155
156 return options
157}