Livereload CSS without browser refresh #87

Closed
darvelo opened this Issue May 6, 2013 · 55 comments

Projects

None yet
darvelo commented May 6, 2013

I've been playing with the new livereload feature and it's pretty easy to use. Thanks for putting it in. :)

I'm stumbling into an issue where a livereload of css changes will sometimes refresh the page, and sometimes not. I'm not sure why, though. It would be awesome if it never triggered a refresh since it makes for faster dev. A quick sample of my Gruntfile:

watch: {
  compass: {
    files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
    tasks: ['compass:server'],
  },
  css: {
    files: [
      '{.tmp,<%= yeoman.app %>}/styles/**/*.css',
    ],
    tasks: ['noop'],
    options: {
      livereload: true
    },
  },
}

Any ideas why this might be happening? I've tweaked settings back and forth but can't seem to pin down the cause.

Contributor
itsjamie commented May 7, 2013

What exactly does the

.tmp 

in your css.files part do for you? I know Livereload will cause a browser refresh if you fire it with a file other than CSS...

Owner
shama commented May 7, 2013

@appleYaks Try running with grunt watch --verbose. It will list the files triggering the live reload. It may not be the files you want. We have #82 open for being able to specify the files in which trigger the reload as well.

I guess I've had this issue with .scss file changes from your compass task being pushed to livereload.
Setting nospawn: "true" for the compass task helped.

darvelo commented May 8, 2013

@shama My results in running grunt watch --verbose show both Live reloading app/styles/app.scss... and Live reloading .tmp/styles/app.css.... So it looks like you're right!

@bestander After I set nospawn:true on the compass task like you suggested, the browser doesn't refresh. So that helped for sure. The only problem is that sometimes the CSS changes don't get "caught" by the watch task when a file is saved. If they're caught, my output is:

OK
>> File "app/styles/app.scss" changed.

Running "compass:server" (compass) task
unchanged app/styles/main.scss
unchanged app/styles/modified-bootstrap-3.0.scss
unchanged app/styles/layoutPlugin.scss
overwrite .tmp/styles/app.css 

Running "watch" task

Completed in 2.912s at Wed May 08 2013 12:05:47 GMT-0400 (EDT) - Waiting...OK
>> File ".tmp/styles/app.css" changed.

Done, without errors.
... Reload .tmp/styles/app.css ...

Completed in 1.692s at Wed May 08 2013 12:05:49 GMT-0400 (EDT) - Waiting...GET /styles/app.css?livereload=1368029149210 200 31ms

If they're not caught, the output is:

OK
>> File "app/styles/app.scss" changed.

Running "compass:server" (compass) task
unchanged app/styles/main.scss
unchanged app/styles/modified-bootstrap-3.0.scss
unchanged app/styles/layoutPlugin.scss
overwrite .tmp/styles/app.css 

Running "watch" task

Completed in 3.883s at Wed May 08 2013 12:06:27 GMT-0400 (EDT) - Waiting...

@jamie-stackhouse I'm using Yeoman, which scaffolded out my initial Gruntfile (which I've modified heavily). The .tmp folder is where the compass task will compile the scss files that are in the app/styles folder of my project into css. I've tweaked it so that livereload could recognize changes to css files that may be in app/styles.

MoOx commented May 10, 2013

I'm also having hard time to switch from grunt-regarde + grunt-contrib-livereload to grunt-contrib-watch + connect-livereload :s

Owner
shama commented May 10, 2013

@MoOx What kind of problems?

I was about to open an issue about this (css soft refresh) when I saw this issue. Also having some troubles moving from regarde.

@Steida when I run:
→ npm grunt-contrib-watch -v
1.2.14

Is this ok?

Even with the option nospawn:true it still forces the browser to refresh.

Snugug commented May 12, 2013

Likewise I'm having an issue with this. I'm on watch 0.4.2 and the browser is refreshing even if the files are identical.

Owner
shama commented May 12, 2013

It is more important to explain the issues you guys are having rather than simply informing me that you're having one. :)

What was your expected behavior and what was the actual behavior? Running grunt with the --verbose flag will tell you which files are triggering the live reload. It seems this helped the OP and thus this issue should be closed. @appleYaks please tell me otherwise.

@lmartins That command is giving you the version number of npm. Try npm view grunt-contrib-watch instead.

Snugug commented May 12, 2013

Sorry, you're right!

Gruntfile (relevant portions):

module.exports = function (grunt) {
  grunt.initConfig({
    watch: {
      options: {
        livereload: 9001
      },
      css: {
        files: ['sass/{,**/}*.scss'],
        tasks: ['compass:dev'],
        options: {
          nospawn: true
        }
      }
    }

    compass: {
      options: {
        config: 'config.rb',
        bundleExec: true
      },
      dev: {
        options: {
          environment: 'development'
        }
      }
    }
  });

  grunt.event.on('watch', function(action, filepath) {
    grunt.config([
      'compass:dev'
    ], filepath);
  });
}

Verbose Grunt Watch:

>> File "sass/style.scss" changed.


Running "compass:dev" (compass) task
Verifying property compass.dev exists in config...OK
File: [no files]
Options: config="config.rb", bundleExec, environment="development"
unchanged sass/print.scss
overwrite stylesheets/style.css

Running "watch" task
Live reloading sass/style.scss...
Completed in 1.796s at Sat May 11 2013 22:10:39 GMT-0400 (EDT) - Waiting...

File is recompiled as expected and LiveReload is triggered as expected. The reload, however, does not behave as expected. Instead of refreshing the individual file that's been changed (I believe the way this is handled by the LiveReload app is by changing the cache key and forcing a single item refresh), the whole browser gets refreshed. The current behavior is undesirable because it doesn't allow for, in this case, CSS changes with in-place state changes in the site.

darvelo commented May 12, 2013

@shama --verbose helped me to determine that the .scss file was triggering livereload, but it's still not altogether clear to me why that's happening.. I don't have a livereload: true option set on the compass watch task, nor globally.

The watch task doesn't seem to catch the .css files changing every time they change also (but catches the .scss file):

Live reloading app/styles/app.scss�...
�Completed in 6.563s at Sat May 11 2013 22:31:30 GMT-0400 (EDT)� - Waiting...
��File ".tmp/styles/app.css" changed.

but no output after that.

@Snugug I think your issue is that you've defined livereload: 9001 on the global watch task. I believe this triggers livereload for all your watch tasks. That, combined with the fact that you're watching your sass files gives me a reason to think livereload is executing properly -- livereloading when sass files change. When watch catches a file change that isn't .css, it will refresh the browser.

Owner
shama commented May 12, 2013

Ah ha, thanks for the info guys. I think I know what is happening. The changed files are being collected together rather than per target thus not executing the live reload properly. Working on a fix now.

@shama shama closed this in c33545f May 12, 2013
Owner
shama commented May 12, 2013

Fixed and published in 0.4.3. Thanks everyone!

Snugug commented May 12, 2013

Huzzah! @shama 👍

Im still seeing a browser refresh every time i change my scss, after updating grunt-contrib-watch

Much likely something wrong on my config (im including only the relevant bits):

    compass: {
        dist: {                   // Target
            options: {              // Target options
                sassDir: 'sass',
                cssDir: 'styles',
                environment: 'production'
            }
        }
    },

    watch: {
        options: {
            livereload: 35729
        },
        css: {
            files: ['sass/{,**/}*.scss'],
            tasks: ['compass:dist'],
            options: {
                nospawn: true
            }
        }


grunt.registerTask('default', [
    'watch'
]);

Grunt verbose shows the following output:
Initializing
Command-line options: --verbose

Reading "Gruntfile.js" Gruntfile...OK

Registering Gruntfile tasks.
Reading package.json...OK
Parsing package.json...OK
Initializing config...OK

Registering "grunt-contrib-watch" local Npm module tasks.
Reading /Users/luismartins/Sites/learn/singularity/node_modules/grunt-contrib-watch/package.json...OK
Parsing /Users/luismartins/Sites/learn/singularity/node_modules/grunt-contrib-watch/package.json...OK
Loading "watch.js" tasks...OK
+ watch

Registering "grunt-contrib-compass" local Npm module tasks.
Reading /Users/luismartins/Sites/learn/singularity/node_modules/grunt-contrib-compass/package.json...OK
Parsing /Users/luismartins/Sites/learn/singularity/node_modules/grunt-contrib-compass/package.json...OK
Loading "compass.js" tasks...OK
+ compass
Loading "Gruntfile.js" tasks...OK
+ default

Running tasks: compass:dist

Running "compass:dist" (compass) task
Verifying property compass.dist exists in config...OK
File: [no files]
Options: sassDir="sass", cssDir="styles", environment="production"
overwrite styles/main.css

Done, without errors.
Live reloading sass/main.scss...
... Reload sass/main.scss ...
Completed in 6.098s at Sun May 12 2013 14:42:26 GMT+0100 (WEST) - Waiting...
Snugug commented May 12, 2013

Add a watch task for your CSS files and instead of nospawn for your Compass settings, set LiveReload: false

That did the trick, thanks @Snugug

Contributor
steida commented May 12, 2013

There must be some bug in your 0.4.3 fix. FSEventStreamStart error is back. And only one of several changes is actually watched. Investigating.

Contributor
steida commented May 12, 2013

It's strange. grunt.config has to use filepath, or it's watching will stop work after several file changes. I can't even hardcode 'client/app/css/app.styl' path.

grunt.event.on 'watch', (action, filepath) ->
  fileExtension = filepath.split('.')[1]
  switch fileExtension
    when 'styl'
      src = [filepath]
      # TODO: fix grunt watch issue
      # Once I add 'client/app/css/app.styl', watching will stop work after
      # several file changes.
      # if filepath != 'client/app/css/app.styl'
      #   src.push 'client/app/css/app.styl'
      grunt.config ['stylus', 'app', 'files'], [
        expand: true
        src: src
        ext: '.css'
      ]
    when 'coffee'
      coffeeArgs = [
        expand: true
        src: filepath
        ext: '.js'
      ]
      grunt.config ['coffee', 'app', 'files'], coffeeArgs
      grunt.config ['coffee2closure', 'app', 'files'], coffeeArgs
      grunt.config ['esteUnitTests', 'app', 'src'], filepath
    when 'soy'
      grunt.config ['esteTemplates', 'app'], filepath
      grunt.config ['esteUnitTests', 'app', 'src'], filepath 
Owner
shama commented May 12, 2013

@Steida There might be little we should do here for that FSEventStreamStart error. Node really shouldn't error out like that. It would be better to investigate a fix upstream where the error is occurring and figure out why. Rather than spending too much time here trying to jump around it. I'm unfortunately not able to reproduce it yet. I'll try your examples in a bit and see if I can reproduce with it. Thanks!

Owner
shama commented May 12, 2013

As for a resolution though... I recommend someone who is experiencing that issue to open up the issue on joyent/node. I'd open the issue myself although they will likely ask for more info to reproduce which I can't provide since I'm not able to reproduce.

Contributor
steida commented May 13, 2013

Hmm, I have found some workaround. If I move

// Close any previously opened watchers
// watchers.forEach(function(watcher, i) {
//   watcher.close();
// });
// watchers = [];

here

// On changed/added/deleted
this.on('all', function(status, filepath) {

  watchers.forEach(function(watcher, i) {
    watcher.close();
  });
  watchers = [];

Everything seems to be ok.

Contributor
steida commented May 13, 2013

Observation, when watching is stopped (seems that file changes are ignored), file change on another watch target will restart all. Until repeated file change ofc. Btw, there has to be some race condition. If I put some long running taks into queue, watching work. Hmm...

Contributor
steida commented May 13, 2013

Btw, I think there is a better solution then suggested one with special watch target for .css files. Also, next target means another watcher slowdown. In my opinion, all transpiled css should be rewritten automatically by default. It would cover 99% of use cases. Of course, make them optionable.

@lmartins can you share your Gruntfile.js with me? I'm trying to get this working, but wasn't sure what @Snugug comment was referring to specifically.

@dmackerman i've run into other issues so i moved back to regarde task for now. Im waiting for this to mature a little more so I can replace regarde with it.

Contributor
steida commented May 17, 2013

Same here. Btw, I think it's time to move from watchFile to watch. From
Node 0.9.2 it's stable even on Mac. And much faster because no polling. I
made my own grunt watcher v LR included, will be released soon.
Grunt-contrib-watch is not ready to production yet.

On Fri, May 17, 2013 at 5:53 PM, Luis Martins notifications@github.comwrote:

@dmackerman https://github.com/dmackerman i've run into other issues so
i moved back to regarde task for now. Im waiting for this to mature a
little more so I can replace regarde with it.


Reply to this email directly or view it on GitHubhttps://github.com/gruntjs/grunt-contrib-watch/issues/87#issuecomment-18069775
.

Owner
shama commented May 17, 2013

Thanks for your opinion guys! If you have a specific issue with this watch task then please discuss it here otherwise please move your discussion somewhere more appropriate. Thanks!

@dmackerman He was referring to @lmartins having his Gruntfile incorrectly configured to trigger live reload upon every watch target. Rather than on the files he would like to have trigger the live reload. Here is an example:

watch: {
  sass: {
    // This `sass` target will run compass to compile files
    // to my `dist/css/` folder.
    files: ['assets/sass/*.scss'],
    tasks: ['compass']
  },
  livereload: {
    // This target doesnt run any tasks
    // But when a file in `dist/css/*` is edited it will trigger the live reload
    // So when compass compiles the files, it will only trigger live reload on
    // the css files and not on the scss files
    files: ['dist/css/*'],
    options: { livereload: true }
  }
}

@shama is your solution above intended to be used in all cases where the soft reload is not working? I am using SASS, but not Compass, should my settings be different? I have been trying a bunch of different settings 9based on comments above) to try to get this to work - none work as I want. I have updated to the latest grunt-contrib-livereload and grunt-contrib-watch packages and it still does not soft reload, but it does hard reload. Here are my settings:

watch: {
    options: { livereload: true },
    scss: {
        files: ['resources/scss/**/*.scss'],
        tasks: ['sass:dev'],
        options: {
            nospawn: true
        }
    },

    js: {
        files: [
            'resources/js/*.js',
            'resources/js/libs/**/*.js',
            'resources/js/narrow/*.js',
            'resources/js/wide/*.js'
        ],
        options: {
            nospawn: true,
            interrupt: true
        },
        tasks: ['uglify']
    }
},

livereload: {
    files: 'resources/css/*',
    options: { livereload: true }
}

If I remove options: { livereload: true } from the watch task, the livereload does not work at all. Also, here's the output from grunt watch --verbose:

$ grunt watch --verbose
Initializing
Command-line options: --verbose

Reading "Gruntfile.js" Gruntfile...OK

Registering Gruntfile tasks.
Initializing config...OK

Registering "grunt-contrib-jshint" local Npm module tasks.
....
Loading "jshint.js" tasks...OK
+ jshint

Registering "grunt-contrib-sass" local Npm module tasks.
....
Loading "sass.js" tasks...OK
+ sass

Registering "grunt-contrib-copy" local Npm module tasks.
....
Loading "copy.js" tasks...OK
+ copy

Registering "grunt-contrib-uglify" local Npm module tasks.
....
Loading "uglify.js" tasks...OK
+ uglify

Registering "grunt-contrib-watch" local Npm module tasks.
....
Loading "watch.js" tasks...OK
+ watch

Registering "grunt-devtools" local Npm module tasks.
....
Loading "devtools.js" tasks...OK
+ devtools

Registering "grunt-contrib-livereload" local Npm module tasks.
....
Loading "livereload.js" tasks...OK
+ livereload, livereload-start
Loading "Gruntfile.js" tasks...OK
+ default

Running tasks: watch

Running "watch" task
Waiting...Verifying property watch exists in config...OK
Verifying property watch.scss.files exists in config...OK
Verifying property watch.js.files exists in config...OK
Live reload server started on port: 35729
[---long list of ALL the watched files---]

and after a change:

OK
>> File "resources/scss/narrow/_app.scss" changed.


Running "sass:dev" (sass) task
Verifying property sass.dev exists in config...OK
Files: resources/scss/site-wide.scss -> resources/css/site-wide.css
Files: resources/scss/site-narrow.scss -> resources/css/site-narrow.css
Files: resources/scss/site-wide-admin.scss -> resources/css/site-wide-admin.css
Options: unixNewlines, style="expanded", lineNumbers, debugInfo=false, precision=8
Reading resources/scss/site-wide.scss...OK
Writing resources/css/site-wide.css...OK
Reading resources/scss/site-narrow.scss...OK
Writing resources/css/site-narrow.css...OK
Reading resources/scss/site-wide-admin.scss...OK
Writing resources/css/site-wide-admin.css...OK

Running "watch" task
Live reloading resources/scss/narrow/_app.scss...
... Reload resources/scss/narrow/_app.scss ...
Completed in 3.867s at Tue May 28 2013 18:31:16 GMT+0100 (BST) - Waiting...
Verifying property watch exists in config...OK
Verifying property watch.scss.files exists in config...OK
Verifying property watch.js.files exists in config...OK
[---long list of ALL the watched files---]

Apologies for the giant comment but I cannot get this right and do not know why..

Owner
shama commented May 28, 2013

@mrmartineau No need to use grunt-contrib-livereload as livereload is built into the watch task. The livereload target in the example should be within the watch config object. I'm using the name livereload just to specify a watch task target that only triggers on files that I want but it can be named anything. Here is a more verbose example:

grunt.initConfig({
  watch: {
    scss: {
      files: ['resources/scss/**/*.scss'],
      tasks: ['sass:dev'],
      options: {
        nospawn: true,
        // We dont want to livereload with this scss target
        // As .scss files will be fed to the livereload server and cause a full page reload
      }
    },
    js: {
        files: [
            'resources/js/*.js',
            'resources/js/libs/**/*.js',
            'resources/js/narrow/*.js',
            'resources/js/wide/*.js'
        ],
        options: {
            nospawn: true,
            interrupt: true,
            // Dont livereload here either
        },
        tasks: ['uglify']
    },
    triggerLiveReloadOnTheseFiles: {
      // We use this target to watch files that will trigger the livereload
      options: { livereload: true },
      files: [
        // Anytime css is edited or compiled by sass, trigger the livereload on those files
        'dist/css/*.css',
        // Or a js file
        'dist/js/*.js',
      ]
    }
},

@shama that works perfectly! thank you so much

Really usefull info Kyle @shama , thanks.

@shama I'm unable to get this working (as in after sass runs and my css is updated, the page doesn't reload). What am I doing wrong?

files: {
            grunt: 'Gruntfile.js',
            root: 'arb/static',
            templates: 'arb/templates',
            css: '<%= files.root %>/css',
            sass: '<%= files.root %>/sass',
            js: '<%= files.root %>/js',
            img: '<%= files.root %>/img',
            sourceMap: 'main.min.map'
        },

        watch: {
            scripts: {
                files: [
                    '<%= files.grunt %>',
                    '<%= files.js %>/**/*.js'
                ],
                tasks: ['jshint'],
                options: {
                    livereload: true
                }
            },
            scss: {
                files: ['<%= files.sass %>/**/*.scss'],
                tasks: ['compass:dev'],
                options: {
                    nospawn: true
                }
            },
            markup: {
                files: [
                    '<%= files.templates %>/**/*.html',
                    '<%= files.root %>/**/*.php',
                    '<%= files.root %>/**/*.html'
                ],
                options: {
                    livereload: true
                }
            },
            livereload: {
                files: ['<%= files.css %>/**/*.css'],
                options: {
                    livereload: true
                }
            }
        },
Owner
shama commented Jul 1, 2013

@reintroducing Try running with grunt watch -v. It should show you the files it is sending to live reload.

Seems to be running as it should:

Running "compass:dev" (compass) task
Verifying property compass.dev exists in config...OK
File: [no files]
Options: sassDir="arb/static/sass", cssDir="arb/static/css", imagesDir="arb/static/img", outputStyle="expanded", debugInfo
unchanged arb/static/img/icon-s3ad1aacdb3.png
overwrite arb/static/css/main.css

and

Running "watch" task
Completed in 0.593s at Mon Jul 01 2013 15:32:01 GMT-0500 (CDT) - Waiting...
..bunch of files including:
Watching arb/static/css/main.css for changes.

Is that not the expected output?

Owner
shama commented Jul 1, 2013

@reintroducing Try installing the latest version of the watch. It should log Live reloading [filenames]... with verbose mode set. See this line: https://github.com/gruntjs/grunt-contrib-watch/blob/master/tasks/lib/livereload.js#L50

I've got version 0.4.4 which according to the package.json file in the repo is the latest :\

Owner
shama commented Jul 1, 2013

@reintroducing Hmm sorry no idea. It should work. I'd try commenting out all the watch targets but the livereload one. Then manually edit the files in arb/static/css/. Which OS and node version are you on btw?

node: v0.8.9
os: OSX 10.8.4

I'll give the commenting out targets a shot next time I'm working on the project and see if I can pinpoint it. Thanks for your help thus far, its greatly appreciated.

Owner
shama commented Jul 1, 2013

@reintroducing Oh try upgrading node. There have been a few fs.watch bugfixes for the older versions of node v0.8. Try upgrading to v0.8.25 or event better v0.10.12.

@shama So I updated to node v0.10.12 which did not fix the issue. I also commented out all my tasks except the one that's watching the css but still edited my sass file, saw the change pop up in my css file upon the task running, but the page didn't refresh. i then edited main.css directly (removing the change I made in the sass file basically) and i got the expected result, which basically seems like livereload is not picking up on my sass editing even though the css file IS in fact changing. :\

OK, so just for fun i removed the nospawn: true option from the scss task and it worked, though with a slight delay. it did, however, not do a full page refresh, just a soft refresh and the css switch took effect.

aarr0n commented May 15, 2014

@reintroducing - did you ever resolve this? I'm having exactly the same problem.

@aarr0n Yes, I did with the above explanation. I have a grunt-init template that I use to start my projects which you can check out here: https://github.com/reintroducing/threshold

This has all my Sass setup in the Gruntfile. Hope that helps.

aarr0n commented May 15, 2014

@reintroducing - I was hoping to find a solution that incorporated the spawn:false option and which did not reload the entire the page. spawn:false dramatically decreases the task time.

Here's what I'm currently using - its fast, but it still performs a page reload. Grateful if anyone can spot anything which could help...

    watch: {

        options: {
            livereload:true
        },

        sass: {
            files: ['<%= pkg.paths.sass %>**/*.scss'],
            tasks: ['scsslint', 'sass:dev', 'autoprefixer'],
            options: {
                spawn:false
            }
        },

        livereload: {
            files:[
                '<%= pkg.paths.css %>**/*.css',
                '<%= pkg.paths.js %>**/*.js',
                '<%= pkg.paths.views %>**/*.html',
                '!<%= pkg.paths.js %>vendor/**/*.js'
                ]
        }
    }

Owner
shama commented May 15, 2014

@aarr0n It looks you have livereload enabled across all targets in the watch. Which means edits to '<%= pkg.paths.sass %>**/*.scss' will also trigger live reload (and cause a full page refresh).

Try just enabling livereload on the files you want to trigger on:

watch: {
  livereload: {
    options: { livereload: true },
    files: [/* ... */],
  }
}
aarr0n commented May 16, 2014

@shama - thanks for reply... I should of highlighted that the only reason I've added this was because without it, no changes are reflected in the browser.

What I expect to happen with the suggested example below is that the sass compiles and triggers a reload of the css. This doesn't happen. I have to add the livereload option to the sass target just so I can see my changes.

If however, I remove the spawn:false everything works as expected, but is obviously slower.

    watch: {

        sass: {
            files: ['<%= pkg.paths.sass %>**/*.scss'],
            tasks: ['scsslint', 'sass:dev', 'autoprefixer'],
            options: {
                spawn:false
            }
        },

        livereload: {
            options: {
                livereload:true
            },
            files:[
                '<%= pkg.paths.css %>**/*.css',
                '<%= pkg.paths.js %>**/*.js',
                '<%= pkg.paths.views %>**/*.html',
                '!<%= pkg.paths.js %>vendor/**/*.js'
                ]
        }
Owner
shama commented May 16, 2014

@aarr0n Ah you're right. Looks like this is because of how spawn: false works. Grunt, atm, can only run a single task run in a series at a time (which includes the running watch task). With spawn: false, it schedules the tasks to run, schedules the watch task to run after those, and finishes the watch task so those tasks will run.

During the time those tasks are running, changes are not watched. FWIW, the watch task in the next version of Grunt doesn't have this limitation. There might be a way to continue watching for changes and schedule subsequent runs if a target is triggered during a run. If so, I'm open to pull request for it.

hilja commented Jun 13, 2014

Having spawn: true in the watch:sass task is the only way to get the soft reload (style injection) to work. The problem is that with spawn: false the CSS compiles 0.27s and with spawn: true it's around 2.7s. Using grunt-sass.

hilja commented Jun 14, 2014

Timed it and seems like the actual tasks only take only 319ms from the total 2.407s, when spawn: true.

Execution Time (2014-06-14 12:15:52 UTC)
sass:dist                  70ms  ▇▇▇▇▇▇▇▇▇▇▇▇ 22%
autoprefixer:single_file  247ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 77%
Total 319ms

Completed in 2.407s
Namek commented Aug 27, 2014

@aarr0n Run those watches through grunt-concurrent.

concurrent: ['watch:sass', 'watch:livereload']

This worked for me and now only css is being refreshed, not a whole page.

The only way I get to grunt-sass to do a soft reload of the css is using spawn: false globally and spawn:true in the sass task.

watch: {
    options: {
        spawn: false,
        livereload: true
    },
    sass: {
        options: {
            spawn: true,
            livereload: false
        },
        files: ['app/styles/{,*/}*.{scss,sass}'],
        tasks: ['sass']
    },
    css: {
        files: [
            '.tmp/styles/{,*/}*.css'
        ]
    }
}

still no fix for this? Having the same issue

x1024 commented Jul 13, 2015

@kirillgroshkov the grunt-concurrent thing works (it was suggested earlier in the thread).
Here is some more info: http://stackoverflow.com/a/18191735/140786

artuska commented Sep 25, 2016 edited

I have tried all those spawn: true|false tricks (with my original watch config below) and none of them is working in September 25th, 2016. (grunt-concurrent is totally offtopic — it has nothing to do with CSS soft reloading).

watch: {
    options: {
        livereload: 35729
    },
    locale: {
        files: 'app/assets/common/locale/**/*.yml',
        tasks: ['locale']
    },
    scripts: {
        files: 'app/assets/**/*.js',
        tasks: ['scripts']
    },
    styles: {
        files: 'app/assets/**/*.scss',
        tasks: ['styles']
    },
    templates: {
        files: 'app/assets/**/*.html',
        tasks: ['templates', 'scripts']
    }
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment