Twitter: raymondcamden


Address: Lafayette, LA, USA

Using Grunt to automatically build your PhoneGap/Cordova projects

11-07-2013 17,164 views Mobile, Development, JavaScript, HTML5 19 Comments

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.

19 Comments

  • colin #
    Commented on 11-07-2013 at 11:47 PM
    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!
  • Mayur Panchal #
    Commented on 11-08-2013 at 1:48 AM
    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
  • Commented on 11-08-2013 at 5:21 AM
    Mayur - I wrote multiple posts specifically for PhoneGap 3. Please search my blog for "phonegap 3".
  • Commented on 11-09-2013 at 3:07 PM
    Why not use the grunt-phonegap plugin, while you're at it? https://github.com/logankoester/grunt-phonegap
  • Commented on 11-09-2013 at 3:19 PM
    I wasn't aware of it, Logan. Thanks for sharing it.
  • Commented on 11-09-2013 at 3:20 PM
    No problem. Enjoy!
  • Commented on 11-12-2013 at 11:54 AM
    Thanks for this! I had some trouble using the grunt-phonegap plugin, but this seems much more flexible.
  • Commented on 11-13-2013 at 12:05 AM
    Hey Adam,

    If you want to open a ticket at https://github.com/logankoester/grunt-phonegap/iss... I'd be happy to help you figure it out.

    - ldk
  • Commented on 11-20-2013 at 3:42 AM
    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.
  • Commented on 11-20-2013 at 3:29 PM
    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).
  • Commented on 03-23-2014 at 11:15 PM
    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.
  • Commented on 03-26-2014 at 2:03 AM
    Hello Raymond,

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

    Cheers.
  • Commented on 03-26-2014 at 5:55 AM
    Glad to be an inspiration. :)
  • Commented on 06-04-2014 at 6:43 AM
    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
  • Commented on 06-04-2014 at 9:34 AM
    Heh - I'm a Padawan in the Web/Mobile space still. Give me 5 more years. ;)
  • Commented on 06-04-2014 at 1: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.
  • Commented on 06-04-2014 at 4:54 PM
    I definitely prefer verbose - in any CLI I use pretty much.
  • Commented on 07-10-2014 at 4:38 AM
    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?
  • Commented on 07-10-2014 at 5:56 AM
    Um... no idea. I haven't used Ant in a while.

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead. Text wrapped in asterisks (*) will be bold and text wrapped in underscores (_) will be italicized.

Leave this field empty