Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grunt doesn't update main scss file

I have a project that uses GruntJS with grunt-contrib-sass, grunt-contrib-watch and grunt-newer.

My main app.scss file imports a few .scss files with the @import directive like

@import "common/vars.scss";

If I make changes in the main app.scss everything works. The problem is that when I make changes in a file that is being imported (like vars.scss), the app.scss doesn't get updated.

This is my watch task:

    watch: {
      css: {
        files: ['scss/**/*.scss'],
        tasks: ['newer:sass'],
        options: {
          spawn: false,
        }
      }
    }

And this is the sass task itself:

sass: {
      dist: {
        options: {
          style: 'compressed',
          noCache: true
        },
        /* looks for every .scss file in the scss folder (checks nested folders too), 
         * compile it and create another file wit the same name in the style folder */
        files: [{
          expand: true,
          cwd: 'scss',
          src: ['**/*.scss'],
          dest: 'style',
          rename: function (dest, src) {
            var folder    = src.substring(0, src.lastIndexOf('/'));
            var filename  = src.substring(src.lastIndexOf('/'), src.length);

            filename  = filename.substring(0, filename.lastIndexOf('.'));

            return dest + '/' + folder + filename + '.css';
          }
        }]
      }
    }

Any idea how to change the Gruntfile.js to cover this scenario too? :) Thanks.

like image 876
isHristov Avatar asked Jun 02 '14 10:06

isHristov


1 Answers

Note: This is a minimally modified copy of this comment in an issue on the grunt-newer GitHub page.


I came up with this simple delegation task that does the trick for tasks where you would like to react to changes other than specified in the src property:

grunt.initConfig( {
    delegate: {
        some_other_TASK: {
            src: [ 'some/src/path/**/*.ext' ],
            dest: 'some/dest/path/'
        }
    }
} );

grunt.registerTask( 'delegate', function() {
    grunt.task.run( this.args.join( ':' ) );
} );

A complete example for grunt-contrib-sass would look like the following:

module.exports = function( grunt ) {
    require( 'load-grunt-tasks' )( grunt );

    grunt.initConfig( {
        delegate: {
            sass: {
                src: [ 'scss/**/*.scss' ],
                dest: 'style'
            }
        },

        sass: {
          dist: {
            options: {
              style: 'compressed',
              noCache: true
            },
            files: [{
              expand: true,
              cwd: 'scss',
              src: ['*.scss'],
              dest: 'style',
              ext: '.css'
            }]
          }
        }
    } );

    grunt.registerTask( 'delegate', function() {
        grunt.task.run( this.args.join( ':' ) );
    } );
};

You just have to call newer:delegate:sass (via CLI, or some other task). grunt-newer checks the files given in the according delegate target (where I have the globbing pattern **/ included). If there are new files found (also .scss files in subfolders), the according sass task (with the given target) will be called.

I'm unsure, though, if making a separate grunt plugin would be of use here.


Edit: I recently released the above code (cleaned up) as separate npm package grunt-delegate.

like image 89
tfrommen Avatar answered Sep 23 '22 13:09

tfrommen