Using Grunt to automatically build your PhoneGap/Cordova projects

This post is more than 2 years old.

Earlier this week I blogged about the relaunch of Ripple, a great tool for building your mobile applications with Chrome. One of the issues with the new version of Ripple is that when you edit your code, you have to run "cordova prepare" to copy the assets into your platform before you can view it in the browser.

You can get around this by just directly editing the code in your platform directory, but by doing so you run the risk of accidentally blowing it away the next time you do a build with Cordova. So the only safe method is to edit in your main www folder and run "cordova prepare" after every single save, which kinda sucks, even if you just use !! to run the last command or up arrow/enter (which should work on both Windows and OS X I believe).

I was thinking about this today and I thought that this could be a good use of Grunt. Grunt is a JavaScript task runner (it reminds me of Ant, but using JavaScript) with a large set of plugins for a variety of tasks. I've been interested in it, but haven't really had an opportunity to make use of it yet. (Check out this article on it over at Smashing Magazine: Get Up and Running with Grunt.)

I knew Grunt supported two different types of plugins I'd need. First is the ability to watch files for changes. The second is the ability to run ad hoc shell scripts. I whipped up the following example. Please note this is my very first Grunt script and I probably did it completely wrong.

module.exports = function(grunt){

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        exec:{
        	prepare:{
        		command:"cordova prepare",
        		stdout:true,
        		stderror:true
        	}
        },
        watch:{
        	files:['www/**/*.*'],
        	tasks:['exec:prepare']
        }
    });

	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-exec');

    grunt.registerTask('default', ['watch']);

};

Even if you've never seen Grunt before you can probably follow the flow. I've basically told Grunt to run the watch task by default, monitor the www folder (remember, this is where Cordova keeps the web assets it will copy into each platform) and when a change is noticed, run cordova prepare. This copies the assets into the right folder.

Now I can edit my HTML and see the change as soon as I reload my browser, just like the older Ripple. As I said, there is probably an easier way to do this with Grunt, but I enjoyed finally getting a chance to play with it.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by colin posted on 11/8/2013 at 10:47 AM

I use it with parse.com too. it's espicially helpful to copy the keys around. I use --target=debug and --target=release to propagate the correct keys for the correct parse app. I also use it to deploy my cloud code: grunt --target=debug cloud.

grunt really is a great tool! Thanks for sharing once again!

Comment 2 by Mayur Panchal posted on 11/8/2013 at 12:48 PM

Hello
I am familier with Phonegap till 2.x
but after new version i m little confuse.
can u guide me how create new app and install plugin in phonegap 3.x

Comment 3 by Raymond Camden posted on 11/8/2013 at 4:21 PM

Mayur - I wrote multiple posts specifically for PhoneGap 3. Please search my blog for "phonegap 3".

Comment 4 by Logan Koester posted on 11/10/2013 at 2:07 AM

Why not use the grunt-phonegap plugin, while you're at it? https://github.com/logankoe...

Comment 5 by Raymond Camden posted on 11/10/2013 at 2:19 AM

I wasn't aware of it, Logan. Thanks for sharing it.

Comment 6 by Logan Koester posted on 11/10/2013 at 2:20 AM

No problem. Enjoy!

Comment 7 by Adam posted on 11/12/2013 at 10:54 PM

Thanks for this! I had some trouble using the grunt-phonegap plugin, but this seems much more flexible.

Comment 8 by Logan Koester posted on 11/13/2013 at 11:05 AM

Hey Adam,

If you want to open a ticket at https://github.com/logankoe... I'd be happy to help you figure it out.

- ldk

Comment 9 by Ethan posted on 11/20/2013 at 2:42 PM

Hi Raymond

I knew phonegap came from cordova, but how to do cordova prepare with phonegap 3.x? It seems it only has build command but prepare.

Comment 10 by Raymond Camden posted on 11/21/2013 at 2:29 AM

There is no "prepare" statement for the PhoneGap CLI. If you want to do something similar, "phonegap local build" should do the same thing (but obviously build it as well).

Comment 11 by Sankate Sharma posted on 3/24/2014 at 8:15 AM

Thanks Raymond, this is exactly what I was looking for.

For those like me who are new to Grunt, you do following

Create Gruntfile.js using the contents specified in the blog

1. npm init
2. sudo npm install grunt --save-dev
3. npm install
4. sudo npm install grunt-contrib-watch --save-dev
5. sudo npm install grunt-exec --save-dev

#1 will create a package.json for you, #2 - #5 will update package.json and add dev dependencies
"devDependencies": {
"grunt": "~0.4.4",
"grunt-contrib-watch": "~0.6.1",
"grunt-exec": "~0.4.5"
}

Now you are good to go, just fire up grunt in your shell.

Comment 12 by Ogom Okafor posted on 3/26/2014 at 11:03 AM

Hello Raymond,

Thanks for your post. It inspired this project: http://realog32.github.io/g... (pardon the shameless plug)

Cheers.

Comment 13 by Raymond Camden posted on 3/26/2014 at 2:55 PM

Glad to be an inspiration. :)

Comment 14 by Pete Williamson posted on 6/4/2014 at 3:43 PM

Ah this is so useful, thanks Ray!

You need an updated nickname, you're not just a CFJediMaster, you're some sort of WebMobileAppJediMaster - but that doesn't have the same ring to it

Comment 15 by Raymond Camden posted on 6/4/2014 at 6:34 PM

Heh - I'm a Padawan in the Web/Mobile space still. Give me 5 more years. ;)

Comment 16 by Pete Williamson posted on 6/4/2014 at 10:05 PM

If you're a Padawan, that makes me JarJar binks... roll on 5 years.

On a more technical note, I added more blocks to just build for Android or iOS, useful for speeding up build times when developing:

prepare_android:{
command:"cordova prepare android"
}

Also the stdout and stderr default to true - do you prefer being verbose or was that not the case when you wrote it? Assuming that is grunt-exec you're using.

Comment 17 by Raymond Camden posted on 6/5/2014 at 1:54 AM

I definitely prefer verbose - in any CLI I use pretty much.

Comment 18 by Karan Thakkar posted on 7/10/2014 at 1:38 PM

Is it possible to do something similar within Eclipse using Ant or some kind of a hook that does a _cordova prepare_ everytime your eclipse project builds?

Comment 19 by Raymond Camden posted on 7/10/2014 at 2:56 PM

Um... no idea. I haven't used Ant in a while.

Comment 20 by luca posted on 9/5/2014 at 5:35 PM

myabe there is a error, because when i chanche a file js the watch task don't send the task "exec:prepare"!!!!!!

Comment 21 by luca posted on 9/5/2014 at 6:15 PM

no it's correct.sorry