misc: add user-defined chokidar files to watch (2) (#3633)

* misc: add user-defined chokidar files to watch

* Improved user-defined chokidar files setup

* Improved user-defined chokidar files setup (2)

* Added custom file for CLI watch test

* Added cli.dev.test.js

* Added cli.dev.test.js (2)

* Remove cli-start/cli.dev, just use cli.test

* Refactored CLI test

* Missing dot in fname

* Improved user-defined chokidar files setup (3)

* Fix killNuxt()

* Remove genHandlers

* Refactored CLI test (2)

* Refactor exitCode

* Remove debugging code

* Remove debugging code (2)

* Linting

* Linting (2)

* Disable nuxt-start test for now

* Disable nuxt-start test for now (2)

* Tweaking nuxt-start test

* Tweaking nuxt-start test (2)

* Tweaking nuxt-start test (3)

* Fix ext

* Tweaked wait params

* Fix conflicts

*  hotfix

* nuxt-dev tweak

* Add blank line after variables declaration

* Disable waitFor() test due to random failure in appveyor

* Fixed error msg

* Refactored into builder.js

* Refactored into builder.js (2)

* Remove unnecessary import from nuxt-dev

* Fixed nuxt-dev test

* Debugging nuxt-dev test

* Debugging nuxt-dev test (2)

* Skip in appveyor

* Linting

* Requested changes

* Hook into nuxt-dev

* Hook into nuxt-dev (2)

* Get fname

* Get fname (2)

* Get fname (3)

* Change hook name

* Fixed conflict
This commit is contained in:
Jonas Galvez 2018-08-08 15:51:57 -03:00 committed by Clark Du
parent 7349adde18
commit a522aaf125
7 changed files with 87 additions and 114 deletions

View File

@ -1,5 +1,4 @@
#!/usr/bin/env node
const defaultsDeep = require('lodash/defaultsDeep')
const parseArgs = require('minimist')
const chokidar = require('chokidar')
const consola = require('consola')
@ -53,27 +52,10 @@ if (argv.help) {
// Load config once for chokidar
const nuxtConfig = loadNuxtConfig(argv)
defaultsDeep(nuxtConfig, { watchers: { chokidar: { ignoreInitial: true } } })
// Start dev
let hooked = false
let dev = startDev()
let needToRestart = false
// Start watching for nuxt.config.js changes
chokidar
.watch(nuxtConfigFile(argv), nuxtConfig.watchers.chokidar)
.on('all', () => {
consola.debug('[nuxt.config.js] changed')
needToRestart = true
dev = dev.then(instance => {
if (needToRestart === false) return instance
needToRestart = false
consola.debug('Rebuilding the app...')
return startDev(instance)
})
})
function startDev(oldInstance) {
// Get latest environment variables
@ -105,6 +87,17 @@ function startDev(oldInstance) {
return onError(err, oldInstance)
}
if (!hooked) {
nuxt.hook('watch:fileChanged', (fname) => {
consola.debug(`[${fname}] changed`)
dev = dev.then((instance) => {
consola.debug('Rebuilding the app...')
return startDev(instance)
})
})
hooked = true
}
return (
Promise.resolve()
.then(() => {

View File

@ -37,6 +37,7 @@ export default class Builder {
this.webpackHotMiddleware = null
this.filesWatcher = null
this.customFilesWatcher = null
this.nuxtRestartWatcher = null
this.perfLoader = null
// Helper to resolve build paths
@ -622,6 +623,22 @@ export default class Builder {
this.customFilesWatcher = chokidar
.watch(customPatterns, options)
.on('change', refreshFiles)
// Watch for nuxt.config.js and user-defined changes
const restartServer = _.debounce((fname) => {
this.nuxt.callHook('watch:fileChanged', fname)
})
const nuxtRestartWatch = _.concat(
this.options.watch,
path.join(this.options.rootDir, 'nuxt.config.js')
)
this.nuxtRestartWatcher = chokidar
.watch(nuxtRestartWatch, options)
.on('change', (event, _path) => {
const parsedPath = path.parse(_path)
restartServer(`${parsedPath.base}${parsedPath.ext}`)
})
}
async unwatch() {
@ -633,6 +650,10 @@ export default class Builder {
this.customFilesWatcher.close()
}
if (this.nuxtRestartWatcher) {
this.nuxtRestartWatcher.close()
}
this.compilersWatching.forEach(watching => watching.close())
// Stop webpack middleware

View File

@ -186,6 +186,8 @@ export default {
},
csp: false
},
// User-defined changes
watch: [],
watchers: {
webpack: {},
chokidar: {}

1
test/fixtures/cli/custom.file vendored Normal file
View File

@ -0,0 +1 @@
This file is used to test custom chokidar watchers.

3
test/fixtures/cli/nuxt.config.js vendored Normal file
View File

@ -0,0 +1,3 @@
export default {
watch: ['./custom.file']
}

View File

@ -1,64 +0,0 @@
import { spawn } from 'child_process'
import { resolve } from 'path'
import { getPort, rp, waitUntil } from '../utils'
let port
const rootDir = resolve(__dirname, '..', 'fixtures/cli')
const url = route => 'http://localhost:' + port + route
const nuxtBin = resolve(__dirname, '..', '..', 'bin', 'nuxt')
describe.skip.appveyor('cli', () => {
test('nuxt start', async () => {
let stdout = ''
let error
let exitCode
const env = process.env
env.PORT = port = await getPort()
const nuxtStart = spawn('node', [nuxtBin, 'start', rootDir], { env })
nuxtStart.stdout.on('data', (data) => {
stdout += data
})
nuxtStart.on('error', (err) => {
error = err
})
nuxtStart.on('close', (code) => {
exitCode = code
})
// Wait max 20s for the starting
let timeout = await waitUntil(() => stdout.includes('Listening on'))
if (timeout === true) {
error = 'server failed to start successfully in 20 seconds'
}
expect(error).toBe(undefined)
expect(stdout.includes('Listening on ')).toBe(true)
expect(stdout.includes(`http://localhost:${port}`)).toBe(true)
const html = await rp(url('/'))
expect(html).toMatch(('<div>CLI Test</div>'))
nuxtStart.kill()
// Wait max 10s for the process to be killed
timeout = await waitUntil(() => exitCode !== undefined, 10)
if (timeout === true) {
console.warn( // eslint-disable-line no-console
`we were unable to automatically kill the child process with pid: ${
nuxtStart.pid
}`
)
}
expect(exitCode).toBe(undefined)
})
})

View File

@ -1,41 +1,71 @@
import { spawn } from 'child_process'
import { resolve } from 'path'
import { resolve, join } from 'path'
import { writeFileSync } from 'fs-extra'
import { getPort, rp, waitUntil } from '../utils'
let port
const rootDir = resolve(__dirname, '..', 'fixtures/cli')
const url = route => 'http://localhost:' + port + route
const nuxtBin = resolve(__dirname, '..', '..', 'bin', 'nuxt')
const killNuxt = async (nuxtInt) => {
let exitCode
nuxtInt.on('close', (code) => { exitCode = code })
nuxtInt.kill()
// Wait max 10s for the process to be killed
if (await waitUntil(() => exitCode !== undefined, 10)) {
console.warn( // eslint-disable-line no-console
`we were unable to automatically kill the child process with pid: ${
nuxtInt.pid
}`
)
}
}
describe.skip.appveyor('cli', () => {
test('nuxt dev', async () => {
let stdout = ''
const env = process.env
env.PORT = port = await getPort()
const nuxtDev = spawn('node', [nuxtBin, 'dev', rootDir], { env })
nuxtDev.stdout.on('data', (data) => { stdout += data })
// Wait max 20s for the starting
await waitUntil(() => stdout.includes(`${port}`))
// Change file specified in `watchers` (nuxt.config.js)
const customFilePath = join(rootDir, 'custom.file')
writeFileSync(customFilePath, 'This file is used to test custom chokidar watchers.')
// Must see two compilations in the log
expect(
stdout.indexOf('Compiled client') !==
stdout.lastIndexOf('Compiled client')
)
await killNuxt(nuxtDev)
})
test('nuxt start', async () => {
let stdout = ''
let error
let exitCode
const env = process.env
env.PORT = port = await getPort()
await new Promise((resolve) => {
const nuxtBuild = spawn('node', [nuxtBin, 'build', rootDir], { env })
nuxtBuild.on('close', () => { resolve() })
})
const nuxtStart = spawn('node', [nuxtBin, 'start', rootDir], { env })
nuxtStart.stdout.on('data', (data) => {
stdout += data
})
nuxtStart.on('error', (err) => {
error = err
})
nuxtStart.on('close', (code) => {
exitCode = code
})
nuxtStart.stdout.on('data', (data) => { stdout += data })
nuxtStart.on('error', (err) => { error = err })
// Wait max 20s for the starting
let timeout = await waitUntil(() => stdout.includes('Listening on'))
if (timeout === true) {
if (await waitUntil(() => stdout.includes(`${port}`))) {
error = 'server failed to start successfully in 20 seconds'
}
@ -45,19 +75,6 @@ describe.skip.appveyor('cli', () => {
const html = await rp(url('/'))
expect(html).toMatch(('<div>CLI Test</div>'))
nuxtStart.kill()
// Wait max 10s for the process to be killed
timeout = await waitUntil(() => exitCode !== undefined, 10)
if (timeout === true) {
console.warn( // eslint-disable-line no-console
`we were unable to automatically kill the child process with pid: ${
nuxtStart.pid
}`
)
}
expect(exitCode).toBe(undefined)
await killNuxt(nuxtStart)
})
})