refacto: Refacto nuxt.build() to finish after webpack is done

This commit is contained in:
Atinux 2017-10-30 15:42:59 +01:00
parent c688fc06d9
commit 379d4f72d4
3 changed files with 56 additions and 97 deletions

View File

@ -406,19 +406,14 @@ export default class Builder extends Tapable {
}
})
// Make a dll plugin after compile to make next dev builds faster
// Make a dll plugin after compile to make nuxt dev builds faster
if (this.options.build.dll && this.options.dev) {
compilersOptions.push(dllWebpackConfig.call(this, clientConfig))
}
// Simulate webpack multi compiler interface
// Separate compilers are simpler, safer and faster
this.compiler = { compilers: [] }
this.compiler.plugin = (...args) => {
this.compiler.compilers.forEach(compiler => {
compiler.plugin(...args)
})
}
this.compilers = []
// Initialize shared FS and Cache
const sharedFS = this.options.dev && new MFS()
@ -427,100 +422,73 @@ export default class Builder extends Tapable {
// Initialize compilers
compilersOptions.forEach(compilersOption => {
const compiler = webpack(compilersOption)
// In dev, write files in memory FS (except for DLL)
if (sharedFS && !compiler.name.includes('-dll')) {
compiler.outputFileSystem = sharedFS
}
compiler.cache = sharedCache
this.compiler.compilers.push(compiler)
this.compilers.push(compiler)
})
// Access to compilers with name
this.compiler.compilers.forEach(compiler => {
if (compiler.name) {
this.compiler[compiler.name] = compiler
}
})
// Run after each compile
this.compiler.plugin('done', async stats => {
// Don't reload failed builds
/* istanbul ignore if */
if (stats.hasErrors()) {
return
}
// console.log(stats.toString({ chunks: true }))
// Reload renderer if available
if (this.nuxt.renderer) {
this.nuxt.renderer.loadResources(sharedFS || fs)
}
await this.applyPluginsAsync('done', { builder: this, stats })
})
// Add dev Stuff
if (this.options.dev) {
this.webpackDev()
}
await this.applyPluginsAsync('compile', { builder: this, compiler: this.compiler })
// Start Builds
await sequence(this.compiler.compilers, compiler => new Promise((resolve, reject) => {
await sequence(this.compilers, (compiler) => new Promise(async (resolve, reject) => {
const name = compiler.options.name
await this.applyPluginsAsync('compile', { builder: this, compiler, name })
// Resolve only when compiler emit done event
compiler.plugin('done', async (stats) => {
await this.applyPluginsAsync('compiled', { builder: this, compiler, name, stats })
process.nextTick(resolve)
})
// --- Dev Build ---
if (this.options.dev) {
// --- Dev Build ---
// Client Build, watch is started by dev-middleware
if (compiler.options.name === 'client') {
// Client watch is started by dev-middleware
resolve()
} else if (compiler.options.name.includes('-dll')) {
// DLL builds should run once
compiler.run((err, stats) => {
if (err) {
return reject(err)
}
debug('[DLL] updated')
resolve()
})
} else {
// Build and watch for changes
compiler.watch(this.options.watchers.webpack, (err) => {
/* istanbul ignore if */
if (err) {
return reject(err)
}
resolve()
})
return this.webpackDev(compiler)
}
} else {
// --- Production Build ---
compiler.run((err, stats) => {
// DLL build, should run only once
if (compiler.options.name.includes('-dll')) {
compiler.run((err, stats) => {
if (err) return reject(err)
debug('[DLL] updated')
})
return
}
// Server, build and watch for changes
compiler.watch(this.options.watchers.webpack, (err) => {
/* istanbul ignore if */
if (err) {
console.error(err) // eslint-disable-line no-console
return reject(err)
}
// Show build stats for production
console.log(stats.toString(this.webpackStats)) // eslint-disable-line no-console
/* istanbul ignore if */
if (stats.hasErrors()) {
return reject(new Error('Webpack build exited with errors'))
}
resolve()
if (err) return reject(err)
})
return
}
}))
// --- Production Build ---
compiler.run((err, stats) => {
/* istanbul ignore if */
if (err) {
console.error(err) // eslint-disable-line no-console
return reject(err)
}
await this.applyPluginsAsync('compiled', this)
// Show build stats for production
console.log(stats.toString(this.webpackStats)) // eslint-disable-line no-console
/* istanbul ignore if */
if (stats.hasErrors()) {
return reject(new Error('Webpack build exited with errors'))
}
})
}))
// Reload renderer if available
if (this.nuxt.renderer) {
this.nuxt.renderer.loadResources(sharedFS || fs)
}
}
webpackDev () {
webpackDev (compiler) {
debug('Adding webpack middleware...')
// Create webpack dev middleware
this.webpackDevMiddleware = pify(webpackDevMiddleware(this.compiler.client, Object.assign({
this.webpackDevMiddleware = pify(webpackDevMiddleware(compiler, Object.assign({
publicPath: this.options.build.publicPath,
stats: this.webpackStats,
noInfo: true,
@ -528,7 +496,7 @@ export default class Builder extends Tapable {
watchOptions: this.options.watchers.webpack
}, this.options.build.devMiddleware)))
this.webpackHotMiddleware = pify(webpackHotMiddleware(this.compiler.client, Object.assign({
this.webpackHotMiddleware = pify(webpackHotMiddleware(compiler, Object.assign({
log: false,
heartbeat: 10000
}, this.options.build.hotMiddleware)))

View File

@ -32,9 +32,6 @@ export default class Nuxt extends Tapable {
this.renderRoute = this.renderer.renderRoute.bind(this.renderer)
this.renderAndGetWindow = this.renderer.renderAndGetWindow.bind(this.renderer)
// Default Show Open if Nuxt is not listening
this.showOpen = () => {}
this._ready = this.ready().catch(this.errorHandler)
}
@ -52,13 +49,6 @@ export default class Nuxt extends Tapable {
}
listen (port = 3000, host = 'localhost') {
// Update showOpen
this.showOpen = () => {
const _host = host === '0.0.0.0' ? 'localhost' : host
// eslint-disable-next-line no-console
console.log('\n' + chalk.bgGreen.black(' OPEN ') + chalk.green(` http://${_host}:${port}\n`))
}
return new Promise((resolve, reject) => {
const server = this.renderer.app.listen({ port, host, exclusive: false }, err => {
/* istanbul ignore if */
@ -66,6 +56,10 @@ export default class Nuxt extends Tapable {
return reject(err)
}
const _host = host === '0.0.0.0' ? 'localhost' : host
// eslint-disable-next-line no-console
console.log('\n' + chalk.bgGreen.black(' OPEN ') + chalk.green(` http://${_host}:${port}\n`))
// Close server on nuxt close
this.plugin('close', () => new Promise((resolve, reject) => {
// Destroy server by forcing every connection to be closed

View File

@ -57,7 +57,7 @@ export default class Renderer extends Tapable {
// Setup nuxt middleware
await this.setupMiddleware()
// Load SSR resources from fs
// Production: Load SSR resources from fs
if (!this.options.dev) {
await this.loadResources()
}
@ -151,9 +151,6 @@ export default class Renderer extends Tapable {
// Create Meta Renderer
this.metaRenderer = new MetaRenderer(this.nuxt, this)
// Show Open URL
this.nuxt.showOpen()
// Skip following steps if noSSR mode
if (this.noSSR) {
return