Create Multiple Builds for Ionic Mobile Apps Using Gulp

What did I learn today?

Today I learned that it is possible to create multiple builds for Ionic mobile applications using Gulp tasks in Visual Studio. In this post, I’ll explain how I accomplished this task using Gulp and a few Gulp plugins.

This post will explain how to setup multiple builds using Gulp for Ionic mobile apps.  The full example can be found on GitHub: https://github.com/bwhittington/Multi-Build-Gulp-Setup-Example

The Setup

I had a requirement that I needed to be able to create two different versions of the same application but with a different name and a backing store.  Initially, I thought I would need to create find and replace statements in our build server to run through my code and replace every custom variable I setup and replace it with a configuration on the build server.  This seems like a nightmare to me because every time I wish to test each version of the application on my local machine, I’d still have to make the changes manually.

75215926
Terrible Memes are Terrible

 

 

“I needed a way to create builds so that I can test and configure my applications no matter what environment I was using.”

The Fix

I found two Gulp packages that gave me exactly the thing I needed to accomplish my goal.  The first package allows developers to use XPath to find nodes in an XML document and replace their values and attributes with whatever you want.  The second package does basically the same thing in JavaScript files but uses regex or basic string find/replace.

Step One

Update package.json file to include gulp-xml-transformer and gulp-replace.  Reload dependencies to add these to gulp packages to the project.

{
"name": "multi-build-gulp-task",
"version": "1.0.0",
"description": "An example project on creating multiple build configurations using Gulp",
"dependencies": {
"gulp": "^3.9.1",
"gulp-sass": "^3.1.0",
"gulp-concat": "^2.6.1",
"gulp-minify-css": "^1.2.4",
"gulp-rename": "^1.2.2",
"gulp-replace": "0.5.4",
"gulp-xml-transformer": "1.2.0"
},
"devDependencies": {
"bower": "^1.3.3",
"gulp-util": "^2.2.14",
"shelljs": "^0.3.0"
},
"cordovaPlugins": [
"cordova-plugin-device",
"cordova-plugin-console",
"cordova-plugin-whitelist",
"cordova-plugin-statusbar",
"ionic-plugin-keyboard"
],
"cordovaPlatforms": []
}

Step Two

Update the gulpfile.js to include the two new packages to the file.  Then add a gulp task that explains what the task is going to do.  The example below shows the items added in bold.

var gulp = require('gulp');
var gutil = require('gulp-util');
var bower = require('bower');
var concat = require('gulp-concat');
var sass = require('gulp-sass');
var minifyCss = require('gulp-minify-css');
var rename = require('gulp-rename');
var sh = require('shelljs');
var uglify = require('gulp-uglify');
var xmlTransformer = require('gulp-xml-transformer');
var replace = require('gulp-replace');

var paths = { sass: ['./scss/**/*.scss'] };
gulp.task('default', ['sass']);
gulp.task('sass', function(done) { 
	gulp.src('./scss/ionic.app.scss') 
	.pipe(sass()) .on('error', sass.logError) 
	.pipe(gulp.dest('./www/css/')) 
	.pipe(minifyCss({ keepSpecialComments: 0 })) 
	.pipe(rename({ extname: '.min.css' })) 
	.pipe(gulp.dest('./www/css/')) 
	.on('end', done); 
}); 

gulp.task('build-development', function () {

 });

Step Three

Add pipelines to update JavaScript files with build configuration settings.  The key here is that your configuration settings in your JavaScript files have well defined style so you don’t accidentally replace something you need.  I like to use ‘@@’ because that is not something I use everyday.  The code below is just some samples of things I like to setup in my build configuration

gulpfile.js

gulp.task('build-development', function () {
	//Read in all the JavaScript files in the project
	gulp.src('./www/app/**/*.js')
	//Replace the following settings with the appropriate information
      	.pipe(replace('@@GoogleProjectNumber', 'XXXXXXXXXX'))
	.pipe(replace('@@GoogleAnalyticsCode', 'UA-XXXXXXXX-XX'))
	.pipe(replace('@@AppName', 'com.XXX.mobile.XXX'))
      	.pipe(replace('@@ServerName', 'http://www.yourdomain.com/'))
	//Concat all of the script files together
      	.pipe(concat('scripts.js'))
	//Print out the results to use in the application.
      	.pipe(gulp.dest('./www/'));
});

config.js

angular.module('starter', ['ionic'])
.constant('serverName', '@@ServerName')
.constant('googleProjectNumber', '@@GoogleProjectNumber')
.constant('googleAnalyticsCode', '@@GoogleAnalyticsCode');

Step Four

Finally, add XML transform statements to create a new config.xml file with your own settings.  To create this new config.xml file, I like to use a series of base configuration XML files.  In these files, you can setup environment specific settings and you can replace certain settings through code the xml-transformer.

  • config-development.xml
  • config-stage.xml
  • config-production.xml

gulpfile.js

gulp.task('build-development', function () {
	gulp.src('./www/app/**/*.js')
	.pipe(replace('@@GoogleProjectNumber', 'XXXXXXXXXX'))
	.pipe(replace('@@GoogleAnalyticsCode', 'UA-XXXXXXXX-XX'))
	.pipe(replace('@@AppName', 'com.XXX.mobile.dev'))
	.pipe(replace('@@ServerName', 'http://www.your-dev-domain.com/'))
	.pipe(concat('scripts.js'))
	.pipe(gulp.dest('./www/')); 

gulp.src("./config-development.xml") .pipe(xmlTransformer([ 
{ path: '//xmlns:widget', attr: [
    { 'id': 'com.XXX.mobile.dev' }, { 'version': '1.0.0' }] },
{ path: '//xmlns:name', 
    text: 'Multi-Build Gulp Setup Development Build Example' }, 
{ path: '//xmlns:description', 
    text: 'A template project showing how to setup multiple builds using Gulp.' }, 
{ path: '//xmlns:icon[@name="android-icon"]', 
    attr: { 'src': 'resources/android/icon/drawable-xhdpi-icon.png' } }, 
{ path: '//xmlns:icon[@name="ios-icon"]', 
    attr: { 'src': 'resources/ios/icon/icon.png' } }, 
], 'http://www.w3.org/ns/widgets')) 
.pipe(rename('config.xml')) 
.pipe(gulp.dest("./")); 
});

config-development.xml

<?xml version="1.0" encoding="utf-8"?>
<widget id="com.ionicframework.ionicblankapp" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
  <name>ionic-blankapp</name>
  <description>
        An Ionic Framework and Cordova project.
    </description>
  <author email="you@example.com" href="http://example.com.com/">
      Your Name Here
    </author>
  <content src="index.html" />
  <access origin="*" />
  <preference name="webviewbounce" value="false" />
  <preference name="UIWebViewBounce" value="false" />
  <preference name="DisallowOverscroll" value="true" />
  <preference name="android-minSdkVersion" value="16" />
  <preference name="BackupWebStorage" value="none" />
  <feature name="StatusBar">
    <param name="ios-package" onload="true" value="CDVStatusBar" />
  </feature>
  <preference name="KeepRunning" value="True" />
  <preference name="ShowTitle" value="True" />
  <preference name="InAppBrowserStorageEnabled" value="True" />
  <preference name="SuppressesIncrementalRendering" value="True" />
  <preference name="windows-target-version" value="10.0" />
  <plugin name="cordova-plugin-device" spec="~1.1.1" />
  <plugin name="cordova-plugin-console" spec="~1.0.2" />
  <plugin name="cordova-plugin-whitelist" spec="~1.2.1" />
  <plugin name="cordova-plugin-statusbar" spec="~2.1.0" />
  <plugin name="ionic-plugin-keyboard" spec="~1.0.8" />
  <platform name="android">
    <icon src="resources/android/icon/drawable-xhdpi-icon.png" name="android-icon" />
  </platform>
  <platform name="ios">
    <icon src="resources/ios/icon/icon.png" width="57" height="57" name="ios-icon" />
  </platform>
</widget>

Conclusion

Using the above examples, I have been able to create multiple build scenarios for Ionic mobile apps.  I’ve configured different environment builds as well as builds that create different apps using the same code base.  You can find a working template example on GitHub.

75216400

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s