Brent White Brent White - 7 months ago 48
Javascript Question

SASS + CSS Injecting with Gulp and BrowserSync

Just getting started with BrowserSync and I have a question regarding the common use-cases on configuration for SASS + CSS injecting.

What I'm a little confused about is weather I can give the

server
property its own name.

In the docs here they use
"./app"
. Can I use another name like
"./site"
or am I only allowed to use
"./app"
?

Here's the code

// task
gulp.task('serve',['sass'], function (){

// static server
browserSync.init({
server: "./app"
});

// watching html and scss files for changes then reloading browser
gulp.watch("app/scss/*.scss", ['sass']);
gulp.watch("app/*.html").on('change', browserSync.reload);

});

Answer

UPDATED

If you're looking to set up browserSync as a static server with live reloading you're pretty much right with your approach. You can point browsersync to any folder in your repository using the baseDir option. You can also use multiple directories. For further info check out the options documentation.

First. I would look to split up the tasks you have.

Personally, I would opt to have my server task something like;

gulp.task('serve', ['build'], function(event) {
  var server = browsersync.create();
  server.init({
    baseDir: 'app/'
  });
  return server.watch('app/**', function(evt, file) {
    server.reload();
  });
});

Note how build is a dependency. This ensures that all of our served files are in place when we initiate BrowserSync.

Keeping it generic we can then split the SCSS related tasks into their own tasks such as scss:compile and scss:watch.

gulp.task('scss:compile', function(){
    return gulp.src('src/scss/**/*.scss')
        .pipe(plumber())
        .pipe(scss())
        .pipe(gulp.dest('app/css/');
});

and

gulp.task('scss:watch', function() {
    gulp.watch('src/scss/**/*.scss', ['scss:compile']);
});

For CSS injection. There are two options for doing this

Remember injection differs from reload. Whereas reload will reset the page state, injection won't affect the current page state and justs injects the styles.

Option one is to invoke browsersync.stream() with the piped content of your SASS compilation like follows;

gulp.task('scss:compile', function() {
  return gulp.src('src/scss/**/*.scss')
    .pipe(plumber())
    .pipe(scss())
    .pipe(gulp.dest('app/css')
    .pipe(browsersync.stream());
});

Note that the last pipe injects the changes. This also requires to check the file type in the BrowserSync watch to only reload when a non CSS file changes.

This option is OK. However, I think it's not clear to have it just bundled on the end there and separate from BrowserSync setup code.

The second option(personally preferred) is to watch for changes with BrowserSync and if a CSS file changes, use vinyl to stream those changes to BrowserSync.

Something like the following tends to work;

var gulp      = require('gulp'),
  browsersync = require('browser-sync'),
  vss         = require('vinyl-source-stream'),
  vb          = require('vinyl-buffer'),
  vf          = require('vinyl-file');

gulp.task('serve', ['build'], function() {
  var server = browsersync.create();
  server.init({ baseDir: 'app/' });
  return server.watch('app/**', function(evt, file) {
    if (evt === 'change' && file.indexOf('.css') === -1)
      server.reload();
    if (evt === 'change' && file.indexOf('.css') !== -1)
      vf.readSync(file)
        .pipe(vss(file))
        .pipe(vb())
        .pipe(server.stream());
  });
});

Hope that helps you out!

Comments