How to manage bower overweight?

I am wondering how you guys manage all the bower rubbish that comes from packages. I have installed like 6 dependencies and as you know i only need one file but i get around 10 or 15. This is bad for the weight of the app.

How do you keep only the things you need and still use bower?

Thanks

1 Like

The default Ionic location for bower packages is inside of the www/lib directory, but you can change this. Then you would need to have a build job that can combine the files and drop them into your www directory somewhere.

I agree, its bloat that shouldn’t be bundled in the app. I’d recommend using a gulp or grunt build to help with this.

3 Likes

Thanks that seems reasonable. I will do that and share here the result.
Don’t you think this should be the default behaviour?

1 Like

I think the default project needs some flexibility, but I appreciate the difficulty in changing the default setup for the projects. The current structure is great for getting up and running without having to have a build job, which I think is a reasonable default as well.

I’ve been working on a revised starter project that I hope to share soon. It will include a lot of steps such as a build job for this purpose, asset optimization, translation and localization support, and more.

This topic is exactly waht I was looking for, and I believe this should get much more attention. If you read some comments of apps on play store you can notice that a lot of applications at some point receive comments like “Why do I have to install 10mb application for something simple like this?”.

I have just installed localforage and library of 80kb added more than 300kb to the apk file. Thats not good at all. Not to mention that I still have to add angular-localforage plus whatever other libraries I need.

I think there should definitely be something built right into ionic build command that exclude files that are not needed. I think this could bring the simple app currently of 2mb down to maybe even less than 1mb

Just for information, I changed the bower installation folder and created simple grunt task to copy the resources, my apk went from 2.8mb to 1.04mb

The only problem is that I have to manually add what I want to copy into grunt task which is pain, but well worth it.

How to do this:

  • Change your bower install folder by opening .bowerrc and changing:

    {
    “directory”: “lib”
    }

  • Install grunt (from console):

    npm install -g grunt grunt-cli
    npm install --save-dev grunt grunt-contrib-copy

  • Create Gruntfile.js in root of the ionic project and paste:

      module.exports = function(grunt) {
    
      grunt.loadNpmTasks('grunt-contrib-copy');
    
      // Project configuration.
      grunt.initConfig({
          pkg: grunt.file.readJSON('package.json'),
          default: {},
          copy: {
              libs: {
                  files: [
                      // Ionic
                      {expand:true, src:['lib/ionic/js/ionic.bundle.min.js'], dest: 'www'},
                      {expand:true, src:['lib/ionic/fonts/**'], dest: 'www'},
                      {expand:true, src:['lib/ionic/css/ionic.min.css'], dest: 'www'},
    
                      // Other bower libs
                      {expand:true, src:['lib/localforage/dist/localforage.min.js'], dest: 'www'}, // localforage
                      {expand:true, src:['lib/angular-localforage/dist/angular-localForage.min.js'], dest: 'www'} // angular-localforage
                  ]
              }
          }
      });
      };
    
  • Make sure all references in index are correct

Downsides:

  • Every time you install new library you need to manually add it to the copy job in grunt.
  • You have to remember to run the grunt job
1 Like

Great thanks for sharing your workaround

There is a great grunt plugin I use called wiredep.

During your grunt build process, it will look at your bower.json file and automatically inject the script tags and even css for all your bower packages.

Then you add grunt-concat plugin ( https://github.com/gruntjs/grunt-contrib-concat ) and it will take all the script tags and concat it into one file and copy to your www folder.

I found this simple npm package called bower-installer
This extracts only main files mentioned in the bower.json of a repo and puts it onto the provided path

I changed my .bowerrc to not install bower packages in lib and updated bower.json as follows:

"install":{
 "path":"www/lib"
 }

Now simply run bower-installer -p in the current directory
If you intend to use ionic css and js directly then its a great option

But Since I am using sass setup and hooking third party libraries with my ionic sass build the install key can be a little complex

"install": {
"base": "www/lib",
"path": {
  "scss": "{name}/scss",
  "css": "{name}/css",
  "js": "{name}/js",
  "eot": "{name}/fonts",
  "otf": "{name}/fonts",
  "ttf": "{name}/fonts",
  "woff": "{name}/fonts",
  "woff2": "{name}/fonts",
  "svg": "{name}/fonts"
},
"sources": {
  "ionic": [
    "bower_components/ionic/js/ionic.bundle.js",
    "bower_components/ionic/scss/**",
    "bower_components/ionic/fonts/**"
  ],
  "font-awsome": [
    "bower_components/font-awsome/scss/**",
    "bower_components/font-awsome/fonts/**"
  ],
  "angular-timeline": "bower_components/angular-timeline/dist/*.*"
}

Pros:

  1. Very easy to use
  2. Fairly configurable

Cons:

  1. Doesn’t handle complex cases
  2. Limited flexibility
1 Like

To remove the cruft from libraries installed via bower I use ‘preen’, see https://github.com/braddenver/preen and documentation in readme.
Add the line "preen": "1.2.0", to your depencies in package.json and run npm install.
Modify your bower.json file and specify which files you want to keep, e.g. :

"preen": {
  "angular-cache": [
    "dist/angular-cache.min.js"
  ],
  "angular-google-maps": [
    "dist/angular-google-maps.min.js"
  ],
  "angular-moment": [
    "angular-moment.min.js"
  ],
  "angular-uuid4": [
    "angular-uuid4.min.js"
  ],
  "i18next": [
    "i18next.min.js"
  ],
  "lodash": [
    "lodash.min.js"
  ],
  "moment": [
    "min/moment-with-locales.min.js"
  ],
  "ng-i18next": [
    "dist/ng-i18next.min.js"
  ],
  "ngCordova": [
    "dist/ng-cordova.min.js"
  ],
  "underscore": [
    "underscore-min.js"
  ]
},

Add a gulp task to your gulpfile.js. Include the dependency
var preen = require('preen');

and specify the task

gulp.task('preen', function(cb) {
    preen.preen({}, cb);
});

From the command line run gulp preen
That’s it, all cruft is gone!

2 Likes

What is the benefit of preen versus using bower.json overrides section?

{
  "overrides": {
      "angular-cache": {
         "main": [
            "dist/angular-cache.min.js"
         ]
      }
  }
}
1 Like

Hi @gmarziou, I ran into preen as it was mentioned on bower’s tool section at http://bower.io/docs/tools/#gulp. I’m not (yet) familiar with bower overrides section in bower.json (thank you for mentioning it). What I like about preen is the ability to run it from the command line or gulp task to clean cruft after I’ve installed a component with bower and found out I only needed a specific file. Do overrides allow you to do that, or should I know beforehand what files I want to override and create a section for them in my bower.json?

Off topic: I like the name ‘preen’ and how it relates to bower’s bird icon. I’m not a native speaker so looked it up: to preen = to smooth or clean (feathers) with the beak.

Hi @tomkuipers,

There’s a gulp task main-bower-files which iterates the ‘main’ property of each of your dependencies (and their dependencies) to build a list of mandatory files.

This list can then be used to copy only what’s needed from bower_components folder to www/lib, to concatenate them, minify them or whatever.

Bower.json ‘overrides’ property allows you to amend the ‘main’ of some of your bower dependencies in case they include too many files.

Hi @gmarziou , thanks for the explanation!

I’m a bit confused. My www/lib directory had a size of ~9 MB and after I removed all files that I didn’t need, its size shrunk to ~1 MB. So I expected that the APK file to shrink accordingly, however it only shrunk by about 1 MB.
Is it because the APK file is compressed, or does Ionic do a clean up of the www/lib directory under the hood anyways?