APK has stopped working after mining, uglify - The code works on: 'ionic serve --lab' and 'ionic run android -l --debug' but not on 'ionic build android'

advertisements

I was following the tutorial to make a production ready ionic app. I wanted to uglify my js. All works great except for 'ionic build android' generates an apk, installing which the app doesn't run. The same code runs with 'ionic serve --lab' and 'ionic run android'. Please help.

Code runs on : ‘ionic serve –lab’ and and 'ionic run android -l --debug’ but not on 'ionic build android’

I added the following code for exception handling, is there a better way to know what run-time exception might cause something like this?

// catch exceptions out of angular
window.onerror = function(message, url, line, col, error) {
  var debug = true;
  var stopPropagation = debug ? false : true;
  var data = {
    type: 'javascript',
    url: window.location.hash,
    localtime: Date.now()
  };
  if (message) {
    data.message = message;
  }
  if (url) {
    data.fileName = url;
  }
  if (line) {
    data.lineNumber = line;
  }
  if (col) {
    data.columnNumber = col;
  }
  if (error) {
    if (error.name) {
      data.name = error.name;
    }
    if (error.stack) {
      data.stack = error.stack;
    }
  }

  if (debug) {
    console.log('exception', data);
    window.alert('Error: ' + data.message);
  } else {
    track('exception', data);
  }
  return stopPropagation;
};

EDIT 1 I got this error on running adb logcat:

E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/css/social-icons.css
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/css/font-awesome.css
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/css/style-chetan.css
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/css/tabSlideBox.css
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/app.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/controllers.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/services.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/openfb.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/ngopenfb.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/collide.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/ionic.tdcards.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/mfb-directive.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/ng-cordova-oauth.min.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/ng-cordova.min.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/facebookConnectPlugin.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/tabSlideBox.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/templates.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/dist/dist_js/app/ng-tags-input.js
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/css/ng-tags-input.bootstrap.css
E/AndroidProtocolHandler( 3622): Unable to open asset URL: file:///android_asset
/www/css/ng-tags-input.css

My apk doesn't have these files, as I have installed npm install gulp-useref --save-dev as mentioned in the tutorial. This builds all css and js to one single file. Also inside the apk in assets/ww now I have only two folders dist_js and dist_css


I followed that tutorial but at some point I gave up as it was mixing too many different different tasks: gulp and node.

My personal opinion is the hooks should be responsible to prepare the folders for the final build.

I came up with this solution which works pretty well but requires some configuration. Having said that even the solution proposed in that article requires some sort of defining folders for different gulp tasks.

First of all you need to install a few package:

npm install jshint --save-dev
npm install async --save-dev
npm install htmlparser2 --save-dev
npm install concat-with-sourcemaps --save-dev
npm install uglify-js --save-dev
npm install clean-css --save-dev
npm install ng-annotate --save-dev
npm install node-useref --save-dev

then you need to copy these hooks in the hooks folder. You should have this after_prepare\010_add_platform_class.js javascript file already.

before_prepare\02_jshint.js must be copied in the folder before_prepare inside hooks. If you don't have that folder, just create it.

after_prepare\011_move_fonts_to_root.js must be copied in the folder after_prepare.

after_prepare\012_concat_files_in_index.js must be copied in the folder after_prepare.

after_prepare\013_unused_folders_delete.js must be copied in the folder after_prepare.

after_prepare\014_uglify.js must be copied in the folder after_prepare.

after_prepare\015_prepare_index_html.js must be copied in the folder after_prepare.

I'll try to explain what all these scripts should do.

02_jshint.js will validated the javascripts in your application.

You can edit that file and change or add other javascripts folders to this array:

var foldersToProcess = [
    'js'
];

I am doing this as I don't have all main application's js files in the same place.

011_move_fonts_to_root.js move all the fonts in a folder called fonts in the root of your app. I have to do this task as at some point I am going to remove all the lib folder, which is a hell of a lot of weight for your app during release.

Again in that file there's an array of folder:

var foldersWithFontsToMove = [
  'lib/ionic/fonts'
];

where you can add other fonts folders you want to move to the root fonts.

012_concat_files_in_index.js parses the html file index.html and finds all the references to the js and css files and concatenate all those files in just 2 documents: app.js and app.css.

These 2 bundles will contain all the js files of your app included the ionic bundles.

NOTE: cordova.js won't be touched cause it's better like this.

Here you can adjust things working with these 4 variables:

var appConcatFolder = 'app';
var appConcatFile = 'app.js';
var cssConcatFolder = 'css';
var cssConcatFile = 'app.css';

appConcatFolder is the folder which will contain the bundle for the js file. appConcatFile is the name of the js bundle. cssConcatFolder is the folder which will contain the bundle for the js file cssConcatFile is the name of the css bundle.

013_unused_folders_delete.js will delete all the unused folders. Since we're moving stuff around there no need to have those folders copied in our final app.

You can configure it adding or removing path to this array:

var foldersToRemove = [
  'lib',
  'js'
];

Since we've moved all the js files in the folder app (in the root) we don't need the js folder any more. We get rid of the lib folder where all the ionic stuff as been put.

014_uglify.js uglifies and minifies the js file and the css bundles.

You can change this file updating this array:

var foldersToProcess = [
    'app',
    'css'
];

This array contains the folders where the css bundle; the other folder is the js bundle folder.

015_prepare_index_html.js will use node-useref to parse our index.html file and replace the scripts and css with our bundles.

To configure this task you have to change your index.html file adding these sections:

<!-- build:css css/app.css -->

<!-- endbuild -->

so your index.html could look like this:

<!-- build:css css/app.css -->
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- endbuild -->

<!-- build:js app/app.js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>

<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
<!-- endbuild -->

if you want to find out more about node-useref you can check here.

Now, with all these scripts in place you should be able to run:

ionic build --release [platform]

or my custom ionic run --runrelease.

You will see lot of things happening as I write in the console quite a lot of info.

At the end of the process you should find this folder structure in your apk:

where you will find your compressed, minified and uglified files and your index.html with the new references.