grunt: watch command never runs when including other tasks in registerTask method - gruntjs

I'm having some unexpected behavior with my Gruntfile. I've registered a task that looks like this: grunt.registerTask('dev', ['jekyll:server', 'watch:jekyll']) with the hopes that it will sequentially start a jekyll server, and then watch my project for specific file changes (using the grunt-contrib-watch plugin). Once it detects those changes, it would re-run jekyll:server automatically.
The problem I'm having is that when I run grunt dev, it will start the Jekyll server, but it will not run the watch commands. However, if I remove the server task from grunt dev, it will run the watch command as expected.
Below is the contents of my Gruntfile. Can anyone help me understand what is happening?
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
jekyll: {
server : {
server: true,
server_port: 4000,
exclude: ['node_modules']
},
prod: {
dest: './_site-release'
}
},
watch: {
jekyll: {
files: ['_posts/**/*.md', '_layout/*.html', '_includes/*.html', 'index.html'],
tasks: ['jekyll:server']
}
}
});
grunt.loadNpmTasks('grunt-jekyll');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', 'jekyll:server');
grunt.registerTask('dev', ['jekyll:server', 'watch:jekyll']);
grunt.registerTask('release', 'jekyll:prod');
};

The server option makes the task block since it's persistent. You can either use the tasks watch option or something like grunt-concurrent to run jekyll and watch concurrently:
grunt.initConfig({
concurrent: {
target: {
tasks: ['jekyll:server', 'watch'],
options: {
logConcurrentOutput: true
}
}
}
});
grunt.loadNpmTasks('grunt-concurrent');
grunt.registerTask('default', ['concurrent:target']);

Related

Grunt watch says 'waiting' not watching

so I am trying to get grunt working ( ive installed the relevant elements ) I'm not sure what settings i have wrong as, this is what comes up in the terminal after 'grunt watch'
$ grunt watch
Running "watch" task
Waiting...
it won't do anything until i hit save. then it will say a change has taken place.
i dont think this is how it's supposed to work.
my gruntfile is:
// Use "grunt --help" to list the available tasks
module.exports = function(grunt) {
grunt.initConfig({
sass: {
// this is the "dev" Sass config used with "grunt watch" command
dev: {
options: {
style: 'expanded',
},
files: {
// the first path is the output and the second is the input
'style.css': 'sass/style.scss',
'style_products.css': 'sass/style_products.scss',
'style-mega-menu.css': 'sass/style-mega-menu.scss'
}
},
// this is the "production" Sass config used with the "grunt default" command
dist: {
options: {
style: 'compressed',
},
files: {
'style.css': 'sass/style.scss',
'style_products.css': 'sass/style_products.scss',
'style-mega-menu.css': 'sass/style-mega-menu.scss'
}
}
},
// configure the "grunt watch" task
watch: {
sass: {
files: ['sass/*.scss', 'sass/**/*.scss',],
tasks: ['sass:dev']
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
// "grunt" is the same as running "grunt sass:dist".
grunt.registerTask('default', ['sass:dist']);
grunt.registerTask('dev', ['sass:dev']);
grunt.registerTask('default', ['watch',]);
};
can anyone pls help?

How to combine multiple watch tasks for different compass tasks in Grunt

We are having some problems finetuning our Grunt setup. Our current project setup is like this. We have a Themes folder, in that themes folder there are different themes that all hold their own SCSS files and other bits related to that theme.
Our grunt file is setup like this with around 15 themes (leaving out default Grunt setup and JSHint because in the end Grunt is working):
compass: {
options: {
...
}
theme1: {
src: ['App/Themes/theme1/scss/**/*.scss'],
tasks: ['compass'],
options: {
sassDir: 'App/Themes/theme1/scss',
cssDir: 'App/Themes/theme1'
}
},
theme2: {
src: ['App/Themes/theme2/scss/**/*.scss'],
tasks: ['compass'],
options: {
sassDir: 'App/Themes/theme2/scss',
cssDir: 'App/Themes/theme2'
}
},
...
}
concurrent: {
watch: {
tasks: ['compass:theme1', 'compass:theme2', ..., 'compass:themeXX'],
options: {
logConcurrentOutput: true,
spawn: false
}
}
}
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['concurrent']);
The actual issue then is that when we start the default task also x watch threads are started. Which have a lot of overhead for the small watch task they have to do.
The solution I'm looking for is a way to setup a single watch task that can trigger the specific theme compass compile. Is there a way to do that? Or is the current setup the only way to do it? So no other option than to have x watch tasks?
Thanks.
First, scaffold a watch task in your config object that watches files but doesn't execute any tasks. Using the glob pattern, tell the watcher to spy on all .scss files within the themes directory:
grunt.initConfig({
compress: {}, //your existing compress object goes here
watch: {
themes: {
files: ['App/Themes/**/*.scss'],
tasks: []
},
},
});
Next, you're going to add a grunt.event listener to your gruntfile. The listener event will expose the file changed (example: App/Themes/theme1/scss/foobar.scss). With that, you can now determine which compress target (theme1) to run:
grunt.event.on('watch', function(action, filepath, target) {
if (target === 'themes') {
var theme = filepath.split("/");
grunt.task.run('compress.' + theme[2]); //tells grunt to run "compress.theme1" based on this example
}
});

Grunt default task only runs first task in the list

I'm just getting started with grunt and just trying to get a few basic tasks working.
Here's my Gruntfile:
module.exports = function(grunt) {
grunt.initConfig({
compass: {
dist: {
options: {
config: 'config.rb',
watch: true
}
}
},
livecopy: {
your_target: {
options: {
source: "C:/Websites/xxx/styles/screen.css",
target: "W:/Websites/xxx/styles/screen.css"
},
},
},
watch: {
assets: {
files: ['**//*.css', '**/*.js'],
options: {
livereload: true,
},
},
},
});
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-livecopy');
grunt.task.registerTask('default', ['compass','livecopy','watch']);
};
I can run each of these tasks individually without any issues. When I run the grunt default task, only the first task in the default task list runs. It doesn't matter which order they are in, only the first one runs.
What am I missing?
When you run Compass with the watch option it runs compass watch which is a blocking task. From the grunt-contrib-compass docs:
watch
Type: Boolean
Runs compass watch instead of compass compile. This will use Compass'
native watch command to listen for changes to Sass files and recompile
your CSS on changes. While much faster than running compass compile
each time you want to compile your Sass, Compass becomes a blocking
task. This means that if you would like to use it in conjunction with
another blocking task, such as watch, you will need to use it in
conjunction with a paralleling task such as grunt-concurrent.

How to use grunt-forever and grunt-watch together

I have both files: app.js which starts the http server, and main.js which is compiled by browserify and used in html as
So I have a Grunt configured with forever, browserify and watch.
I want that on app.js chance, the http must be restarted (via forever:restart), and when main.js changes, the build must be browserified (via browserify)
so, when i run grunt, says forever:start does not exist, any help ?
$ grunt
Warning: Task "forever:server1:start" not found. Use --force to continue.
this is my gruntfile:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
dist: {
files: {
'examples/public/js/module.js': ['examples/main.js']
}
}
},
forever: {
server1: {
options: {
index: 'examples/app.js',
logDir: 'examples/logs'
}
}
},
watch: {
app: {
files: ['examples/*.js', 'examples/templates/*' ],
tasks: ['forever:server1:start']
},
web: {
files: ['examples/*.js', 'examples/templates/*' ],
tasks: ['browserify']
},
}
});
//grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-watch');
// Default task(s).
grunt.registerTask('default', ['browserify', 'forever:server1:start']);
grunt.registerTask('restart', ['browserify', 'forever:server1:restart']);
};
The task isn't found because you're missing grunt.loadNpmTasks('grunt-forever'). You might also find more success using something like nodemon instead of grunt.

Need to Perform a Grunt Watch Forever

I'm new to Node.js and Grunt... I'm attempting to use Node.js and Grunt on a Windows server to watch my main.less file and do a standard compile and concatinate. I'm able to do this while the command prompt is open, but I need this to run as a daemon while not logged into the server since the .less files get deployed from our CMS that sits in the cloud.
I found promising documentation in Grunt-Forever, but it requires you to point to an application, while I just want to perform the grunt watch task.
Someone else asked a similar question 9 months ago, but nobody gave an answer:
Grunt.js Watch Forever
I tried this from the command line:
FWIW, you can do forever /usr/local/bin/grunt --base . watch to use forever with grunt watch atm.
But, I got errors.
Here is my gruntfile:
module.exports = function(grunt) {
grunt.registerTask('watch', [ 'watch' ]);
grunt.initConfig({
concat: {
js: {
src: [
'js/global.js','js/googlemap.js'
],
dest: 'js/main.min.js'
},
},
uglify: {
options: {
mangle: false
},
js: {
files: {
'js/main.min.js': ['js/main.min.js']
}
}
},
less: {
style: {
files: {
"css/style.css": "less/main.less"
}
}
},
watch: {
js: {
files: ['js/global.js','js/googlemap.js'],
tasks: ['concat:js', 'uglify:js']
},
css: {
files: ['less/*.less'],
tasks: ['less:style']
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
};
Any help is much appreciated!
Use node to call grunt, use PM2 to run and manage node.
Try running the grunt watch task with nohup. Since you mentioned "Windows server" you can check this answer about nohup equivalent in Windows. Then you will have the grunt task running even when you log out of the server.

Resources