You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.5 KiB
95 lines
2.5 KiB
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.config");
|
|
const serverConfig = require("./webpack.server.config");
|
|
|
|
/**
|
|
* 读取文件
|
|
*/
|
|
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()
|
|
);
|
|
|
|
const clientCompiler = webpack(clientConfig);
|
|
const devMiddleware = require("webpack-dev-middleware")(clientCompiler, {
|
|
publicPath: clientConfig.output.publicPath,
|
|
});
|
|
|
|
// dev middleware
|
|
app.use(devMiddleware);
|
|
clientCompiler.hooks.done.tap("done", (stats) => {
|
|
console.log("编译完成");
|
|
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.context.outputFileSystem, "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;
|
|
};
|
|
|