app-dev.js 1.67 KB
const fs = require('fs');
const path = require('path');
const cluster = require('cluster');
const express = require('express');
const chokidar = require('chokidar');
const {createApp} = require('./create-app.js');
const {createBundleRenderer} = require('vue-server-renderer');
const {devServer, publish} = require('./build/dev-server.js');

const watcher = {
  paths: ['./create-app.js', './doraemon', './config', './utils'],
  options: {}
};

let renderer;
let realyPromise;
let template = fs.readFileSync(path.join(__dirname, './apps/index.html'), 'utf-8');

if (cluster.isMaster) {
  const masterApp = express();

  realyPromise = devServer(masterApp, params => {
    renderer = createBundleRenderer(params.bundle, Object.assign(params.options, {
      runInNewContext: false,
      template
    }));
  });
  let childWorker = cluster.fork();

  cluster.on('message', (worker, msg) => {
    if (msg.action === 'ssr_request') {
      realyPromise.then(() => {
        renderer.renderToString(msg.context, (err, html) => {
          if (err) {
            console.error(err);
          }
          worker.send({action: 'ssr_request', html, err: err && JSON.stringify(err)});
        });
      });
    }
  });
  chokidar.watch(watcher.paths, watcher.options).on('change', pathStr => {
    console.log(`${pathStr} changed`);
    childWorker && childWorker.kill();
    childWorker = cluster.fork().on('listening', address => {
      console.log(`worker is restarted at ${address.port}`);
      publish({action: 'reload'});
      console.log('client is refresh');
    });
  });
  masterApp.listen(6005, () => {
    console.log('master is started');
  });
} else {
  const app = express();

  createApp(app);
}