Minimizing Angular Minification Anger
As a coder and developer I know that the prospect of unforeseen consequences is always there. It is very difficult to learn and be aware of all the ins and outs of any language. With using Ruby on Rails we have a melting pot of languages from Ruby, HTML, CSS, and JavaScript to preprocessors like SCSS and Coffee. This mix is what makes the Rails framework so powerful. We can even run our entire app in three different modes: test, development, and production.
One feature that aims to improve performance has recently caused me some mental anguish: minification. By default Rails includes the Uglifier gem. The Uglifier gem is a wrapper for UglifyJS which compresses and minifies JavaScript. One of the ways that this happens is that variable names are shortened as much as possible. This is a problem for Angular.
Take a look at my one page app, eWorm. When building with Angular, we sometimes pass around objects like $scope
or $stateProvider
and service functions we create like BooksService
or AuthorsService
. UglifyJS sees these as variables whose names can be shortened to save a few bytes. However, changing $stateProvider
to $s
and BooksService
to B
breaks everything and leaves us with errors like the following:
Angular needs to have objects like $stateProvider
stay as is. I discovered this Stack Overflow post by googling my error and knew right away that my strange issues in production that were absent in development were directly tied to minification. Of course I didn’t want to not minify my JS code and hinder performance of my app in production, so I has some work to do.
The first step was to fix my .config()
in my app.js
file. I had to change this:
I used array notation to specify dependencies like so:
In my controllers and services, I opted for setting the $inject
property like so…
We can test how our JS and CSS code holds up to minification in Rails development mode with one line of code. Keep in mind that this will slow down page loads quite a bit due to the minification processing, so you will likely want to turn this off until you need it.
You can read more about $injector
at this Angular docs page.