I'm still rather new to Grunt so maybe someone with more experience can help me with this. For some reason anytime I run grunt watch the uglify task is getting executed multiple times so my scripts.min.js file is getting compiled multiple times.
This is what my Gruntfile.js currently looks like:
'use strict';
module.exports = function(grunt) {
// Show elapsed time
require('time-grunt')(grunt);
// Comment out any unused components
var jsFiles = [
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/affix.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/alert.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/button.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/carousel.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/collapse.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/dropdown.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/modal.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/popover.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/scrollspy.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tab.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tooltip.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/transition.js',
'assets/js/*.js'
];
// Configure tasks.
grunt.initConfig({
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'assets/css/main.min.css': 'assets/sass/app.scss',
'assets/css/custom-login.min.css': 'assets/sass/_login.scss',
'assets/css/magnific.min.css': 'assets/sass/plugins/magnific/magnific.scss'
}
}
},
uglify: {
dist: {
files: {
'assets/js/scripts.min.js': [ jsFiles ]
}
}
},
watch: {
sass: {
files: [ 'assets/sass/*.scss' ],
tasks: [ 'sass' ]
},
js: {
files: [ jsFiles ],
tasks: [ 'uglify' ]
}
}
});
// Load tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
// Register tasks.
grunt.registerTask('default', [
'watch',
'sass',
'uglify'
]);
};
Anyone have any ideas why the uglify task is executing multiple times?
The problem is that you have all the js files to inspect and minify. The main problem is:
'assets/js/*.js'
You are compressing all the js files, but also you are watching then, so when you uglify all the js files, they changed, and for that reason the watch task executes and minify again....and that's the infinite loop.
You should change your gruntfile, for example removing scripts.min.js of the assets folder, or removimg assets/js/*.js and adding manually all your js files. I recommend apply the second one.
'use strict';
module.exports = function(grunt) {
// Show elapsed time
require('time-grunt')(grunt);
// Comment out any unused components
var jsFiles = [
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/affix.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/alert.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/button.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/carousel.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/collapse.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/dropdown.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/modal.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/popover.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/scrollspy.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tab.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tooltip.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/transition.js'
];
// Configure tasks.
grunt.initConfig({
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'assets/css/main.min.css': 'assets/sass/app.scss',
'assets/css/custom-login.min.css': 'assets/sass/_login.scss',
'assets/css/magnific.min.css': 'assets/sass/plugins/magnific/magnific.scss'
}
}
},
uglify: {
dist: {
files: {
'assets/js/scripts.min.js': [ jsFiles ]
}
}
},
watch: {
sass: {
files: [ 'assets/sass/*.scss' ],
tasks: [ 'sass' ]
},
js: {
files: [ jsFiles ],
tasks: [ 'uglify' ]
}
}
});
// Load tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
// Register tasks.
grunt.registerTask('default', [
'watch',
'sass',
'uglify'
]);
};
Regards.
Related
can you please take a look at the following Gruntfile to see if you can determine why it isn't running cssnano and autoprefixer?
Grunt is currently watching my project and with each save grunt-sass compiles fine but neither grunt-cssnano or autoprefixer are doing their thing and no errors are reported.
Done, without errors.
Completed in 1.906s at Wed Nov 25 2015 13:12:18 GMT+0000 (GMT Standard Time) - Waiting...
File "sass\styles.scss" changed.
Running "sass:dist" (sass) task
I figure I've done something wrong with grunt-contrib-watch setup (specifically the css part) but that's just a guess.
My project folder looks like so
dist
css
styles.css
node_modules (includes all relevant packages)
sass
styles.css
Gruntfile.js
package.json
And my Gruntfile is as follows
module.exports = function (grunt) {
grunt.initConfig({
sass: {
options: {
sourceMap: false
},
dist: {
files: {
'dist/css/styles.css': 'sass/styles.scss'
}
}
},
postcss: {
options: {
map: {
inline: false,
annotation: 'dist/css/maps/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
}),
require('cssnano')()
]
},
dist: {
src: 'dist/css/styles.css'
}
},
watch: {
sass: {
files: 'sass/*.scss',
tasks: ['sass']
},
css: {
files: 'dist/css/styles.css',
tasks: ['cssnano', 'autoprefixer']
}
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-cssnano');
grunt.registerTask('default', ['watch', 'sass', 'postcss:dist', 'cssnano', 'autoprefixer']);
};
registering a task like you do :
grunt.registerTask('default', ['watch', 'sass', 'postcss:dist', 'cssnano']);
will execute the tasks one by one. So in your case, only the watch task will be executed because it "never ends" till you finish it. So the sass, postcss:dist, cssnano wont be reached.
So in your case it will execute the watch task only, which will watch the *.scss files to execute the sass task and watch the style.css to execute the cssnano and autoprefixer task.
But these 2 last tasks aren't defined in your config, so it won't do anything.
To solve your problem, remove the tasks from your default registered task because they aren't used :
grunt.registerTask('default', ['watch']);
And add a config for each missing task. for example:
cssnano: {
options: {
sourcemap: true
},
dist: {
files: {
'dist/css/styles.min.css': 'dist/css/styles.css'
}
}
},
//and same for autoprefixer
With a lot more trial and error it looks like I have a solution. The below file now runs Sass, cssnano, autoprefix and watch. Sass, cssnano and autoprefix packets (and I assume any others that are added in future) will do their thing in grunt.initConfig while and at the bottom of the file registerTask takes care of watch.
More work is need to figure out how to create other registerTasks but that's for another day.
Thanks to Mian who set me on the right track.
module.exports = function (grunt) {
grunt.initConfig({
sass: {
options: {
sourceMap: false
},
dist: {
files: {
'dist/css/styles.css': 'sass/styles.scss'
}
}
},
postcss: {
options: {
map: {
inline: false,
annotation: 'dist/css/maps/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
}),
require('cssnano')()
]
},
dist: {
src: 'dist/css/styles.css'
}
},
watch: {
sass: {
files: 'sass/*.scss',
tasks: ['sass', 'postcss']
},
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-cssnano');
grunt.registerTask('default', ['watch']);
};
I have installed bootstrap using sass, however my scss files are not compiling to the css folder.
I was able to install the bootstrap, using bower.
This is my gruntfile.js
/*jslint node: true */
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
loadPath: ['./bower_components/bootstrap-sass/assets/stylesheets']
},
dist: {
options: {
outputStyle: 'expanded',
sourceMap: false
},
files: {
'css/bootstrap.css' : 'stylesheets/_bootstrap.scss',
}
}
}, // sass
compass: {
dev: {
options: {
config: 'config.rb'
}
} // dev
}, //compass
watch: {
options: {
livereload: true,
dateFormat: function(time) {
grunt.log.writeln('The watch finished in ' + time + 'ms at ' + (new Date()).toString());
grunt.log.writeln('Waiting for more changes...');
} //date format function
}, //options
scripts: {
files: ['*.js']
}, // scripts
//Live Reload of SASS
sass: {
files: ['stylesheets/*.scss', 'stylesheets/bootstrap/*.scss'],
tasks: ['sass']
}, //sass
css: {
files: ['stylesheets/*.scss', 'stylesheets/bootstrap/*.scss'],
tasks: ['compass']
},
html: {
files: ['*.html']
}
}, //watch
postcss: {
options: {
processors: [
require('autoprefixer-core')({
browsers: 'last 2 versions'
})
]
}
}, //post css
jshint: {
options: {
reporter: require('jshint-stylish')
},
target: ['*.js', 'js/*.js']
} //jshint
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('build', ['sass']);
grunt.registerTask('default', ['build', 'watch', 'compass', 'jshint']);
}
I would like to know, what step I am missing, because I have followed the directory paths correctly. My config.rb file, I have changed the sass directory to stylesheets.
When I run, sudo grunt, no errors are found but the stylesheet is not compiling.
In SCSS, files starting with _ (underscore) are typically ignored. See: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#partials
This also applies to grunt-sass.
I am working on a site that uses SCSS. We have grunt watching those files to convert them to css but each time we make a change we have to tab over to the css file and upload. Maybe not a big deal but over time on different projects it adds up.
I would like the watch process to run ftpush once it see's a change but the only times I've got it to work it stays on ftpush which means we have to exit grunt then run it again. It would be helpful if after the upload os complete(or a specific time passes) it resumes the watch task.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
loadPath: ['bower_components/foundation/scss'],
sourceMap: true
},
dist: {
options: {
style: 'expanded'
},
files: {
'assets/css/app.css': 'assets/scss/app.scss'
}
}
},
ftpush: {
build: {
auth: {
host: 'OUR HOST',
port: 21,
authKey: 'key1'
},
src: '../vhc-master',
dest: '/var/www/html/vhc/dev/wp-content-themes/vhc-master'
}
},
watch: {
scripts: {
files: ['Gruntfile.js'],
tasks: ['ftpush'],
options: {
interrupt: true,
reload: true
}
},
sass: {
files: 'assets/scss/*.scss',
tasks: ['sass']
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-ftpush');
grunt.registerTask('build', ['sass']);
grunt.registerTask('deploy', ['ftpush']);
grunt.registerTask('default', ['build','watch']);
}
I am not sure why Grunt isn't generating my HTML?
Is there a mistake with my gruntfile?
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-haml');
grunt.initConfig({
uglify: {
my_target: {
files: {
'js/script.js': ['javascripts/*.js']
} //files
} //my_target
}, //uglify
sass: {
dist: {
options: {
sourcemap: true,
compass: true
}, //options
files:{
'stylesheets/style.css': 'sass/style.scss'
} //files
} //dist
}, //sass
haml: { // Task
dist: { // Target
files: { // Dictionary of files
'index.html': 'index.haml' // 'destination': 'source'
}
}
},
watch: {
options: { livereload: true },
scripts: {
files: ['javascripts/*.js'],
tasks: ['uglify']
}, //script
css: {
files: ['sass/*.scss'],
tasks: ['sass']
}, //sass
html: {
files: ['*.haml'],
task: ['haml']
}
} //watch
}) //initConfig
grunt.registerTask('default', ['haml', 'watch']);
} //exports
Old question, but I had the same issue, and here's what it was for anyone's future reference.
The gruntfile that I downloaded (like this one) had 'task' instead of 'tasks'. So the watch task is running, and you'll get notified that a file has changed, but no actual tasks will be run. Correct the typo and you're back in action!
Figure this out.
There is no problem with the code itself.
It is the terminal screwing up.
I would like to run the jshint task twice in GruntJS, but with different options each time.
How would I go about doing something like that?
Currently, my Gruntfile.js looks like this:
'use strict';
module.exports = function(grunt) {
var opts = {
pkg: grunt.file.readJSON('package.json'),
jasmine_node: {
matchall: true,
forceExit: true
},
jshint: {
files: [
'gruntfile.js',
'src/**/*.js', '!src/static/bin', '!src/static/js/libs/*.js',
'test/spec/**/*.js'
],
options: {
jshintrc: '.jshintrc'
}
}
};
grunt.initConfig(opts);
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.registerTask('default', ['jshint', 'jasmine_node']);
grunt.registerTask('travis', ['jshint', 'jasmine_node']);
};
And I would probably want it to be something like this:
var jshint: {
files: [
'gruntfile.js',
'src/**/*.js', '!src/static/**',
'test/spec/**/*.js'
],
options: {
jshintrc: '.jshintrc'
}
}
var jshint2 = {
files: [
'src/static/**/*.js',
'!src/static/bin',
'!src/static/js/libs/*.js'
],
options: {
jshintrc: '.jshintrc-browser'
}
};
So that I can pick different options for the front-end javascript and the NodeJS javascript, since linting should be different for each of those environments
jshint is a multitask. So it is possible to have to following config:
jshint: {
browser: {
files: [
'src/static/**/*.js',
'!src/static/bin',
'!src/static/js/libs/*.js'
],
options: {
jshintrc: '.jshintrc-browser'
}
},
node: {
files: [
'gruntfile.js',
'src/**/*.js', '!src/static/**',
'test/spec/**/*.js'
],
options: {
jshintrc: '.jshintrc'
}
}
}
To run the browser version:
grunt jshint:browser.
To run to node version:
grunt jshint:node.
Running just:
grunt jshint
will run both.
Of course, you probably will want to trigger them via another task, e.g:
grunt.registerTask('build', ['clean:all', 'jshint:browser', ...]);
You want want to read the section Specifying JSHint options and globals for more info.