Gaunt Face

Cordova + Web Best Practices

Cordova + Yeoman

New Version of this Guide is Now Available

There is a new version of this guide on my site which takes into account changes in the Cordova-CLI and Yeoman.

Cordova + Web Best Practices v2.0

Those of you who have tried Cordova / PhoneGap, will know that it’s not always easy to manage your web content along side the native platform projects.

Historically, you’ve had to create your own Android, iOS, … projects and then wrangle them to work with Cordova’s libraries. Once you’ve managed that, it’s up to you to decide how you add the web parts of your app to each platform.

This improved after the Cordova team released a command line interface (cordova-cli), which addresses a number of these problems. The new approach to starting a Cordova project is to use the CLI to scaffold out the project structure. This results in everything living under one directory and then gives you a set of simple commands to add support for platforms, start emulators, install on devices and copy content from a www directory into each native platform.

The missing piece to this? A structure and workflow for your web application. This is where Yeoman comes in, you can use a generator to scaffold out a web application and Grunt to run a number of useful tasks, which will implement some of the web’s best practices, without any extra effort.

To get a basic set-up of a new Cordova project with Yeoman, follow these steps.

Install Yeoman

If you haven’t used Yeoman before, then head on over to yeoman.io and step through the “Getting Started” guide, which will get you set up with Yeoman as well as the webapp generator (a.k.a. generator-webapp).

Ultimately you just need to run the following:

npm install yo -g

Cordova Set-Up & Install

Cordova set-up is nice and simple.

Start by installing the cordova-cli:

npm install -g cordova

Create a brand spanking new project with the command:

cordova create <Project Directory> <Package Name> <Project Name>

Example:
cordova create my-project co.uk.gauntface.myproject.cordova "My Project"

Cordova Project Structure

Then add your platforms of choice (in this case Android).

cd my-project
cordova platform add android

You’ll now have a Cordova project ready to go, congrats :)

If you want, you can run an emulator with the following command:

cordova emulate android

Android Emulator Running Cordova App

Set-Up Yeoman

This part of the guide will use Yeoman’s default generator (webapp generator), however the changes needed to get everything to play nicely, should apply to other generators as well.

To keep a clean directory structure within the Cordova project, we’ll want to add a directory at the root of the project for Yeoman.

mkdir yeoman

So we now have merges, platforms, plugins, www & yeoman directories in our project.

Next, lets run through our yeoman generator as normal

cd yeoman
yo webapp

Yeoman WebApp Terminal

Go through all the Yeoman prompts and once this is done, copy the config.xml file from the www directory over to yeoman/app.

[In the long term, I hope the location of the config.xml file will change - I can't see the why it would need to stay in www]

cp ../www/config.xml ./app/config.xml

The next step is to get Yeoman to build into the www directory, so let’s change the dist location:

Before

// configurable paths
var yeomanConfig = {
  app: 'app',
  dist: 'dist'
};

After

// configurable paths
var yeomanConfig = {
  app: 'app',
  dist: '../www'
};

Since dist is now outside of the Yeoman directory, we need to make sure the clean task can clean directories outside of it’s current directory

Before

clean: {
  dist: {
    files: [{
      dot: true,
      src: [
        '.tmp',
        '<%= yeoman.dist %>/*',
        '!<%= yeoman.dist %>/.git*'
      ]
    }]
  },
  server: '.tmp'
},

After

clean: {
  options: {
    force: true
  },

  dist: {
    files: [{
      dot: true,
      src: [
        '.tmp',
        '<%= yeoman.dist %>/*',
        '!<%= yeoman.dist %>/.git*'
      ]
    }]
  },
  server: '.tmp'
},

The final step is to make sure the config.xml file is copied over to the www directory whenever we perform a build, so lets add the xml file extension to the copy task

Before

// Put files not handled in other tasks here
copy: {
  dist: {
    files: [{
      expand: true,
      dot: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>',
      src: [
        '*.{ico,png,txt}',
        '.htaccess',
        'images/{,*/}*.{webp,gif}',
        'styles/fonts/*'
      ]
    }
.......

After

// Put files not handled in other tasks here
copy: {
  dist: {
    files: [{
      expand: true,
      dot: true,
      cwd: '<%= yeoman.app %>',
      dest: '<%= yeoman.dist %>',
      src: [
        '*.{ico,png,txt,xml}',
        '.htaccess',
        'images/{,*/}*.{webp,gif}',
        'styles/fonts/*'
      ]
    }
.......

Now whenever you run grunt build, it’ll go through the build steps and load the appropriate files into the www directory.

Meaning a full project compile cycle is, build with Yeoman, then build with Cordova for the relevant platform.

grunt build && cordova run android

Cordova’s tools will actually add cordova.js to the projects root directory, so when you want to use some of Cordova’s features, you just need to reference cordova.js in your html page.

Yeoman + Cordova App

Fin.

This is by no means a perfect workflow, ideally you’d have a single tool control the entire build process, but this is a huge leap forward from any previous workflows I’ve had while working with Cordova.

Yeoman Loves Cordova

matt

Matt is a Developer Advocate for Chrome @ Google.

Working from, the (occasionally) sunny, city of London, focusing on the mobile web, specifically hybrid apps.