Ionic 2 - app.bundle.js - Minification


#1

Hello,

Is there a way we can minify the app.bundle.js ? The current compiler/builder concats all js into one file but doesn’t minify them.

I am basically looking to improve performance a bit :slight_smile: on my ionic 2 app.

Thanks,
Tony


#2

You’ll need to edit the index.js file
node_modules >> ionic-gulp-browserify-typescript

Add the following line to the bundle function at the end of the script.

.pipe(uglify({mangle: false}))

if you also want to minifythe polyfills.js file you can add the same line of code to the index.js file located in
node_modules >> ionic-gulp-scripts-copy

Hope that helps


#3

Hiii,

I tried it but it doesn’t seem to work. I am using typescript, not sure if that matters.

Here’s what I did:

  1. Installed this https://www.npmjs.com/package/gulp-uglify (since ionic2 starter project doesn’t include one.
  2. Added the following line to node_modules => ionic-gulp-browserify-typescript (index.js - bundle function) :
.pipe(uglify({mangle: false}));
function bundle() {
    return b.bundle()
      .on('error', options.onError)
      .pipe(source(options.outputFile))
      .pipe(gulpif(options.browserifyOptions.debug, sourcemapPipe()))
      .pipe(gulp.dest(options.outputPath))
      .pipe(uglify({mangle: false}))
      ;
  }

I am getting the following 2 different errors depending on the browserifyOptions debug if set to true or not:

if set to true

[06:13:56] Error in plugin 'gulp-uglify'
Message:  .../www/build/js/app.bundle.js.map: Unexpected token: punc (:)
Details:    fileName: .../www/build/js/app.bundle.js.map    lineNumber: 1

if set to false

[06:19:34] Error in plugin 'gulp-uglify'
Message:    .../build/js/app.bundle.js: Streaming not supported
Details:
    fileName: .../www/build/js/app.bundle.js

Any idea :slight_smile: ?
Thanks again.


#4

have you tried putting the uglify 1 line up? You uglify the after it’s writting now.


#5

Use Grunt-minifed

Add something like this in your gruntfile:

minified : {
files: {
src: [
’/js/src/**/.js’,
’/js/src/
.js’
],
dest: ‘/js/min/’
},
options : {
sourcemap: true,
allinone: false
}
}


Compress app.bundle.js (typesript)
#6

if I do put it 1 line up, I start getting parse errors.

Caught exception:
 Error
    at new JS_Parse_Error (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:1526:18)
    at js_error (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:1534:11)
    at croak (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2026:9)
    at token_error (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2034:9)
    at unexpected (eval at <anonymous> (../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2040:9)
    at semicolon (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2060:56)
    at simple_statement (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2240:73)
    at eval (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2093:47)
    at eval (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2073:24)
    at block_ (eval at <anonymous> (.../node_modules/gulp-uglify/node_modules/uglify-js/tools/node.js:24:4), <anonymous>:2353:20) 

#7

Heres a copy of my ionic-gulp-scripts-copy index.js file (its the smallest of the two!!)

var gulp = require(‘gulp’),
uglify = require(‘gulp-uglify’);

module.exports = function(options) {
options.src = options.src || ‘node_modules/angular2/bundles/angular2-polyfills.js’;
options.dest = options.dest || ‘www/build/js’;

return gulp.src(options.src)
.pipe(uglify({mangle: false}))
.pipe(gulp.dest(options.dest));
}

gulp-uglify must be included at the top
Then just add it to the pipe statement before the gulp.dest


#8

That works perfectly for angular2-polyfill.js. Thank you.

app.bundle.js is the one I still have a problem with. Do you mind if I get a look at your ionic-gulp-browserify-typescript “index.js” ?

Thanks again.


#9

Maybe log a feature request on ionic cli github page for this? I think this would be something awesome they can maybe build in when a certain flag is passed or something?


#10

There’s already an open issue about it:


#11

Oh that’s pretty cool! Nice.


#12

I hope it gets included as part of ionic serve as well. Thanks for the update @iignatov .

Any suggested workarounds to minify app.bundle.js?


#13

UPDATE: This is no longer needed because it’s now part of the build process for TS and JS.

@tonyawad88 First of all I would recommend you to not modify anything under node_modules (unless you want to apply a temporary fix) because your changes will be lost when you update your packages.

If you want to customize your build process you could use the gulpfile.js file for that purpose.

Disclaimer: I still don’t have any experience with gulp/browserify so this is just a quick example and most probably there’s a much better way to achieve this.

There’s a sample implementation that I made (intentionally works only with the --release parameter):

// gulpfile.js
// ...
var uglify = require('gulp-uglify');
var isRelease = argv.indexOf('--release') > -1;

var minifyScripts = function(path, done) {
  if (isRelease) {
    gulp.src(path + '/*.js')
      .pipe(uglify({ mangle: false }))
      .pipe(gulp.dest(path))
      .on('end', done);
  } else {
    done();
  }
};

// ...

gulp.task('build', ['clean'], function(done){
  runSequence(
    ['sass', 'html', 'fonts', 'scripts'],
    function(){
      //buildBrowserify().on('end', done); // <- replace this line with:
      buildBrowserify().on('end', function(){
        minifyScripts('www/build/js', done);
      });
    }
  );
});

If you haven’t installed gulp-uglify you need to install it too:

npm install --save-dev gulp-uglify

Compress app.bundle.js (typesript)
How to reduce the size of apk?
#14

It looks to me like buildBrowserify has built-in support for uglify…you can activate it by adding minify and uglifyOptions to the buildBrowserify options in gulpfile.js. Note than minification can be rather time-consuming (over 40 secs for me), so it’s probably a bad idea to minify with a watcher / auto-reloader. That would be very frustrating and unneeded for local dev.

    minify: true,
    uglifyOptions: {
      mangle: false
    },
gulp.task('build', ['clean'], function(done){
  runSequence(
    ['sass', 'html', 'fonts', 'scripts'],
    function(){
      buildBrowserify({
        minify: true,
        uglifyOptions: {
          mangle: false
        },  
        browserifyOptions: {
          debug: !isRelease
        }   
      }).on('end', done);
    }   
  );  
});

Compress app.bundle.js (typesript)
#15

@iignatov I tried your solution. It is minifying the app.bundle.js but I am getting the following:

EXCEPTION: No provider for t! (t -> t)
app.bundle.js:19 EXCEPTION: No provider for t! (t -> t)t.logError @ app.bundle.js:19
app.bundle.js:19 EXCEPTION: Error: Uncaught (in promise): No provider for t! (t -> t)

app.bundle.js:19 EXCEPTION: Error: Uncaught (in promise): No provider for t! (t -> t)t.logError @ app.bundle.js:19
app.bundle.js:19 STACKTRACE:t.logError @ app.bundle.js:19
app.bundle.js:19 Error: Uncaught (in promise): No provider for t! (t -> t)
    at l (angular2-polyfills.js:1)
    at angular2-polyfills.js:1
    at e.invokeTask (angular2-polyfills.js:1)
    at Object.inner.inner.fork.onInvokeTask (app.bundle.js:18)
    at e.invokeTask (angular2-polyfills.js:1)
    at e.runTask (angular2-polyfills.js:1)
    at a (angular2-polyfills.js:1)
    at XMLHttpRequest.invoke (angular2-polyfills.js:1)

Do you think it’s cause it’s minifying more than it should ?


#16

Yes, actually it is, you have to add the uglify option mangle: false to fix it, i.e. to change it this way:

  if (isRelease) {
    gulp.src(path + '/*.js')
-     .pipe(uglify())
+     .pipe(uglify({ mangle: false }))
      .pipe(gulp.dest(path))
      .on('end', done);
  } else {
    done();
  }

BUT, wait, this is no longer needed, because now this is part of the build process for TS or JS:

minify (boolean) Whether to minify the bundle using Uglify or not. Default: false.

Thanks for reminding me about this, I updated my answer accordingly.


#17

Yes, it has been added just recently, thanks for the heads up.


#18

I can see it now as part of the latest ionic2 package. Thank you !


#19

hi, i add this to the gulpfile.js but the app.bundle.js is still not uglified, am i miss somethings? thanks.

minify: true,
    uglifyOptions: {
      mangle: false
    },

#20

It works for me. Maybe post your full gulpfile.js?