In using Grunt on a large project, I wanted to speed up the build time by only copying files to the staging area that have changed. Unless I missed something, the Grunt Copy plugin always copies all files, regardless if they were changed or not. It does provide hooks that we can use in determining what should be copied, thus I created this small function that does just that using the filter parameter. The function simply compares the time stamp of the FROM file to the TO file, and tells the Copy plugin if it should copy it or not.

The function below can also be found in this GIST:


In your Gruntfile.js, include the above function before defining your grunt configuration. Then use it in the Copy task as:


    copy: {
        build: {
            src:    "src/**,
            dest:   "build/",
            expand: true,
            filter: onlyNew(['copy', 'build'])



The example above will copy files from a the src folder to the build folder, but only if they are newer than those currently in the build folder. Note the use of expand: true, which is necessary in order for this work.

Using a Local Time Stamp File for Destination

I often use the Copy task to copy files over the network to a server – usually a linux mounted directory or a SharePoint document library folder. I call it my deployment task. Both of these types of destinations can be very slow when copying large amounts of files because the Copy task needs to access file information on the destination in order to determine if the file should be copied or not. To get around that performance issue, a second parameter can be given to the onlyNew function – a path to a local file – that will be used as the Destination file to compare time stamps to. That file will be “touched” at the end of the build so that it insures the next time the grunt task is ran, it will be comparing file time stamps against the last run.

Here is an example of a Copy task that uses a local file for comparing time stamps:

    copy: {
        deploy: {
            src:    "build/**,
            dest:   "//",
            expand: true,
            filter: onlyNew(['copy', 'build'], "build/copy.deploy.last.deployed.txt")


I use this function in several projects to assist with a more efficient build. Perhaps I should create a Grunt plugin out of it, so that it can be better incorporated into a build by defining it as a dependency in the package.js.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s