dev-server.js 2.8 KB
const webpack = require('webpack');
const path = require('path');
const MFS = require('memory-fs');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const pkg = require('../package.json');
let clientConfig = require('./webpack.client.conf.js');
let serverConfig = require('./webpack.server.conf.js');

let devMiddleware;
let hotMiddleware;

const _readFile = (fs, file) => {
    try {
        return fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8');
    } catch (e) {
        console.error('file load failure!', file);
    }
};

exports.readFile = (file) => {
    try {
        return devMiddleware.fileSystem.readFileSync(path.join(clientConfig.output.path, file), 'utf-8');
    } catch (e) {
        return false;
    }
};
exports.publish = (data) => {
    return hotMiddleware.publish(data);
};

exports.devServer = (app, cb) => {
    let resolve;
    let realyPromise = new Promise(r => {
        resolve = r;
    });
    let ready = (...args) => {
        resolve();
        cb(...args);
    };

    clientConfig.entry.app = ['./build/client-hot.js', clientConfig.entry.app];
    clientConfig.output.publicPath = 'http://localhost:6005/';
    clientConfig.output.filename = '[name].js';
    clientConfig.plugins.push(
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin()
    );
    const clientCompiler = webpack(clientConfig);

    devMiddleware = webpackDevMiddleware(clientCompiler, {
        publicPath: clientConfig.output.publicPath,
        quiet: true,
        headers: {
            'Access-Control-Allow-Origin': '*'
        }
    });

    app.use(devMiddleware);

    let bundle, clientManifest;

    clientCompiler.plugin('done', stats => {
        stats = stats.toJson();
        stats.errors.forEach(error => console.log(error));
        stats.warnings.forEach(warning => console.log(warning));
        if (stats.errors.length) {
            return;
        }
        clientManifest = JSON.parse(_readFile(devMiddleware.fileSystem, `yoho-ssr-client-${pkg.version}.json`));

        if (bundle) {
            ready({bundle, options: {clientManifest}});
        }
    });
    hotMiddleware = webpackHotMiddleware(clientCompiler, { heartbeat: 5000 });

    app.use(hotMiddleware);

    const serverCompiler = webpack(serverConfig);
    let mfs = new MFS();

    serverCompiler.outputFileSystem = mfs;
    serverCompiler.watch({}, (err, stats) => {
        if (err) {
            throw err;
        }
        stats = stats.toJson();
        if (stats.errors.length) {
            return;
        }
        bundle = JSON.parse(_readFile(mfs, `yoho-ssr-server-${pkg.version}.json`));

        if (clientManifest) {
            ready({bundle, options: {clientManifest}});
        }
    });

    return realyPromise;
};