UNPKG

@mapbox/batfish

Version:

The React-powered static-site generator you didn't know you wanted

133 lines (118 loc) 4.08 kB
// 'use strict'; const _ = require('lodash'); const webpack = require('webpack'); const path = require('path'); const chalk = require('chalk'); const EventEmitter = require('events'); const webpackMerge = require('webpack-merge'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const errorTypes = require('./error-types'); const wrapError = require('./wrap-error'); const constants = require('./constants'); const createWebpackConfigClient = require('./create-webpack-config-client'); const createWebpackStatsError = require('./create-webpack-stats-error'); const watchContext = require('./watch-context'); const serverInitMessage = require('./server-init-message'); const writeWebpackStats = require('./write-webpack-stats'); // Returns an EventEmitter that fires notification and error events. function watchWebpack( batfishConfig , server ) { const emitter = new EventEmitter(); const emitError = (error ) => { emitter.emit(constants.EVENT_ERROR, error); }; const emitNotification = (message ) => { emitter.emit(constants.EVENT_NOTIFICATION, message); }; const htmlWebpackPluginOptions = { template: path.join(__dirname, '../webpack/html-webpack-template.ejs'), cssBasename: _.isEmpty(batfishConfig.stylesheets) ? '' : constants.BATFISH_CSS_BASENAME }; let lastHash; let hasCompiled = false; createWebpackConfigClient(batfishConfig, { devServer: true }) .then(clientConfig => { // Create an HTML file to load the assets in the browser. const config = webpackMerge(clientConfig, { plugins: [new HtmlWebpackPlugin(htmlWebpackPluginOptions)] }); let compiler; try { compiler = webpack(config); } catch (compilerInitializationError) { emitError( wrapError(compilerInitializationError, errorTypes.WebpackFatalError) ); return; } const onCompilation = (compilationError, stats) => { // Don't do anything if the compilation is just repetition. // There's often a series of many compilations with the same output. if (stats.hash === lastHash) return; lastHash = stats.hash; if (!hasCompiled) { hasCompiled = true; emitNotification(chalk.green.bold('Go!')); emitNotification( serverInitMessage(server.browserSyncInstance, batfishConfig) ); } if (compilationError) { emitError( wrapError(compilationError, errorTypes.WebpackCompilationError) ); return; } if (stats.hasErrors()) { emitError(createWebpackStatsError(stats)); } writeWebpackStats(batfishConfig.outputDirectory, stats).catch( emitError ); if (batfishConfig.verbose) { emitNotification( stats.toString({ chunks: false, colors: true }) ); } emitNotification('Webpack finished compiling.'); server.reload(); }; compiler.watch( { ignored: [ /node_modules/, // Ignore page files because they are watched by watchContext. path.join( batfishConfig.pagesDirectory, `./**/*.${constants.PAGE_EXT_GLOB}` ), // Ignore temporary files because they are only re-generated by // watchContext, and we don't want to double-compile. path.join(batfishConfig.temporaryDirectory, './**/*') ] }, onCompilation ); // Watch pages separately, so we can rewrite the context module, which // will capture changes to front matter, page additions and deletions. watchContext(batfishConfig, { onError: emitError, afterCompilation: () => { compiler.run(onCompilation); } }); }) .catch(emitError); return emitter; } module.exports = watchWebpack;