UNPKG

react-universally

Version:

A starter kit for universal react applications.

129 lines (110 loc) 3.19 kB
import path from 'path'; import appRootDir from 'app-root-dir'; import { spawn } from 'child_process'; import { log } from '../utils'; class HotNodeServer { constructor(name, compiler, clientCompiler) { const compiledEntryFile = path.resolve( appRootDir.get(), compiler.options.output.path, `${Object.keys(compiler.options.entry)[0]}.js`, ); const startServer = () => { if (this.server) { this.server.kill(); this.server = null; log({ title: name, level: 'info', message: 'Restarting server...', }); } const newServer = spawn('node', [compiledEntryFile]); log({ title: name, level: 'info', message: 'Server running with latest changes.', notify: true, }); newServer.stdout.on('data', data => console.log(data.toString().trim())); newServer.stderr.on('data', (data) => { log({ title: name, level: 'error', message: 'Error in server execution, check the console for more info.', }); console.error(data.toString().trim()); }); this.server = newServer; }; // We want our node server bundles to only start after a successful client // build. This avoids any issues with node server bundles depending on // client bundle assets. const waitForClientThenStartServer = () => { if (this.serverCompiling) { // A new server bundle is building, break this loop. return; } if (this.clientCompiling) { setTimeout(waitForClientThenStartServer, 50); } else { startServer(); } }; clientCompiler.plugin('compile', () => { this.clientCompiling = true; }); clientCompiler.plugin('done', (stats) => { if (!stats.hasErrors()) { this.clientCompiling = false; } }); compiler.plugin('compile', () => { this.serverCompiling = true; log({ title: name, level: 'info', message: 'Building new bundle...', }); }); compiler.plugin('done', (stats) => { this.serverCompiling = false; if (this.disposing) { return; } try { if (stats.hasErrors()) { log({ title: name, level: 'error', message: 'Build failed, check the console for more information.', notify: true, }); console.log(stats.toString()); return; } waitForClientThenStartServer(); } catch (err) { log({ title: name, level: 'error', message: 'Failed to start, please check the console for more information.', notify: true, }); console.error(err); } }); // Lets start the compiler. this.watcher = compiler.watch(null, () => undefined); } dispose() { this.disposing = true; const stopWatcher = new Promise((resolve) => { this.watcher.close(resolve); }); return stopWatcher.then(() => { if (this.server) this.server.kill(); }); } } export default HotNodeServer;