Nodemon-like task in Grunt : execute node process and watch
Edit: grunt-nodemon
since writing this, a nice person developed that.
I was having a lot of trouble using grunt.util.spawn to fire off new processes. They would run, but they wouldn't give me any output back. Perhaps you can figure out what I could not in these docs. http://gruntjs.com/api/grunt.util#grunt.util.spawn
Two problems I see with what you have:
- I think grunt.registerTask() has to take three arguments when you use a callback function to run your task.
- I don't think you can just call
node server.js
over and over again everytime a file changes. It will work on the first time, for it to really work you'd have to manage the server as a child process, killing and restarting it on subsequent file changes.
For the registerTask arguments try this, just to see if you can get something to work in your current implementation.
http://gruntjs.com/api/grunt.task#grunt.task.registertask
It takes (taskName, description, taskFunction)
like so:
grunt.registerTask('start', 'My start task description', function() { grunt.util.spawn({ cmd: 'node', args: ['server.js'] }); grunt.task.run('watch');});
That might at least get your watch
to run node server.js
the first time a file changes.
Here's what I would do instead.
Either just use nodemon $ nodemon server.js
as is
or...
Read the source and use grunt-develop
He is managing the server as a child process, might be what you're looking for.
or...
Get grunt-shellnpm install grunt-shell --save-dev
And use it to run nodemon for you:
module.exports = function(grunt) { // Project configuration. grunt.initConfig({ serverFile: 'server.js', shell: { nodemon: { command: 'nodemon <%= serverFile %>', options: { stdout: true, stderr: true } } }, watch: { /* nothing to do in watch anymore */ } }); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-shell'); grunt.registerTask('default', 'shell:nodemon');};
$ grunt shell:nodemon
I sincerely hope that helps. Good luck!
Hi I also came across this problem and here is my solution (based on nackjicholson's answer). This uses grunt-nodemon in a spawned process. so I can:
- Reload nodejs
- Watch for changes to e.g. .less files
Get output of both tasks
grunt.loadNpmTasks('grunt-nodemon');grunt.initConfig({ nodemon: { dev: { options: { file: 'server.js', nodeArgs: ['--debug'], env: { PORT: '8282' } } } },});grunt.registerTask('server', function (target) { // Running nodejs in a different process and displaying output on the main console var nodemon = grunt.util.spawn({ cmd: 'grunt', grunt: true, args: 'nodemon' }); nodemon.stdout.pipe(process.stdout); nodemon.stderr.pipe(process.stderr); // here you can run other tasks e.g. // grunt.task.run([ 'watch' ]);});
Use grunt-concurrent
The issue is that tasks like watch and nodemon will never terminate, so grunt will never reach them. You need to spawn a new process.
You can do this easily using grunt-concurrent:
https://github.com/sindresorhus/grunt-concurrent
For example:
module.exports = function(grunt) { grunt.initConfig({ ... concurrent: { dev: { tasks: ['nodemon', 'watch'], options: { logConcurrentOutput: true } } } });};
The two will now run happily side by side.