Cordova tooling - API

Experimental API for better development workflows

By Mark Koudritsky - kamrik@google.com / GitHub

PDF

kamrik.org/PlatformProjectSlides

Some pain points of Cordova tooling

  • Difficult to combine with other webdev tools like Sass and CoffeScript
  • Too prescriptive and wastes our time debating how exactly to over-specify Cordova user's environment
  • Not very git friendly (platforms and plugins dirs)

Cordova via the API

  • More flexible
  • Works better with existing web dev workflows

Side note about Gulp

I'll be using Gulp for code examples in this presentation. Since Gulp tasks are just JS functions, it can be trivially translated to pure JS scripts.

Gulp crash course

Gulp logo

  • Gulp is minimal, liberal and simple task runner
  • Gulpfile is a JS file that can contain any code
  • Way less declarative than Grunt
  • Very easy to experiment and prototype with
  • Based on streams but I don't really care


A typical "clean" task in Gulp.

gulp.task('clean', function(cb) {
  del(['./build'], cb);
});
					

Take a loot at gulpjs.com or a presentatioin about Gulp

Cordova OOP API wrapper & Demo App

Evolved from the previous iteration at:
github.com/kamrik/CordovaGulpTemplate

API Wrapper

  • A wrapper around cordova-lib that provides a coherent OOP API
  • Centered around a PlatformProject object that deals with a single platform - represents what traditionally lives under platforms/<platform>/*
  • Is experimental!

Sample App Structure

  • package.json
  • gulpfile.js
  • www/
  • CordovaConfig.xml - Cordova's config.xml file
  • build/ - build artifacts, nuked on every "clean"
    • build/android
    • build/ios
    • ...

package.json



"dependencies": {
    "CordovaPlatformProject": "kamrik/CordovaPlatformProject",

    "cordova-android": "latest",
    "cordova-ios": "latest",
    "cordova-plugin-dialogs": "latest"
    ...
}
						

gulpfile.js - setup


var pp = require('CordovaPlatformProject'); // The API Wrapper

var prjInfo = {
    platform: 'ios',
    paths: {
        root: 'build/ios',
        template: 'node_modules/cordova-ios',
        www: 'www'
    },
    cfg: new pp.cdv.ConfigParser('CordovaConfig.xml');
};
						

gulpfile.js - create & add plugins


gulp.task('create', ['clean'], function() {
    fs.mkdirSync('build');
    var proj = new pp.PlatformProject();

    return prj.init(prjInfo)
    .then(function(){
        return prj.addPluginsFrom('./node_modules');
    }).then(function(){
        return proj.updateConfig(prjInfo.cfg);
    }).then(function(){
        return proj.copyWww(prjInfo.paths.www);
    });
});
					

gulpfile.js - build & run


gulp.task('build', [], function() {
    var prj = new pp.PlatformProject();
    return prj.open(platform, prjInfo.paths.root)
    .then(function() {
        return prj.updateConfig(prjInfo.cfg);
    })
    .then(function() {
        return prj.copyWww(prjInfo.paths.www);
        // Or copy yourself to prj.wwwDir
    })
    .then(function() {
    	// This runs ./build//cordova/run --device
        return prj.run({args: ['--device']});
    });
});

					

Usage


$ git clone https://github.com/kamrik/cordova-api-example.git .
$ npm install
$ gulp create
$ gulp run  # repeat after changing files in www

						

Add / remove a plugin


$ gulp clean
$ npm (un)install --save cordova-plugin-xyz
$ gulp create
						
Note: Peer dependencies not yet added to plugins on npm

Notable points

  • Using ConfigParser from cordova-lib directly. The loaded object can be manipulated in JS to customize workflow
  • Using PluginInfo objects from cordova-lib directly
  • Project hooks are no longer needed
  • Plugin hooks might still be needed

Next Steps

  • Evolve PlatformProject and polish the API
  • Minimize code duplication, though some duplication is unavoidable in this case

Future improvements

  • ConfigParser from App manifest and other files
  • Improved PluginInfo object and plugin handling functionality

Questions?

THE END

github.com/kamrik/cordova-api-example

Exporting as PDF etc.
black theme - PDF - export as PDF (Cmd-P, Chrome only)