[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/devhttps/frontend/test-code-owners/dev/watch.js [Back]  [Original]

#!/usr/bin/env node

const path = require('path');

const chalk = require('chalk');
const browserSync = require('browser-sync').create();
const bsConfig = require('./bs-config');

// ********************************** JAVASCRIPT **********************************

// webpack watch task always performs an intial bundle, and we don't want browsersync
// listening at the point. so we use this flag to know whether any change webpack reports
// is the initial bundle, or subsequent file changes
let INITIAL_BUNDLE = true;

// just a bit of visual feedback while webpack creates its initial bundles.
// fakes a listr step
const ora = require('ora');

const wpNotification = ora({
    text: 'Create initial webpack bundles',
    color: 'yellow',
});
wpNotification.start();

const webpack = require('webpack');
const webpackBundler = webpack(require('../webpack.config.dev.js'));

webpackBundler.watch(
    {
        ignored: /node_modules/,
    },
    (err, stats) => {
        if (err) {
            // log any unexpected error
            console.log(chalk.red(err));
        }

        if (INITIAL_BUNDLE) {
            INITIAL_BUNDLE = false;
            wpNotification.succeed();

            // now have the initial bundles, we can start browsersync
            return browserSync.init(bsConfig);
        }

        const info = stats.toJson();
        // send editing errors to console and browser
        if (stats.hasErrors()) {
            console.log(chalk.red(info.errors));
            return browserSync.sockets.emit('fullscreen:message', {
                title: 'Webpack Error:',
                body: info.errors,
                timeout: 100000,
            });
        }

        if (stats.hasWarnings()) {
            console.warn(chalk.yellow(info.warnings));
        }

        // announce the changes
        return browserSync.reload();
    }
);

// ********************************** Sass **********************************

const chokidar = require('chokidar');

const sassDir = path.resolve(__dirname, '../', 'static', 'src', 'stylesheets');
const sassGraph = require('sass-graph').parseDir(sassDir, {
    loadPaths: [sassDir],
});

const compileSass = require('../tools/compile-css');

// when we detect a change in a sass file, we look up the tree of imports
// and only compile what we need to. anything matching this regex, we can just ignore in dev.
const ignoredSassRegEx = /^(_|ie9|old-ie)/;

chokidar.watch(`${sassDir}/**/*.scss`).on('change', changedFile => {
    // see what top-level files need to be recompiled
    const filesToCompile = [];
    const changedFileBasename = path.basename(changedFile);

    sassGraph.visitAncestors(changedFile, ancestorPath => {
        const ancestorFileName = path.basename(ancestorPath);
        if (!ignoredSassRegEx.test(ancestorFileName)) {
            filesToCompile.push(ancestorFileName);
        }
    });

    if (!/^_/.test(changedFileBasename)) {
        filesToCompile.push(changedFileBasename);
    }

    // now recompile all files that matter
    Promise.all(filesToCompile.map(compileSass))
        .then(() => {
            // clear any previous error messages
            browserSync.sockets.emit('fullscreen:message:clear');

            // announce the changes
            browserSync.reload(
                filesToCompile.map(file => file.replace('scss', 'css'))
            );
        })
        .catch(e => {
            // send editing errors to console and browser
            console.log(chalk.red(`\n${e.formatted}`));
            browserSync.sockets.emit('fullscreen:message', {
                title: 'CSS Error:',
                body: e.formatted,
                timeout: 100000,
            });
        });
});

Web Proxy Viewer  |  New URL  |  Original Page