KawAnime/webpack/setup-dev-server.js

74 lines
2.4 KiB
JavaScript

const path = require('path')
const webpack = require('webpack')
const MFS = require('memory-fs')
const clientConfig = require(path.join(__dirname, 'webpack.client.config'))
const serverConfig = require(path.join(__dirname, 'webpack.server.config'))
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const chalk = require('chalk')
module.exports = function setupDevServer (app, cb) {
let bundle, clientManifest
let resolve
let resolved = false
const readyPromise = new Promise(r => { resolve = r }) // eslint-disable-line promise/param-names
const ready = (...args) => {
if (!resolved) resolve()
cb(...args) // eslint-disable-line standard/no-callback-literal
}
// modify client config to work with hot middleware
clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app]
clientConfig.output.filename = '[name].js'
clientConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new ProgressBarPlugin({
format: chalk.cyan('> build') + ' [:bar] ' + chalk.green.bold(':percent') + ' (:elapsed seconds)',
clear: true
})
)
// dev middleware
const clientCompiler = webpack(clientConfig)
const devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
publicPath: clientConfig.output.publicPath,
noInfo: true
})
app.use(devMiddleware)
clientCompiler.plugin('done', () => {
const fs = devMiddleware.fileSystem
const readFile = file => fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
clientManifest = JSON.parse(readFile('vue-ssr-client-manifest.json'))
if (bundle) {
ready(bundle, {
clientManifest
})
}
})
// hot middleware
app.use(require('webpack-hot-middleware')(clientCompiler))
// watch and update server renderer
const serverCompiler = webpack(serverConfig)
const mfs = new MFS()
serverCompiler.outputFileSystem = mfs
serverCompiler.watch({}, (err, stats) => {
if (err) throw err
stats = stats.toJson()
stats.errors.forEach(err => console.error(err))
stats.warnings.forEach(err => console.warn(err))
const readFile = file => mfs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
// read bundle generated by vue-ssr-webpack-plugin
bundle = JSON.parse(readFile('vue-ssr-server-bundle.json'))
if (clientManifest) {
ready(bundle, {
clientManifest
})
}
})
return readyPromise
}