LordTribual
LordTribual

Reputation: 4249

Excluding files for BrowserSync not working

I'm currently following John Papa's course on JavaScript Build Automation with GulpJS. At the moment I try to setup browser-sync with gulp-nodemon to keep my browser in sync. This is my gulp task to serve my development build:

gulp.task('serve-dev', ['inject'], function () {
    var isDev = true;

    var nodeOptions = {
        script: config.settings.node.server,
        delayTime: 1,
        env: {
            'PORT': port,
            'NODE_ENV': isDev ? 'dev' : 'build'
        },
        watch: [config.server]
    };

    return $.nodemon(nodeOptions)
        .on('restart', ['vet'], function (event) {
            util.log('[nodemon] restarted');
        })
        .on('start', function () {
            util.log('[nodemon] started');
            startBrowserSync();
        })
        .on('crash', function () {
            util.log('[nodemon] crashed', 'red');
        })
        .on('exit', function () {
            util.log('[nodemon] exited cleanly');
        });
});

The interesting part is the function startBrowserSync():

function startBrowserSync() {
    if (browserSync.active) {
        return;
    }

    util.log('[browser-sync] Starting on port ' + port);

    gulp
        .watch([config.sass], ['styles'])
        .on('change', function (event) {
            util.onChange(event);
        });

    var options = {
        proxy: 'localhost:' + port,
        port: 3000,
        files: [
            config.client + '**/*.*',
            '!' + config.sass,
            config.tmp + '**/*.css'
        ],
        ghostMode: {
            clicks: true,
            location: false,
            forms: true,
            scroll: true
        },
        injectChanges: true,
        logFileChanges: true,
        logLevel: 'debug',
        logPrefix: 'bsp',
        notify: true,
        reloadDelay: 1000
    };

    browserSync(options);
}

As you can see in the files option I would like to watch all files in the client folder except *.scss files and explicitly watch the CSS file in my .tmp directory. That's the way John Papa does it in his course. However, everytime I change something in the *.scss files the whole page is reloaded. That's not the expected behaviour since I set injectChanges to true which means to inject CSS and not reload the whole page. The problem is that the ! does not exclude the files from being watched. What's the problem here?

By the way; My config for sass looks like this:

var client = './src/client/';

var config = {
    [...]
    sass: client + 'styles/**/*.scss',
    [...]
}

I already took a look into the documentation of BrowserSync here and here but even if I use the watchOptions property and ignore files it doesn't work.

Anoher problem is that config.tmp + '**/*.css' is not working properly. I declared the variable to be var tmp = './.tmp/';. Somehow BrowserSync has a problem with the .tmp. If I change that to tmp only it works. However, .tmp works in all other gulp tasks, e.g. the styles task:

gulp.task('styles', ['clean-styles'], function () {
    util.log('Compiling SCSS to CSS');

    if (production) {
        config.settings.sass.outputStyle = 'compressed';
    }

    return gulp
        .src(config.sass)
        .pipe($.plumber({
            errorHandler: util.onError
        }))
        .pipe($.sass(config.settings.sass))
        .pipe($.autoprefixer({
            browsers: [
                'last 2 versions',
                '> 5%'
            ]
        }))
        .pipe(gulp.dest(config.tmp));
});

What is the problem here? Any ideas?

Edit: Since I am using BrowserSync 2.7.1 I also tried the recommended way of creating the browserSync instance by calling create() on the module export. Furthermore I changed the BrowserSync call like so, as stated in this blog post:

 browserSync.init([
            config.client + '**/*.*',
            '!' + config.sass,
            config.tmp + '**/*.css'
        ], options);

I removed the files property from the options object and passed them as an array in the init() function. Still the scss files are not ignored and thus the the whole page is reloaded even if there is only a change in the styles.

Upvotes: 3

Views: 2603

Answers (3)

Neil
Neil

Reputation: 2749

From the browserSync documentation:

// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function() {
    return gulp.src("app/scss/*.scss")
        .pipe(sass())
        .pipe(gulp.dest("app/css"))
        .pipe(browserSync.stream());
});

So in the John Papa course, I got it to work by changing my styles task to the following:

    gulp.task('styles', ['clean-styles'], function() {
        log('Compiling Less --> CSS');

        return gulp
            .src(config.less)
            .pipe($.less())
            .on('error', errorLogger)
            .pipe($.autoprefixer({browsers: ['last 2 version', '> 5%']}))
            .pipe(gulp.dest(config.temp))
            .pipe(browserSync.stream());
    });

Upvotes: 0

Post Impatica
Post Impatica

Reputation: 16453

If anyone else has the same issue I am having, the only way I could get files to exclude was dropping the ./ in the file path. So as an example, I had to change ./config/*.less to config/*.less, then it would work.

Upvotes: 0

LordTribual
LordTribual

Reputation: 4249

I found a solution to my problem. It was actually crashing because of my path declaration. This is what I had before:

var client = './src/client/';
var clientApp = client + 'app/';
var server = './src/server/';
var bower = './bower_components/';
var tmp = './.tmp/';

As you can see each path starts with a ./ which only works for non Windows machines since Windows uses .\ as a command for the current working directory. Maybe it is BrowserSync which does not convert this correctly but for me it works perfectly if I change that as follows:

var client = 'src/client/';
var clientApp = client + 'app/';
var server = 'src/server/';
var bower = 'bower_components/';
var tmp = '.tmp/';

I removed all ./ from the paths and also changed the way I start BrowserSync to the recommended way as already mentioned in my question edit with a minor refactoring:

var files = isDev ? [
    config.client + '**/*.*',
    '!' + config.sass,
    config.tmp + '**/*.css'
] : [];

browserSync.init(files, options);

Some sites I stumbled upon gave me the clue to test that out:

If anyone has a better solution to my problem, feel free to add up on my post.

Upvotes: 4

Related Questions