Migrating to the Cordova CLI

With PhoneGap Build shutting down, many developers are now left trying to find options to continue building their Cordova-based applications. While several new services like Ionic’s Appflow and Monaca Cloud have entered the market as replacements. Their cost might be too much for the independent developer. One of the things that attracted many to use PhoneGap Build was it was included as part of your Creative Cloud subscription. There was even a free version for open-source projects. For those developers who are either resource constrained or want complete control over their build system, they should migrate to using the Cordova CLI and building locally.

There are four general steps we need to take to accomplish this:

  1. Install the Cordova CLI
  2. Install the native build environments
  3. Migrate our existing PhoneGap Build App to use Cordova
  4. Build and Test!

Step 1: Installing the Cordova CLI

The Cordova CLI is a free, open source tool that is actively maintained by many of the former PhoneGap team. It runs on Node.js and is available on NPM. You can learn more about it by visiting their site, https://cordova.apache.org/.

To install the Cordova command-line tool, follow these steps:

1. Download and install Node.js [https://nodejs.org/en/download/]. On installation you should be able to invoke node and npm on your command line.

2. Install the Cordova CLI using npm.

On OS X and Linux use the following command:

$ sudo npm install -g cordova

On OS X and Linux, prefixing the npm command with sudo may be necessary to install this development utility in otherwise restricted directories such as /usr/local/share. If you are using the optional nvm/nave tool or have write access to the install directory, you may be able to omit the sudo prefix. There are more tips available on using npm without sudo, if you desire to do that.

On Windows do the following:

C:\>npm install -g cordova

The -g flag above tells npm to install cordova globally. Otherwise it will be installed in the node_modules subdirectory of the current working directory.

To test the installation, simply run

$ cordova

on the command line with no arguments and it should print help text.

You will probably want to bookmark the Cordova CLI reference page while you are learning the various CLI commands and parameters. This can be found at: https://cordova.apache.org/docs/en/latest/reference/cordova-cli/

Step 2: Install the native build environments

One of the major appeals of PhoneGap Build was not having to install the native build tools for each platform. This was especially true for Android, as it required multiple components to be properly installed. PhoneGap Build also allowed Windows users to compile iOS applications without needing a Macintosh.

Now that you are building locally, your will will need access to a Mac with Xcode installed to create your IPA files. Some options to get around this requirement are to use one of the “Mac in the Cloud” services or instead migrate to one of the PhoneGap Build replacements, or consider deploying your application as Progressive Web App.

Rather than rewrite the instructions outlined by the Apache Cordova team, I will point you to the specific instructions for each platform:

Android Setup

You will be installing the following elements: Java Development Kit (JDK), Gradle, Android Studio and the Android SDKs.

iOS Setup

The iOS installation is basically just installing Xcode on your Macintosh.

Once this is done, we can validate that status of the tools by running a Cordova command to verify the state of them In the command line run the follow:

$ cordova requirements

You will see a report of the status of the various requirements. If something is not installed, you should go back and reinstall it.

Step 3: Migrate your existing PhoneGap Build App

The method I recommend is to migrate your existing PhoneGap Build app is to first start with a new Cordova application. To create a blank Cordova project using the command-line tool, navigate to the directory where you wish to create your project and run

$ cordova create  [ID [NAME ]]

cordova create [ID [NAME [CONFIG]]] [options]

PATH ……………………. Where to create the project
ID ……………………… Reverse-domain-style package name – used in
NAME ……………………. Human readable name

Here is a sample command:

$ cordova create myapp com.mycompany.myteam.myapp MyApp

With the basic application skeleton in place, we need to navigate to the project directory that was just created using the change directory, or CD command:

$ cd myapp

From the project directory, you need to add the platforms for which you want to build your app.

The general command is:

$ cordova platform add

To add the iOS platform

$ cordova platform add ios

To add the Android platform

$ cordova platform add android

These can take a bit to install, so be patient. Although you can install any platform, it does not mean you can compile for that platform.

With all the necessary requirements in place, we can perform our first build by running

$ cordova build

The process will take a bit, but it should generate the artifacts we need.

Since SDKs for Android and iOS come bundled with emulators, we can use them without the additional steps required to deploy them onto an actual device. We can target the emulator by running this command:

$ cordova emulate

The app will be built, the proper emulator launched and the app installed. This can take a bit. You may need to refer to the Cordova documentation to make sure you have the native environment setup correctly and the emulator/simulators configured correctly.

Now that we know we can build and emulate a basic Cordova app, we can move on migrating our actual application. With the platforms installed, let’s take a look at the directory structure that was generated:

config.xml
hooks
node_modules
package-lock.json
package.json
platforms
plugins
www

There are some folders and files that might look familiar, and others that might be new to you. Now we can roll up our sleeves and do the real migration.

In most PhoneGap Build apps, you probably have a single www folder that contains your code, application resources and it’s config.xml file. This is typically the structure that I see:

resources
config.xml
css
img
index.html
js

Go ahead and replace the www folder that was created with the Cordova CLI with the contents of your PhoneGap Build www. Next, we are going to move your resources directory, the one containing your app icons and splash screens and move it to the root directory for the project. The final step will be editing the main config.xml file. By default, the Cordova CLI generates a bare-bones config.xml file, so references to any icons or splash screens are not included.

I recommend following standard directory and file naming structures to reduce possible headaches. In the main config.xml file add the following elements. If you are not targeting that particular platform, feel free to skip it.


<platform name="android">
<allow-intent href="market:*" />
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
<icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
<icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
<icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
<icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
<icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
<splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
<splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
<splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
<splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
<splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
<splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
<splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
<splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
<splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
<splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
<splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
<splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<icon height="57" src="resources/ios/icon/icon.png" width="57" />
<icon height="114" src="resources/ios/icon/icon@2x.png" width="114" />
<icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-small@2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-small@3x.png" width="87" />
<icon height="20" src="resources/ios/icon/icon-20.png" width="20" />
<icon height="40" src="resources/ios/icon/icon-20@2x.png" width="40" />
<icon height="60" src="resources/ios/icon/icon-20@3x.png" width="60" />
<icon height="48" src="resources/ios/icon/icon-24@2x.png" width="48" />
<icon height="55" src="resources/ios/icon/icon-27.5@2x.png" width="55" />
<icon height="29" src="resources/ios/icon/icon-29.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-29@2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-29@3x.png" width="87" />
<icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
<icon height="80" src="resources/ios/icon/icon-40@2x.png" width="80" />
<icon height="120" src="resources/ios/icon/icon-40@3x.png" width="120" />
<icon height="88" src="resources/ios/icon/icon-44@2x.png" width="88" />
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
<icon height="100" src="resources/ios/icon/icon-50@2x.png" width="100" />
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
<icon height="120" src="resources/ios/icon/icon-60@2x.png" width="120" />
<icon height="180" src="resources/ios/icon/icon-60@3x.png" width="180" />
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
<icon height="144" src="resources/ios/icon/icon-72@2x.png" width="144" />
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
<icon height="152" src="resources/ios/icon/icon-76@2x.png" width="152" />
<icon height="167" src="resources/ios/icon/icon-83.5@2x.png" width="167" />
<icon height="172" src="resources/ios/icon/icon-86@2x.png" width="172" />
<icon height="196" src="resources/ios/icon/icon-98@2x.png" width="196" />
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
<splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
<splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
<splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
<splash height="1125" src="resources/ios/splash/Default-Landscape-2436h.png" width="2436" />
<splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
<splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
<splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
<splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
<splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
<splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
<splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
<splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
<splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" />
<splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
</platform>

view raw

config.xml

hosted with ❤ by GitHub

With the icons and splash screens migrated, we can turn our attention to adding any plugins that our PhoneGap Build application uses. The PhoneGap Build system would read the config.xml and use it to install the plugin into the build system. We need to perform this step ourselves. Open the config.xml file that you moved from your original PhoneGap Build folder. Your plugins will be individually listed in elements. The Cordova CLI command to add a plugin is

$ cordova plugin add

For adding the Statusbar plugin it would be:

$ cordova plugin add cordova-plugin-statusbar

If you need to install a specific version of plugin, append the version number after the plugin name. For example, if I wanted to instal the version 2.0.0 of the camera plugin I would use:

$ cordova plugin add cordova-plugin-camera@2.0.0

The final bit of heavy lifting is migrating all the other modifications you may have made to the original config.xml. These are things like app permissions or security settings. Go through the file and copy them into the new config.xml. If you need additional help with an element, see the Cordova documentation.

Once you have migrated the contents of the older config.xml file into the new one, delete the old config.xml from within the www directory. The same is true with the resources directory. Your www directory should only contain your HTML, CSS and JS files

Go ahead and try running the emulate command again

$cordova emulate

It might take longer than the first time, but once it finishes you should see your application running in the emulator!

Next steps…

Now that you have migrated from PhoneGap Build to use the Cordova CLI, there are some additional steps that will still be needed. PhoneGap Build took care of properly signing your applications for development or release. These are steps that you are now going to have to manage and perform. You can read the documentation about signing your applications on the Cordova website.

Good luck in migrating your apps to whatever build solution you use!

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.