Grunt run task with override config - gruntjs

I always used gulp for all my tasks automation, but in our current project we use grunt and I can't figure out how to make very simple thing:
grunt.initConfig({
watch: {
scripts: {
files: '**/*.js',
tasks: ['karma:watch:run'],
}
},
myWatch: {
scripts: {
files: '**/*.js',
tasks: ['do_my_own_task_but_not_karma'],
}
}
});
//current task
grunt.registerTask('default', ['watch']);
//doesn't work
grunt.registerTask('myWatchTask', ['myWatch']);
Basically I just want to override current watch config for my own custom task, because I don't want karma to run tests each time I change js file.

You need to add an new configuration within the watch configuration object:
grunt.initConfig({
watch: {
main: {
scripts: {
files: '**/*.js',
tasks: ['karma:watch:run'],
}
},
myWatch: {
scripts: {
files: '**/*.js',
tasks: ['do_my_own_task_but_not_karma'],
}
}
},
});
Then you can run grunt watch:main or grunt watch:myWatch, see these docs.
If you want to have something that is watched always you can add it to the root of the watch configuration object.
grunt.initConfig({
watch: {
files: '**/always.js',
tasks: ['always'],
main: {
scripts: {
files: '**/*.js',
tasks: ['karma:watch:run'],
}
},
myWatch: {
scripts: {
files: '**/*.js',
tasks: ['do_my_own_task_but_not_karma'],
}
}
},
});
now grunt watch:myWatch will run it's dedicated config and the config in the root of the watch configuration object.

Related

Get Grunt to upload files after watch is triggered

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']);
}

Set up grunt to build Jekyll site, serve & livereload

I have a simple Jekyll site, and am using grunt to compile LESS files.
I want to build in the ability to continue compiling .less files, building the jekyll site & serving it locally. I also have a task to watch and copy compiled css files into the jekyll _site folder.
However the Grunftile I have at the moment isn't quite working:
module.exports = function (grunt) {
grunt.initConfig({
// compile set less files
less: {
development: {
options: {
paths: ["assets/less"],
yuicompress: true,
compress: true
},
files: {
"assets/css/site.css": ["assets/less/*.less", "!assets/less/_*.less"]
}
}
},
// watch changes to less files
watch: {
styles: {
files: ["less/**/*"],
tasks: ["less", "copy:css"]
},
options: {
livereload: true,
spawn: false,
},
},
// copy compiled css to _site
copy: {
css : {
files: {
cwd: './assets/css/',
src: 'site.css',
dest: './_site/assets/css',
expand: true
}
}
},
// run jekyll command
shell: {
jekyll: {
options: {
stdout: true
},
command: 'jekyll build'
}
},
// jekyll build
jekyll: {
files: [
'*.html', '*.yml', 'assets/js/**.js',
'_posts/**', '_includes/**'
],
tasks: 'shell:jekyll',
options: {
livereload: true
}
},
exec: {
server: {
command: 'jekyll serve -w'
}
},
concurrent: {
options: { logConcurrentOutput: true },
server: {
tasks: ['watch', 'exec:server']
}
}
});
// Load tasks so we can use them
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-contrib-less");
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-concurrent');
// the default task will show the usage
grunt.registerTask("default", "Prints usage", function () {
grunt.log.writeln("");
grunt.log.writeln("Using Base");
grunt.log.writeln("------------------------");
grunt.log.writeln("");
grunt.log.writeln("* run 'grunt --help' to get an overview of all commands.");
grunt.log.writeln("* run 'grunt dev' to start watching and compiling LESS changes.");
});
grunt.registerTask("dev", ["less:development", "watch:styles", "copy:css", "shell:jekyll", "concurrent:server"]);
};
It's probably better to have Grunt also building Jekyll, using grunt-jekyll https://github.com/dannygarcia/grunt-jekyll. I suspect you're having issues with Jekyll cleaning the output directory after your copy task has placed your compiled LESS output there, so it's important your tasks are run in the correct sequence.
There's an excellent Yeoman generator with a complete Jekyll / Grunt workflow that's also worth checking out; https://github.com/robwierzbowski/generator-jekyllrb and if you don't want to use Yeoman then you will at least find some helpful pointers in the Gruntfile https://github.com/robwierzbowski/generator-jekyllrb/blob/master/app/templates/Gruntfile.js

grunt browser sync not injecting changes

I'm trying to get grunt-browser-sync to inject any css changes into an open browser when a file is updated/changed. But for some reason, I can seem to get it to work and grunt is not giving me any errors to let me know it's not working.
I'm currently using MAMP since it's a Wordpress based project.
Here's my Gruntfile.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
build: {
src: '_/js/libs/*.js', //input
dest: '_/js/functions.min.js' //output
}
},
sass: {
dist: {
options: {
loadPath: require('node-bourbon').includePaths,
loadPath: require('node-neat').includePaths,
style: 'compressed'
},
files: {
'style.css': 'scss/style.scss'
}
}
},
autoprefixer: {
dist: {
files: {
'style.css': 'style.css'
}
}
},
browserSync: {
dev: {
bsFiles: {
src : 'style.css'
},
options: {
watchTask: true
}
}
},
watch: {
options: {
livereload: true
},
js: {
files: ["_/js/libs/*.js"],
tasks: ["ugilify"],
},
sass: {
files: ["scss/*.scss"],
tasks: ["sass", "autoprefixer", "browserSync"],
},
php: {
files: ['*.php']
},
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-browser-sync');
// Default task(s).
grunt.registerTask('default', ['uglify', 'sass', 'browserSync', 'watch', 'autoprefixer']);
};
and here's the output when I save/update a file:
Running "watch" task
Waiting...
>> File "scss/global.scss" changed.
Running "sass:dist" (sass) task
File style.css created.
Running "autoprefixer:dist" (autoprefixer) task
File style.css created.
Running "browserSync:dev" (browserSync) task
Done, without errors.
Completed in 1.478s at Wed May 07 2014 18:47:40 GMT-0500 (CDT) - Waiting...
But then I have to physically refresh the browser to see the changes.
I'm not sure if I am missing something within the grunt file or what.
The only version of grunt-browser-sync that works for me with this code is 1.9.1. So, un-install your current version and
npm install grunt-browser-sync#1.9.1 --save-dev
I encountered the same issue and have opened an issue here
Github grunt-browser-sync repo with issues 58

Grunt SCSS - Not reloading

I am trying to achieve a smooth workflow.
my problem:
My JS modifications are shown and minified and the live reload works fine. When I make changes to my SCSS files they do not run under the run command:
grunt
or the grunt plugin:
grunt watch
It only works when I invoke:
grunt sass
This was the output from the 'grunt sass' console window:
Macintosh:grunt-test Neil$ grunt sass
Running "sass:dist" (sass) task
File "css/global.css" created.
Done, without errors.
Notes:
When I run 'grunt watch' on a sass file I have noticed that grunt runs the minification on the javascript for no reason. Surely this be invoked when that file or one of its dependencies is effected?
Gruntfile.js Contents:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: {
files: ['css/*.css'],
livereload: true
},
css: {
files: ['css/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
scripts: {
files: ['js/*.js', 'scss/*.scss'],
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
},
sass: {
dist: {
options: {
style: 'compressed'
},
expand: true,
cwd: 'scss/',
src: ['*.scss'],
dest: 'css/',
ext: '.css'
}
},
concat: {
// 2. Configuration for concatinating files goes here.
dist: {
src: [
'js/libs/*.js', // All JS in the libs folder
'js/global.js' // This specific file
],
dest: 'js/build/production.js',
}
},
uglify: {
build: {
src: 'js/build/production.js',
dest: 'js/build/production.min.js'
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'images-lossy/',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/'
}]
},
png: {
options: {
optimizationLevel: 7
}
},
jpg: {
options: {
progressive: true
}
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
// CONCATENATION PLUGIN
grunt.loadNpmTasks('grunt-contrib-concat');
// MINIFY PLUGIN
grunt.loadNpmTasks('grunt-contrib-uglify');
// IMG CRUSH PLUGIN
grunt.loadNpmTasks('grunt-contrib-imagemin');
// GRUNT WATCH PLUGIN
grunt.loadNpmTasks('grunt-contrib-watch');
// SASS LIBARY PLUGIN
grunt.loadNpmTasks('grunt-contrib-sass');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['sass','concat', 'uglify', 'imagemin', 'watch']);
};
I hope the above information helps. I have previously used Codekit, and it a really great app. I want to move to grunt but maybe my configuration file is incorrect I am close.
Any help would be greatly appreciated.
Neil
It looks like both of your issues occur within the watch configuration.
First, the reason the SASS task isn't working during watch is due to the files entry pointing to the wrong location. Your current files entry points to the "css" folder, but it should point to the "scss" folder, according to what you've specified in the actual "sass" task. In other words, your entry should be: files: ['scss/*.scss'].
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
}
Second, the JavaScript minification occurs during the watch whenever a SASS file changes because you have it listed here:
scripts: {
files: ['js/*.js', 'scss/*.scss'], // <-- scss is covered here
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
Change it to files: ['js/*.js'], instead to have the watch task kick in for JavaScript files only.
Once you address those issues, if things are slightly working you might want to expand the patterns so that it covers all files in the subdirectories for your JavaScript, CSS, SASS, etc. For example, js/*.js includes all .js files under the js folder, while js/**/*.js covers the js folder and its subfolders. You can read more under the GruntJS "globbing patterns" documentation.
EDIT: here's how the updated watch should look like...
watch: {
options: {
livereload: true
},
// css is really for Sass
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
// scripts will detect js changes
scripts: {
files: ['js/**/*.js'],
tasks: ['jshint', 'concat', 'uglify'],
options: {
spawn: false,
}
}
},
As mentioned, your individual tasks might need to use the ** pattern similar to what I've done with the "scripts" entry above: js/**/*.js

Use both grunt-contrib-less and grunt-nodemon

It seems that when the nodemon running ,the other tasks will be pending and not runned. How can I use both of them? or whether I can use nodemon to watch less files and compile them?
Here is my Gruntfile.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
nodemon: {
dev: {
options: {
file: 'app.js',
nodeArgs: ['--debug'],
env: {
PORT: '3000'
}
}
}
},
less: {
development: {
options: {
paths: ['./public/less'],
yuicompress: true
},
files: {
'./public/css/test.css': './public/less/test.less'
}
}
},
watch: {
files: "./public/less/*.less",
tasks: ['less']
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-nodemon');
grunt.registerTask('default', ['less','watch']);
};
What you're looking for is grunt-concurrent, a task that allows you to run multiple tasks asynchronously and it's incredibly common for blocking tasks such as watch or nodemon.
https://github.com/sindresorhus/grunt-concurrent
As for nodemon, a prime example of this is located directly on the github page for grunt-nodemon using grunt-concurrent under the section 'Advanced Usage'.
https://github.com/ChrisWren/grunt-nodemon#advanced-usage
Hope this is what you're looking for.

Resources