1 | #!/usr/bin/env node
|
2 | /* eslint-disable no-console */
|
3 |
|
4 | // Show logs
|
5 | process.env.DEBUG = process.env.DEBUG || 'nuxt:*'
|
6 |
|
7 | const _ = require('lodash')
|
8 | const debug = require('debug')('nuxt:build')
|
9 | debug.color = 2 // force green color
|
10 | const fs = require('fs')
|
11 | const parseArgs = require('minimist')
|
12 | const { Nuxt, Builder } = require('../')
|
13 | const chokidar = require('chokidar')
|
14 | const path = require('path')
|
15 | const resolve = path.resolve
|
16 | const pkg = require(path.join('..', 'package.json'))
|
17 |
|
18 | const 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 |
|
35 | if (argv.version) {
|
36 | console.log(pkg.version)
|
37 | process.exit(0)
|
38 | }
|
39 |
|
40 | if (argv.hostname === '') {
|
41 | console.error(`> Provided hostname argument has no value`)
|
42 | process.exit(1)
|
43 | }
|
44 |
|
45 | if (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 |
|
63 | const rootDir = resolve(argv._[0] || '.')
|
64 | const nuxtConfigFile = resolve(rootDir, argv['config-file'])
|
65 |
|
66 | // Load config once for chokidar
|
67 | const nuxtConfig = loadNuxtConfig()
|
68 | _.defaultsDeep(nuxtConfig, { watchers: { chokidar: { ignoreInitial: true } } })
|
69 |
|
70 | // Start dev
|
71 | let dev = startDev()
|
72 | let needToRestart = false
|
73 |
|
74 | // Start watching for nuxt.config.js changes
|
75 | chokidar
|
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 |
|
90 | function 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 |
|
135 | function 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 | }
|