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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With