Skip to content

Commit

Permalink
refacto: Refacto nuxt.build() to finish after webpack is done
Browse files Browse the repository at this point in the history
  • Loading branch information
Atinux committed Oct 30, 2017
1 parent c688fc0 commit 379d4f7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 94 deletions.
128 changes: 48 additions & 80 deletions lib/builder/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -427,108 +422,81 @@ 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)
})

// 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 })
this.compilers.push(compiler)
})

// 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
return this.webpackDev(compiler)
}
// DLL build, should run only once
if (compiler.options.name.includes('-dll')) {
compiler.run((err, stats) => {
if (err) {
return reject(err)
}
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
}
} else {
// --- Production Build ---
compiler.run((err, stats) => {
// 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,
quiet: true,
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)))
Expand Down
14 changes: 4 additions & 10 deletions lib/core/nuxt.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -52,20 +49,17 @@ 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 */
if (err) {
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
Expand Down
5 changes: 1 addition & 4 deletions lib/core/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 379d4f7

Please sign in to comment.