Merge pull request #2199 from 0pt1m1z3r/nuxt-dev-fix-double-compile

Prevent double compile on nuxt.config.js update
This commit is contained in:
Sébastien Chopin 2017-11-23 13:36:56 +01:00 committed by GitHub
commit 3764dc73c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 34 deletions

View File

@ -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() {

View File

@ -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()
})
}
}