mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 16:12:12 +00:00
improvements
This commit is contained in:
parent
15bc36afb0
commit
d882b1ac77
@ -5,10 +5,9 @@ import hash from 'hash-sum'
|
||||
import pify from 'pify'
|
||||
import webpack from 'webpack'
|
||||
import serialize from 'serialize-javascript'
|
||||
import webpackDevMiddleware from 'webpack-dev-middleware'
|
||||
import webpackHotMiddleware from 'webpack-hot-middleware'
|
||||
import { join, resolve, basename, dirname } from 'path'
|
||||
import Tapable from 'tappable'
|
||||
import chalk from 'chalk'
|
||||
import { r, wp, createRoutes } from './utils'
|
||||
import clientWebpackConfig from './webpack/client.config.js'
|
||||
import serverWebpackConfig from './webpack/server.config.js'
|
||||
@ -282,7 +281,7 @@ export default class Builder extends Tapable {
|
||||
|
||||
// Start build
|
||||
return new Promise((resolve, reject) => {
|
||||
this.compiler.run((err, multiStats) => {
|
||||
const handler = (err, multiStats) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
@ -292,8 +291,15 @@ export default class Builder extends Tapable {
|
||||
return reject(new Error('Webpack build exited with errors'))
|
||||
}
|
||||
}
|
||||
// Use watch handler instead of compiler.apply('done') to prevent duplicate emits
|
||||
this.applyPlugins('reload', multiStats)
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
if (this.options.dev) {
|
||||
this.compiler.watch(this.options.watchers.webpack, handler)
|
||||
} else {
|
||||
this.compiler.run(handler)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -306,42 +312,33 @@ export default class Builder extends Tapable {
|
||||
compiler.outputFileSystem = mfs
|
||||
})
|
||||
|
||||
let clientConfig = this.compiler.$client.options
|
||||
// Watch
|
||||
this.plugin('reload', () => {
|
||||
// Show open URL
|
||||
let _host = host === '0.0.0.0' ? 'localhost' : host
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(chalk.bold(chalk.bgCyan.black(' OPEN ') + chalk.cyan(` http://${_host}:${port}\n`)))
|
||||
|
||||
// Setup on the fly compilation + hot-reload
|
||||
clientConfig.entry.app = _.flatten(['webpack-hot-middleware/client?reload=true', clientConfig.entry.app])
|
||||
clientConfig.plugins.push(
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin()
|
||||
)
|
||||
// Reload renderer if available
|
||||
if (this.nuxt.renderer) {
|
||||
this.nuxt.renderer.loadResources(mfs)
|
||||
}
|
||||
})
|
||||
|
||||
// Create webpack dev middleware
|
||||
this.webpackDevMiddleware = pify(webpackDevMiddleware(this.compiler.$client, {
|
||||
publicPath: clientConfig.output.publicPath,
|
||||
// Create webpack Dev/Hot middleware
|
||||
this.webpackDevMiddleware = pify(require('webpack-dev-middleware')(this.compiler.$client, {
|
||||
publicPath: this.options.build.publicPath,
|
||||
stats: this.webpackStats,
|
||||
quiet: true,
|
||||
noInfo: true,
|
||||
watchOptions: this.options.watchers.webpack
|
||||
}))
|
||||
|
||||
this.webpackHotMiddleware = pify(webpackHotMiddleware(this.compiler.$client, {
|
||||
this.webpackHotMiddleware = pify(require('webpack-hot-middleware')(this.compiler.$client, {
|
||||
log: false,
|
||||
heartbeat: 2500
|
||||
}))
|
||||
|
||||
// Run after compilation is done
|
||||
this.compiler.plugin('done', async stats => {
|
||||
// Reload renderer if available
|
||||
if (this.nuxt.renderer) {
|
||||
await this.nuxt.renderer.loadResources(mfs)
|
||||
}
|
||||
// Show open URL
|
||||
if (!stats.hasErrors() && !stats.hasWarnings()) {
|
||||
let _host = host === '0.0.0.0' ? 'localhost' : host
|
||||
console.log(`> Open http://${_host}:${port}\n`) // eslint-disable-line no-console
|
||||
}
|
||||
})
|
||||
|
||||
this.watchFiles()
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Tapable from 'tappable'
|
||||
import Builder from './builder'
|
||||
import * as Utils from './utils'
|
||||
import Renderer from './renderer'
|
||||
import ModuleContainer from './module-container'
|
||||
@ -56,7 +57,7 @@ export default class Nuxt extends Tapable {
|
||||
if (this._builder) {
|
||||
return this._builder
|
||||
}
|
||||
const Builder = require('./builder').default
|
||||
// const Builder = require('./builder').default
|
||||
this._builder = new Builder(this)
|
||||
return this._builder
|
||||
}
|
||||
|
@ -69,9 +69,11 @@ export default class Renderer extends Tapable {
|
||||
this.gzipMiddleware = pify(compression(this.options.render.gzip))
|
||||
}
|
||||
|
||||
// Try to load resources from fs
|
||||
// Load resources from fs
|
||||
if (!this.options.dev) {
|
||||
return this.loadResources()
|
||||
}
|
||||
}
|
||||
|
||||
async loadResources (_fs = fs, distPath) {
|
||||
distPath = distPath || resolve(this.options.buildDir, 'dist')
|
||||
@ -91,22 +93,33 @@ export default class Renderer extends Tapable {
|
||||
}
|
||||
}
|
||||
|
||||
let updated = []
|
||||
|
||||
Object.keys(resourceMap).forEach(resourceKey => {
|
||||
let { path, transform } = resourceMap[resourceKey]
|
||||
let data
|
||||
if (_fs.existsSync(path)) {
|
||||
data = _fs.readFileSync(path, 'utf8')
|
||||
if (typeof transform === 'function') {
|
||||
data = transform(data)
|
||||
let rawKey = '$$' + resourceKey
|
||||
let rawData, data
|
||||
if (!_fs.existsSync(path)) {
|
||||
return // Resource not exists
|
||||
}
|
||||
rawData = _fs.readFileSync(path, 'utf8')
|
||||
if (!rawData || rawData === this.resources[rawKey]) {
|
||||
return // No changes
|
||||
}
|
||||
this.resources[rawKey] = rawData
|
||||
data = transform(rawData)
|
||||
if (!data) {
|
||||
return // Invalid data ?
|
||||
}
|
||||
if (data) {
|
||||
this.resources[resourceKey] = data
|
||||
}
|
||||
updated.push(resourceKey)
|
||||
})
|
||||
|
||||
if (updated.length > 0) {
|
||||
// debug('Updated', updated.join(', '))
|
||||
this.createRenderer()
|
||||
}
|
||||
}
|
||||
|
||||
createRenderer () {
|
||||
// If resources are not yet provided
|
||||
@ -232,7 +245,9 @@ export default class Renderer extends Tapable {
|
||||
async renderRoute (url, context = {}) {
|
||||
/* istanbul ignore if */
|
||||
if (!this.bundleRenderer || !this.resources.appTemplate) {
|
||||
return Promise.reject(new Error('bundleRenderer is not available'))
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => resolve(this.renderRoute(url, context)), 1000)
|
||||
})
|
||||
}
|
||||
|
||||
// Log rendered url
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { each, defaults } from 'lodash'
|
||||
import { each, defaults, flatten } from 'lodash'
|
||||
import webpack from 'webpack'
|
||||
import VueSSRClientPlugin from 'vue-server-renderer/client-plugin'
|
||||
import HTMLPlugin from 'html-webpack-plugin'
|
||||
@ -88,6 +88,15 @@ export default function webpackClientConfig () {
|
||||
if (this.options.dev) {
|
||||
config.plugins.push(new FriendlyErrorsWebpackPlugin())
|
||||
}
|
||||
// Dev client build
|
||||
if(this.options.dev){
|
||||
// Add HMR support
|
||||
config.entry.app = flatten(['webpack-hot-middleware/client?name=$client&reload=true', config.entry.app])
|
||||
config.plugins.push(
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin()
|
||||
)
|
||||
}
|
||||
// Production client build
|
||||
if (!this.options.dev) {
|
||||
config.plugins.push(
|
||||
|
Loading…
Reference in New Issue
Block a user