UNPKG

@bolt/build-tools

Version:

Curated collection of front-end build tools in the Bolt Design System.

195 lines (168 loc) 6.15 kB
const webpack = require('webpack'); const express = require('express'); const browserSync = require('browser-sync').create(); const webpackDevMiddleware = require('webpack-dev-middleware'); const webpackHotMiddleware = require('webpack-hot-middleware'); const chalk = require('chalk'); const opn = require('better-opn'); const { handleRequest } = require('@bolt/api'); const { getConfig } = require('@bolt/build-utils/config-store'); const { boltWebpackMessages } = require('@bolt/build-utils/webpack-helpers'); const events = require('@bolt/build-utils/events'); const { webpackStats, statsPreset, } = require('@bolt/build-utils/webpack-verbosity'); const fs = require('fs'); const createWebpackConfig = require('../create-webpack-config'); const webpackDevServerWaitpage = require('./webpack-dev-server-waitpage'); let boltBuildConfig; let browserSyncIsRunning = false; const app = express(); const getDirectories = source => fs .readdirSync(source, { withFileTypes: true }) .filter(dir => dir.isDirectory()) .map(dir => dir.name); async function compile(customWebpackConfig) { boltBuildConfig = boltBuildConfig || (await getConfig()); const webpackConfig = customWebpackConfig || (await createWebpackConfig(boltBuildConfig)); return new Promise((resolve, reject) => { const compiler = boltWebpackMessages(webpack(webpackConfig)); compiler.run((err, stats) => { if (err) { return reject(err); } else { return resolve(); } }); }); } compile.description = 'Compile Webpack'; compile.displayName = 'webpack:compile'; async function watch(customConfig) { boltBuildConfig = boltBuildConfig || (await getConfig()); const webpackConfig = customConfig || (await createWebpackConfig(boltBuildConfig)); return new Promise((resolve, reject) => { const compiler = boltWebpackMessages(webpack(webpackConfig)); compiler.watch({ // https://webpack.js.org/configuration/watch/#watchoptions aggregateTimeout: 300, }); }); } watch.description = 'Watch & fast re-compile Webpack'; watch.displayName = 'webpack:watch'; async function server(customWebpackConfig) { const boltBuildConfig = await getConfig(); const webpackConfigs = customWebpackConfig || (await createWebpackConfig(boltBuildConfig)); const browserSyncFileToWatch = [ `${boltBuildConfig.wwwDir}/**/*.css`, `${boltBuildConfig.wwwDir}/**/*.html`, `!**/node_modules/**/*`, `!**/vendor/**/*`, ]; browserSyncFileToWatch.push(`${boltBuildConfig.wwwDir}/**/*.js`); const isUsingInternalServer = typeof boltBuildConfig.proxyHostname === 'undefined' && typeof boltBuildConfig.proxyPort === 'undefined'; return new Promise((resolve, reject) => { if (!browserSyncIsRunning) { browserSync.init( { proxy: !isUsingInternalServer ? `${boltBuildConfig.proxyHostname}:${boltBuildConfig.proxyPort}` : `${boltBuildConfig.hostname}:${boltBuildConfig.port}`, logLevel: 'info', ui: false, notify: false, open: false, // This can be temporarily toggled to solve IP access issues on a lan. https://www.browsersync.io/docs/options#option-tunnel tunnel: false, logFileChanges: false, reloadOnRestart: true, watchOptions: { ignoreInitial: true, }, port: boltBuildConfig.port, files: browserSyncFileToWatch, }, function(err, bs) { browserSyncIsRunning = true; // so we only spin this up once Webpack has finished up initially if (boltBuildConfig.openServerAtStart) { opn(`http://${boltBuildConfig.hostname}:${boltBuildConfig.port}`); } if (!isUsingInternalServer) { console.log( chalk.green( `\nBrowsersync is now proxying ${chalk.underline( `http://${boltBuildConfig.proxyHostname}:${boltBuildConfig.proxyPort}`, )}.\nOpen ${chalk.underline( `http://${boltBuildConfig.hostname}:${boltBuildConfig.port}`, )} to have your locally served pages automatically reload when HTML, CSS, and Javascript files are updated. \n`, ), ); } }, ); } const compiler = boltWebpackMessages(webpack(webpackConfigs)); compiler.hooks.done.tap('AfterDonePlugin', (params, callback) => { events.emit('webpack-dev-server:compiled'); }); app.use( webpackDevServerWaitpage(compiler, { proxyHeader: boltBuildConfig.proxyHeader, redirectPath: `${boltBuildConfig.proxyHostname}:${ boltBuildConfig.proxyPort }/${ boltBuildConfig.startPath !== '/' ? boltBuildConfig.startPath : '' }`, }), ); app.use( webpackDevMiddleware(compiler, { quiet: true, stats: 'errors-warnings', writeToDisk: true, logLevel: 'error', stats: statsPreset(webpackStats[boltBuildConfig.verbosity]), }), ); app.use(express.static(boltBuildConfig.wwwDir)); // app.use('/api', handleRequest); // Component Explorer being temporarily disabled until we've migrated our Twig Rendering Service to Now.sh v2 if (fs.existsSync(`${boltBuildConfig.wwwDir}/integrations`)) { const integrationDirs = getDirectories( `${boltBuildConfig.wwwDir}/integrations`, ); integrationDirs.map(item => { app.use( express.static(`${boltBuildConfig.wwwDir}/integrations/${item}`), ); }); app.get(['/drupal-lab'], (req, res) => { const options = { root: `${boltBuildConfig.wwwDir}/integrations/drupal-lab`, }; res.sendFile('index.html', options); }); } app.listen(boltBuildConfig.port, boltBuildConfig.hostname, function onStart( err, ) { if (err) { console.log(err); } }); }); } server.description = 'Webpack Dev Server'; server.displayName = 'webpack:server'; module.exports = { compile, watch, server, };