Monthly Archives: February 2014

Uploading a single changed file with Grunt

grunt-logo

I have embraced the node task runner Grunt recently and because I was grunting a little myself to get it to do what I wanted, I thought I’d share my experience to help others.

What Did I Want to Achieve?

My environment is pretty simple – I have a development LAMP running inside a local virtual machine and I wanted Grunt to upload files to that VM web server as they change. Sounds straight forward, right?

Started Well

I got to grips relatively well with the basics of Grunt and set up a watch (grunt-contrib-watch) task to monitor changes within my local development folder to then trigger things like minification or linting for example and then I wanted to upload the changed file.

There are many different file upload Grunt plugins ranging from rsync (grunt-rsync) to FTP (grunt-ftp-deploy) and I selected the sftp task from the grunt-ssh package. The fact that I chose this over the others is actually not relevant for the core challenge so you can choose whichever you wish.

The problem was that the sftp task (like any other upload related task) took a file pattern input within the config of the gruntfile.js (see example below). This is commonly a pattern like **/*.js for instance and not a specific file.

sftp:{
  upload:{
    options: {
      host: '<%= sshlogininfo.host %>',
      username: '<%= sshlogininfo.username %>',
      password: '<%= sshlogininfo.password %>',
      path:'/remote-path'
    },
    files:{'./':'**/*.js'} 
  }
}

Therefore, when the watch task is triggered, I wanted to ensure that the downstream tasks (the upload in my case) only needs to focus on that specific file and not a large set to be as fast as possible.

Events to the Rescue

My saviour came in the guise of events. The popular watch task emits a watch event, which allows you to do something simple like create a notification or in my case, change the configuration of a downstream Grunt task. It is important to note at this point, that the watch event is not the right place to run further Grunt tasks although you could. The documentation of the watch task does emphasise this but it is worth stressing as you may want to go down that path in a moment of weakness (read: this is exactly what I was thinking at one point). In my case, I needed to use the event listener to change the configuration of the files parameter for the sftp task and I did this with the following simple listener code in my gruntfile.js:

grunt.event.on('watch', function(action, filepath, target) {
  var files = {"./":filepath};
  grunt.config('sftp.upload.files', files);
});

With other upload tasks, it may be changing a src parameter instead but the principle is the same.

There are possibly other ways to crack this nut and I would absolutely welcome feedback and constructive critique on this as it would help me and others learn.

I hope this helps.