2018-06-07 14:59:05 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the pig4cloud.com developer nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived from
|
|
|
|
* this software without specific prior written permission.
|
|
|
|
* Author: lengleng (wangiegie@gmail.com)
|
|
|
|
*/
|
|
|
|
|
2018-03-04 13:49:35 +08:00
|
|
|
const fs = require('fs')
|
|
|
|
const path = require('path')
|
|
|
|
const MFS = require('memory-fs')
|
|
|
|
const webpack = require('webpack')
|
|
|
|
const chokidar = require('chokidar')
|
|
|
|
const clientConfig = require('./webpack.client.conf')
|
|
|
|
const serverConfig = require('./webpack.server.conf')
|
|
|
|
|
|
|
|
const readFile = (fs, file) => {
|
|
|
|
try {
|
|
|
|
return fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = function setupDevServer (app, templatePath, cb) {
|
|
|
|
let bundle
|
|
|
|
let template
|
|
|
|
let clientManifest
|
|
|
|
|
|
|
|
let ready
|
|
|
|
const readyPromise = new Promise(r => { ready = r })
|
|
|
|
const update = () => {
|
|
|
|
if (bundle && clientManifest) {
|
|
|
|
ready()
|
|
|
|
cb(bundle, {
|
|
|
|
template,
|
|
|
|
clientManifest
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// read template from disk and watch
|
|
|
|
template = fs.readFileSync(templatePath, 'utf-8')
|
|
|
|
chokidar.watch(templatePath).on('change', () => {
|
|
|
|
template = fs.readFileSync(templatePath, 'utf-8')
|
|
|
|
console.log('index.html template updated.')
|
|
|
|
update()
|
|
|
|
})
|
|
|
|
|
|
|
|
// 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()
|
|
|
|
)
|
|
|
|
|
|
|
|
// 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', stats => {
|
|
|
|
stats = stats.toJson()
|
|
|
|
stats.errors.forEach(err => console.error(err))
|
|
|
|
stats.warnings.forEach(err => console.warn(err))
|
|
|
|
if (stats.errors.length) return
|
|
|
|
clientManifest = JSON.parse(readFile(
|
|
|
|
devMiddleware.fileSystem,
|
|
|
|
'vue-ssr-client-manifest.json'
|
|
|
|
))
|
|
|
|
update()
|
|
|
|
})
|
|
|
|
|
|
|
|
// hot middleware
|
|
|
|
app.use(require('webpack-hot-middleware')(clientCompiler, { heartbeat: 5000 }))
|
|
|
|
|
|
|
|
// 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()
|
|
|
|
if (stats.errors.length) return
|
|
|
|
|
|
|
|
// read bundle generated by vue-ssr-webpack-plugin
|
|
|
|
bundle = JSON.parse(readFile(mfs, 'vue-ssr-server-bundle.json'))
|
|
|
|
update()
|
|
|
|
})
|
|
|
|
|
|
|
|
return readyPromise
|
|
|
|
}
|