How can I get Grunt/Watch/LiveReload to reload Sass/CSS without a full page refresh?

Trey Piepmeier picture Trey Piepmeier · Sep 25, 2013 · Viewed 20.2k times · Source

So far, I've gotten everything working how I want (which is monitoring all the files I want and refreshing whenever there is a change), other than I'd love to be able to make modifications to Sass/CSS and have it refresh in the browser without a page load. It's not a huge deal, but sometimes I'm trying to modify the style of something after there's been some page interaction and I have to go through the process all over again if the page refreshes.

I'm fairly certain this is possible, but it eludes me so far.

Here's my Gruntfile.js:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    connect: {
      server: {
        options: {},
      }
    },
    sass: {
      dist: {
        options: {
          style: 'compressed'
        },
        files: {
          'css/main.css': 'css/scss/main.scss',
        }
      }
    },
    jshint: {
      files: ['js/*.js'],
    },
    watch: {
      options: {
        livereload: true,
      },
      html: {
        files: ['index.html'],
      },
      js: {
        files: ['js/**/*.js'],
        tasks: ['jshint'],
      },
      css: {
        files: ['css/scss/**/*.scss'],
        tasks: ['sass'],
      },
    }
  });

  // Actually running things.
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-jshint');

  // Default task(s).
  grunt.registerTask('default', ['connect', 'watch']);

};

One odd thing I wanted to mention about my setup: when I run grunt watch --verbose I see that it's monitoring .git as well as .sass-cache. Does that seem right? I don't know what I did to make it do that.

Watching .git for changes.
Watching .sass-cache for changes.

Answer

Ben picture Ben · Sep 25, 2013

The first part of your question is straightforward enough. Live reload only reloads the files you specify in the configuration; i.e if you specify sass files it is those that are reloaded. I fixed this in my setup by having Grunt watch the css file in my dist directory, which obviously gets changed every time the Sass is recompiled.

watch: {
  options: {
    livereload: true,
  },
  html: {
    files: ['index.html'],
  },
  js: {
    files: ['js/**/*.js'],
    tasks: ['jshint'],
  },
  sass: {
    options: {
      livereload: false
    },
    files: ['css/scss/**/*.scss'],
    tasks: ['sass'],
  },
  css: {
    files: ['dist/css/master.css'],
    tasks: []
  }
}

I'm not sure about the second question. It doesn't show those directories in my grunt watch --verbose for any project, then again I never run that command verbosely.