UNPKG

feds-cli

Version:

CLI for Front-end Dev Stack

174 lines (153 loc) 5.21 kB
const pathResolve = require('path').resolve const chokidar = require('chokidar') const webpack = require('webpack') const {createNotification} = require('../utils') const HotServer = require('./hotServer') const HotClient = require('./hotClient') const ensureVendorDLLExists = require('./ensureVendorDLLExists') const vendorDLLPaths = require('../config/vendorDLLPaths') /** * Hot development hot server class * @class HotDevelopment */ class HotDevelopment { constructor () { ensureVendorDLLExists().then(() => { try { const clientConfigFactory = require('../webpack/client.config') const clientConfig = clientConfigFactory({ mode: 'development' }) // Install the vendor DLL plugin. clientConfig.plugins.push( new webpack.DllReferencePlugin({ manifest: require(vendorDLLPaths.dllJsonPath) }) ) this.clientCompiler = webpack(clientConfig) const middlewareConfigFactory = require('../webpack/universalMiddleware.config') const middlewareConfig = middlewareConfigFactory({ mode: 'development' }) this.middlewareCompiler = webpack(middlewareConfig) const serverConfigFactory = require('../webpack/server.config') const serverConfig = serverConfigFactory({ mode: 'development' }) this.serverCompiler = webpack(serverConfig) } catch (err) { createNotification({ title: 'development', level: 'error', message: 'Webpack configs are invalid, please check the console for more information.' }) console.log(err) return } this.prepHotServer() this.prepHotUniversalMiddleware() this.prepHotClient() }).catch((err) => { createNotification({ title: 'vendorDLL', level: 'error', message: 'Unfortunately an error occured whilst trying to build the vendor dll used by the development server. Please check the console for more information.' }) if (err) { console.log(err) } }) } prepHotClient () { this.clientBundle = new HotClient(this.clientCompiler) } prepHotUniversalMiddleware () { let started = false const runMiddlewareCompiler = () => { this.middlewareCompiler.watch({}, () => undefined) } this.clientCompiler.plugin('done', (stats) => { if (!stats.hasErrors() && !started) { started = true runMiddlewareCompiler() } }) this.middlewareCompiler.plugin('compile', () => { createNotification({ title: 'universalMiddleware', level: 'info', message: 'Building new bundle...' }) }) this.middlewareCompiler.plugin('done', (stats) => { if (!stats.hasErrors()) { // Make sure our newly built bundle is removed from the module cache. Object.keys(require.cache).forEach((modulePath) => { if (modulePath.indexOf('universalMiddleware') !== -1) { delete require.cache[modulePath] } }) createNotification({ title: 'universalMiddleware', level: 'info', message: 'Available with latest changes.' }) } else { createNotification({ title: 'universalMiddleware', level: 'error', message: 'Build failed, please check the console for more information.' }) console.log(stats.toString()) } }) } prepHotServer () { let clientBuilt = false let middlewareBuilt = false let started = false const startServerBundleWhenReady = () => { if (!started && (clientBuilt && middlewareBuilt)) { started = true this.serverBundle = new HotServer(this.serverCompiler) } } this.clientCompiler.plugin('done', (stats) => { if (!stats.hasErrors() && !clientBuilt) { clientBuilt = true startServerBundleWhenReady() } }) this.middlewareCompiler.plugin('done', (stats) => { if (!stats.hasErrors() && !middlewareBuilt) { middlewareBuilt = true startServerBundleWhenReady() } }) } dispose () { const safeDisposer = bundle => () => (bundle ? bundle.dispose() : Promise.resolve()) const safeDisposeClient = safeDisposer(this.clientBundle) const safeDisposeServer = safeDisposer(this.serverBundle) return safeDisposeClient() .then(() => console.log('disposed client')) .then(safeDisposeServer) } } const hotDevelopment = new HotDevelopment() // Any changes to our webpack configs should be notified as requiring a restart // of the development tool. const watcher = chokidar.watch( pathResolve(__dirname, '../webpack') ) watcher.on('ready', () => { watcher.on('change', () => { createNotification({ title: 'webpack', level: 'warn', message: 'Webpack config changed. Please restart your development server to use the latest version of the configs.' }) }) }) // If we receive a kill cmd then we will first try to dispose our listeners. process.on('SIGTERM', () => hotDevelopment.dispose().then(() => process.exit(0)))