Renaming Grunt NPM Tasks

This is an old post!

This post is over 2 years old. Solutions referenced in this article may no longer be valid. Please consider this when utilizing any information referenced here.

For the last few years, Gulp has been my go-to task runner for Node projects and, generally, anywhere where I need to build things or run tasks. But the recent release of Gulp 4 broke all of my config files and left me with hours of frustrating rewrites, I decided to see what else might be out there. And, naturally, I landed on Grunt.

One thing I liked about Gulp (prior to 4.0) was it’s much looser structure that allowed a lot of freedom in how you structured your file. Grunt seems to be much more structured and opinionated. And sometimes, I don’t like those opinions.

A prime example of this is grunt-contrib-watch. When I type grunt watch, I want to run a series of setup tasks first before firing the watcher up. But grunt-contrib-watch squats on the prime real estate that is the watch command.

But I wanted to use that command. And there doesn’t seem to be any way to just say “run these arbitrary tasks before starting the watcher.” At least not one that I could find clearly documented. Sure, I could just make my own mywatch or similar command, but I’m picky. I want my command, so we need a way to rename it.

So how can I get grunt-contrib-watch to quit squatting on the watch command, but still maintain it’s functionality? Well, grunt provides a renameTask command. But simply calling that on watch that is specified in initConfig results in an endless loop. So we have to get creative:

grunt.registerTask('watch', function() {
    grunt.renameTask('watch', 'foo');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.config.set('watch', {
        build: {
            files: "src/foo",
            tasks: 'build'
        }
    });

    grunt.task.run('build:full');
    grunt.task.run('docker:up');
    grunt.task.run('watch');
});

See what happened there? We create our own watch task. Then, the first thing we do when it is called is have it rename itself. What we rename it to doesn’t matter because it’s disposable. Watch is a one-shot command, and we’re not going to execute it again in this run.

But once we’ve renamed it, we load in grunt-contrib-watch, add it’s config to Grunt like it always was there. Run whatever arbitrary tasks we need to run (an initial full build, bringing Docker containers up, etc.) Then, when we’re done, we call watch again, which now points to the correct watcher.

I have to admit, even I was impressed that this actually worked.

Comments (0)

Interested in why you can't leave comments on my blog? Read the article about why comments are uniquely terrible and need to die. If you are still interested in commenting on this article, feel free to reach out to me directly and/or share it on social media.

Contact Me
Share It
Release Announcements
petfeedd users, I am proud to announce the beta release of petfeedd 1.0.1. This release has no major changes in it and is solely about addressing security issues in many of the underlying libraries used by petfeedd. To install it or upgrade from previous versions, you can simply run: docker pull peckrob/petfeedd:latest
Read More
Release Announcements
After five beta releases and months of testing, I am happy to announce petfeedd Version 1.0 is now available. All changes from the beta branch have been merged in and the release is now available on Docker Hub. To install it or upgrade from Version 0.2, you can simply run: docker pull peckrob/petfeedd:latest And restart. It should perform all the upgrades needed for version 1.0.
Read More
Release Announcements
petfeedd users, I am proud to announce the beta release of petfeedd 1.0. It’s been almost three years since the last release of petfeedd (version 0.2.2), and Version 1.0 marks a new start for this project. I have been running the beta release on my feeders for the last week and I believe I have smashed all the major bugs.
Read More