diff --git a/bin/nuxt-dev b/bin/nuxt-dev index b2502e1da5..b8817cb627 100755 --- a/bin/nuxt-dev +++ b/bin/nuxt-dev @@ -78,24 +78,24 @@ chokidar debug('[nuxt.config.js] changed') needToRestart = true - dev = dev.then((nuxt) => { - if (needToRestart === false) return nuxt + dev = dev.then((instance) => { + if (needToRestart === false) return instance needToRestart = false debug('Rebuilding the app...') - return startDev(nuxt) + return startDev(instance) }) }) -function startDev(oldNuxt) { +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, nuxt) => { + const onError = (err, instance) => { debug('Error while reloading [nuxt.config.js]', err) - return Promise.resolve(nuxt) // Wait for next reload + return Promise.resolve(instance) // Wait for next reload } // Load options @@ -103,30 +103,33 @@ function startDev(oldNuxt) { try { options = loadNuxtConfig() } catch (err) { - return onError(err, oldNuxt) + 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, nuxt || oldNuxt) + 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(() => oldNuxt ? oldNuxt.close() : Promise.resolve()) + .then(() => oldInstance && oldInstance.nuxt ? oldInstance.nuxt.close() : Promise.resolve()) // Start listening .then(() => nuxt.listen(port, host)) // Pass new nuxt to watch chain - .then(() => nuxt) + .then(() => instance) // Handle errors - .catch((err) => onError(err, nuxt)) + .catch((err) => onError(err, instance)) } function loadNuxtConfig() { diff --git a/lib/builder/builder.js b/lib/builder/builder.js index bc01da580a..bc79f3d96b 100644 --- a/lib/builder/builder.js +++ b/lib/builder/builder.js @@ -31,8 +31,11 @@ export default class Builder { // Fields that set on build this.compilers = [] + this.compilersWatching = [] this.webpackDevMiddleware = null this.webpackHotMiddleware = null + this.filesWatcher = null + this.customFilesWatcher = null // Mute stats on dev this.webpackStats = this.options.dev ? false : { @@ -55,6 +58,30 @@ export default class Builder { this.vueLoader = vueLoaderConfig.bind(this) this._buildStatus = STATUS.INITIAL + + // Stop watching on nuxt.close() + this.nuxt.hook('close', () => this.unwatch()) + } + + unwatch() { + if (this.filesWatcher) { + this.filesWatcher.close() + } + + if (this.customFilesWatcher) { + this.customFilesWatcher.close() + } + + this.compilersWatching.forEach((watching) => watching.close()) + + // Stop webpack middleware + return new Promise(resolve => { + if (this.webpackDevMiddleware) { + this.webpackDevMiddleware.close(() => resolve()) + } else { + resolve() + } + }) } get plugins() { @@ -449,16 +476,12 @@ export default class Builder { return } // Server, build and watch for changes - const watching = compiler.watch(this.options.watchers.webpack, (err) => { - /* istanbul ignore if */ - if (err) return reject(err) - }) - - // Stop watching on nuxt.close() - this.nuxt.hook('close', () => { - watching.close() - }) - + this.compilersWatching.push( + compiler.watch(this.options.watchers.webpack, (err) => { + /* istanbul ignore if */ + if (err) return reject(err) + }) + ) return } // --- Production Build --- @@ -503,11 +526,6 @@ export default class Builder { this.nuxt.renderer.webpackHotMiddleware = this.webpackHotMiddleware } - // Stop webpack middleware on nuxt.close() - this.nuxt.hook('close', () => new Promise(resolve => { - this.webpackDevMiddleware.close(() => resolve()) - })) - // Start watching files this.watchFiles() } @@ -532,19 +550,13 @@ export default class Builder { const refreshFiles = _.debounce(() => this.generateRoutesAndFiles(), 200) // Watch for src Files - let filesWatcher = chokidar.watch(patterns, options) + this.filesWatcher = chokidar.watch(patterns, options) .on('add', refreshFiles) .on('unlink', refreshFiles) // Watch for custom provided files - let customFilesWatcher = chokidar.watch(_.uniq(this.options.build.watch), options) + this.customFilesWatcher = chokidar.watch(_.uniq(this.options.build.watch), options) .on('change', refreshFiles) - - // Stop watching on nuxt.close() - this.nuxt.hook('close', () => { - filesWatcher.close() - customFilesWatcher.close() - }) } }