Whilst you’re building an application with [Ionic][1], it’s great to have code separated out into separate files with plenty of white space to increase readability. This makes it much easier to work on, but when we’re ready to [submit the application to App Stores][2] we don’t need it to be readable anymore (machines are much better at reading code than we are).

So before you build the final production ready version of your Ionic application, you might want to first minify it. Minifying code is essentially the process of stripping away everything unnecessary: everything is condensed onto a single line, files are concatenated together, variables are renamed to be shorter and so on. There’s two main reasons you might want to do this:

To reduce the file size of your resulting application and increase performance Obfuscate your code so that prying eyes can’t obtain your source code (something which is [quite possible in PhoneGap applications][3])

Ionic has no automated process to do this but it’s relatively simple to set up your own process using [Gulp][4] and [Grunt][5]. A lot of this is based off of [this tutorial][6] by Agustin Haller which was tremendously helpful to me. The only problem I had with it though is that it relies on cordova hooks, and if you’re using [PhoneGap Build][7] to build your application then you won’t be able to use these.

We are going to use a few different tools here, but the overall process we are trying to achieve is:

Convert all .html templates into AngularJS templates in $templateCache ([gulp-angular-templatecache][8]) Prevent dependency injection from breaking when the app is minified ([since variables get renamed][9]) ([gulp-ng-annotate][10]) Concatenate files ([gulp-useref][11]) Minify / Obfuscate the code ([grunt-contrib-uglify][12])

Part of this we will build into Ionic so that the process is executed every time we make a change in the app (whilst ionic serve is running) and the rest we will achieve with a grunt task. In a previous post I discussed [how to use grunt to automatically upload apps to PhoneGap Build][13] and we will be building on that.

**UPDATE: **If you want to use plain old PhoneGap instead of PhoneGap Build make sure you check out [this post][14] as well.

1. Install the dependencies

Before we can get started you will need to install all the Gulp and Grunt tools that we want to use. To do that run the following commands from within your project directory:

npm install gulp-angular-templatecache --save-dev``` npm install gulp-ng-annotate --save-dev``` npm install gulp-useref --save-dev``` npm install grunt-contrib-uglify --save-dev``` npm install grunt-contrib-compress --save-dev``` NOTE: By adding –save-dev onto the end this will add the tool as a dependency in your package.json file ### 2. Modify your Gulp file When you create an Ionic application a file called **gulpfile.js** is automatically created. This handles some automatic tasks like watching your app and building your css files with SASS when necessary. We're going to build a few more tasks on top of that to do the things we want by using **gulp-angular-templatecache**, **gulp-ng-annotate** and **gulp-useref**. To do that we will need to make a few modifications to **gulpfile.js** * Require the three gulp tools we are using at the top of the file: ```javascript var templateCache = require('gulp-angular-templatecache'); var ngAnnotate = require('gulp-ng-annotate'); var useref = require('gulp-useref'); ``` You will also need to modify the paths array so that Gulp knows where you want stuff to happen. * Modify the paths array to reflect the following: ```javascript var paths = { sass: ['./scss/**/*.scss'], templateCache: ['./www/templates/**/*.html'], ng_annotate: ['./www/js/*.js'], useref: ['./www/*.html'] }; ``` You may need to modify these paths depending on the way your application structure is set up, but for a "normal" Ionic setup this should work. * Add three new Gulp tasks to the end of the gulp file: ```javascript gulp.task('templatecache', function(done){ gulp.src('./www/templates/**/*.html') .pipe(templateCache({standalone:true})) .pipe(gulp.dest('./www/js')) .on('end', done); }); gulp.task('ng_annotate', function (done) { gulp.src('./www/js/*.js') .pipe(ngAnnotate({single_quotes: true})) .pipe(gulp.dest('./www/dist/dist_js/app')) .on('end', done); }); gulp.task('useref', function (done) { var assets = useref.assets(); gulp.src('./www/*.html') .pipe(assets) .pipe(assets.restore()) .pipe(useref()) .pipe(gulp.dest('./www/dist')) .on('end', done); }); ``` * Since we want these tasks to run automatically whenever there is a change in the application, we also have to add them to the existing **watch** task: ```javascript gulp.task('watch', function() { gulp.watch(paths.sass, ['sass']); gulp.watch(paths.templatecache, ['templatecache']); gulp.watch(paths.ng_annotate, ['ng_annotate']); gulp.watch(paths.useref, ['useref']); }); ``` * and finally we will also need to add them to the default gulp task: ```javascript gulp.task('default', ['sass', 'templatecache', 'ng_annotate', 'useref']); ``` ### 3. Modify your ionic.project file You will need to add the same tasks we just created to the "**gulpStartupTasks**" option in your **ionic.project** file. The end result should look like this: ```javascript { "name": "MyApp", "app_id": "b4v4v4v4", "gulpStartupTasks": [ "sass", "templatecache", "ng_annotate", "useref", "watch" ], "watchPatterns": [ "www/**/*", "!www/lib/**/*" ] } ``` ### 4. Modify your index.html file There are also a few changes that are required to your **index.html** file. First, you will need to include the **templates.js** file that is created using **gulp-angular-templatecache**. * Add the following to your **index.html** file **before you include your app.js** file: ```javascript * An important change that prevents breaking dependency injection is to add the **ng-strict-di** directive on whatever tag, likely the body tag, you specify your application on: ```javascript <body ng-app="MyApp" ng-strict-di>

Finally, to concatenate the files you are including in index.html you will need to modify them to look like this:

< ! -- build : css dist_css / styles . css -- > < link href = "css/style.css" rel = "stylesheet" > < link href = "css/ionic.app.css" rel = "stylesheet" > < ! -- endbuild -- > < ! -- build : js dist_js / templates . js -- > < script src = "dist/dist_js/app/templates.js" > < / script > < ! -- endbuild -- > < ! -- build : js dist_js / app . min . js -- > < script src = "dist/dist_js/app/app.js" > < / script > < script src = "dist/dist_js/app/controllers.js" > < / script > < script src = "dist/dist_js/app/services.js" > < / script > < ! -- endbuild -- >

This will create a single file called styles.css in the dist_css folder, and a single file called app.min.js in the dist_js folder. If you open up your built index.html file (the one located inside of the dist folder) you will notice that the references are changed to include just the single concatenated file.

5. Modify references to your templates

After using gulp-angular-templatecache we can no longer refer to our templates like this:

$stateProvider . state ( 'intro' , { url : '/' , templateUrl : 'templates/intro.html' , controller : 'IntroCtrl' } ) . state ( 'main' , { url : '/main' , templateUrl : 'templates/main.html' , controller : 'MainCtrl' } ) ;

Instead you will need to modify them so that they only reference the file name, like this:

$stateProvider . state ( 'intro' , { url : '/' , templateUrl : 'intro.html' , controller : 'IntroCtrl' } ) . state ( 'main' , { url : '/main' , templateUrl : 'main.html' , controller : 'MainCtrl' } ) ;

You will also need require the templates **module that is generated in your angular module in **app.js:

angular . module ( 'MyApp' , [ 'ionic' , 'controllers' , 'services' , 'templates' ] )

6. Minify / Uglify the Code

Now we will be using a file in the root of our project called Gruntfile.js to run uglify (which I think makes it sound like I’m casting some Harry Potter spell on my code). For more background on grunt, take a look at [this post][13], as we will be building on top of that. You can also just download the entire file in the bonus content box below.

Add the following to your grunt files initConfig:

uglify : { my_target : { files : { 'www/dist/dist_js/app.min.js' : [ 'www/dist/dist_js/app.min.js' ] } } } ,

This will take the app.min.js file we previously created and create a new minified and uglified app.min.js file. Now you can run the uglify process by running: