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') debug('[nuxt.config.js] changed')
needToRestart = true needToRestart = true
dev = dev.then((nuxt) => { dev = dev.then((instance) => {
if (needToRestart === false) return nuxt if (needToRestart === false) return instance
needToRestart = false needToRestart = false
debug('Rebuilding the app...') debug('Rebuilding the app...')
return startDev(nuxt) return startDev(instance)
}) })
}) })
function startDev(oldNuxt) { function startDev(oldInstance) {
// Get latest environment variables // Get latest environment variables
const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port 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 const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
// Error handler // Error handler
const onError = (err, nuxt) => { const onError = (err, instance) => {
debug('Error while reloading [nuxt.config.js]', err) 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 // Load options
@ -103,30 +103,33 @@ function startDev(oldNuxt) {
try { try {
options = loadNuxtConfig() options = loadNuxtConfig()
} catch (err) { } catch (err) {
return onError(err, oldNuxt) return onError(err, oldInstance)
} }
// Create nuxt and builder instance // Create nuxt and builder instance
let nuxt let nuxt
let builder let builder
let instance
try { try {
nuxt = new Nuxt(options) nuxt = new Nuxt(options)
builder = new Builder(nuxt) builder = new Builder(nuxt)
instance = { nuxt: nuxt, builder: builder }
} catch (err) { } catch (err) {
return onError(err, nuxt || oldNuxt) return onError(err, instance || oldInstance)
} }
return Promise.resolve() return Promise.resolve()
.then(() => oldInstance && oldInstance.builder ? oldInstance.builder.unwatch() : Promise.resolve())
// Start build // Start build
.then(() => builder.build()) .then(() => builder.build())
// Close old nuxt after successful build // Close old nuxt after successful build
.then(() => oldNuxt ? oldNuxt.close() : Promise.resolve()) .then(() => oldInstance && oldInstance.nuxt ? oldInstance.nuxt.close() : Promise.resolve())
// Start listening // Start listening
.then(() => nuxt.listen(port, host)) .then(() => nuxt.listen(port, host))
// Pass new nuxt to watch chain // Pass new nuxt to watch chain
.then(() => nuxt) .then(() => instance)
// Handle errors // Handle errors
.catch((err) => onError(err, nuxt)) .catch((err) => onError(err, instance))
} }
function loadNuxtConfig() { function loadNuxtConfig() {

View File

@ -31,8 +31,11 @@ export default class Builder {
// Fields that set on build // Fields that set on build
this.compilers = [] this.compilers = []
this.compilersWatching = []
this.webpackDevMiddleware = null this.webpackDevMiddleware = null
this.webpackHotMiddleware = null this.webpackHotMiddleware = null
this.filesWatcher = null
this.customFilesWatcher = null
// Mute stats on dev // Mute stats on dev
this.webpackStats = this.options.dev ? false : { this.webpackStats = this.options.dev ? false : {
@ -55,6 +58,30 @@ export default class Builder {
this.vueLoader = vueLoaderConfig.bind(this) this.vueLoader = vueLoaderConfig.bind(this)
this._buildStatus = STATUS.INITIAL 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() { get plugins() {
@ -449,16 +476,12 @@ export default class Builder {
return return
} }
// Server, build and watch for changes // Server, build and watch for changes
const watching = compiler.watch(this.options.watchers.webpack, (err) => { this.compilersWatching.push(
/* istanbul ignore if */ compiler.watch(this.options.watchers.webpack, (err) => {
if (err) return reject(err) /* istanbul ignore if */
}) if (err) return reject(err)
})
// Stop watching on nuxt.close() )
this.nuxt.hook('close', () => {
watching.close()
})
return return
} }
// --- Production Build --- // --- Production Build ---
@ -503,11 +526,6 @@ export default class Builder {
this.nuxt.renderer.webpackHotMiddleware = this.webpackHotMiddleware 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 // Start watching files
this.watchFiles() this.watchFiles()
} }
@ -532,19 +550,13 @@ export default class Builder {
const refreshFiles = _.debounce(() => this.generateRoutesAndFiles(), 200) const refreshFiles = _.debounce(() => this.generateRoutesAndFiles(), 200)
// Watch for src Files // Watch for src Files
let filesWatcher = chokidar.watch(patterns, options) this.filesWatcher = chokidar.watch(patterns, options)
.on('add', refreshFiles) .on('add', refreshFiles)
.on('unlink', refreshFiles) .on('unlink', refreshFiles)
// Watch for custom provided files // 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) .on('change', refreshFiles)
// Stop watching on nuxt.close()
this.nuxt.hook('close', () => {
filesWatcher.close()
customFilesWatcher.close()
})
} }
} }