When you minify your code with a tool like Uglify, the resulting minified file will rename variables. This is a problem for AngualrJS, which uses parameter names to provide injected dependencies. You could use the array notation manually, but no human should ever have to suffer this fate, or you could use ng-annotate with Grunt, and let your helper robots get the job done instead.
What does it mean to be build safe? Let me go ahead and explain it. When we built our app, we created a module named "app," and we added a controller called "Feedback." Inside the "Feedback" controller, we requested three specific dependencies, "$scope", "$http", and "$log".
Because of the way "$scope" is spelled, Angular knows where that dependency is and knows how to inject it, and because we spelled "$http" with a dollar in front of it, Angular knows what that dependency is and can inject it, and same with log.
If we were to change "$http", if we were to remove something or change it to something besides "$http", Angular wouldn't know how to inject it anymore. It's important that our parameter names don't get changed.
When we uglified our code, this is what it looks like now. We have our Angular module "app" with our controller "Feedback," but it renamed our parameters for the sake of minification. It took our "$scope" and called it "a", our "$http" and called it "b", and our "$log" and called it "c".
Angular is now in a busted state because it doesn't know hot inject "a", "b", or "c" because they were never declared. There's two ways to fix this, by manually protecting against this kind of build problem or by using ng-annotate. Let me show you how you would do it manually so we can appreciate the benefits we're getting from ng-annotate.
In order to build-safe our code, we can use what's called an array syntax. We wrap our controller function in an array, and then we take our three parameters, we're going to copy them and make them strings at the beginning of our array.
By doing this, we're protecting our build. The uglification process will not change streams. If we look at our app.js, it didn't change the word "Feedback" because that's in a string. Now that we've build-saved our controller by wrapping in this array, it's not going to go ahead and change these either. It'll still change the parameters to "a", "b", and "c", but because we've wrapped it in this array, Angular will now know how to assimilate that.
Let's go ahead and run our grunt build so we can see what it will look like.
Now when we look at our app.js, we can see we still have our "Feedback" controller but it's got this build safety around it, so it says, "For 'a', 'b', and 'c', go ahead and inject '$scope', '$http', and '$log'." This is how you manually build-safe your code.
A lot of people don't like writing it like this. It takes a lot of effort and some people appreciate the simplicity of writing Angular without the array syntax, and that's where ng-annotate comes in handy. We can use it in our grunt file and add it to our build so that our build will automatically add that build safety into each of our Angular components. Let's go ahead and get it set up.
To start, we're going to go ahead and install the ng-annotate plugin for grunt, so we're going to type "npm install grunt-ng-annotate", and we're going to use the "--save-dev" flag so that it saves it for us.
Now that we've got that installed, let's load it into our grunt file, so we will just say "ng-annotate", and now it's here. Now that we've done that, let's go ahead and add it to our init config.
There's a few ways that we can configure ng-annotate. I'm going to add some options so that it doesn't add double quotes, it adds single quotes, because that's my preference.
Now we're going to add a build target for our app. We're going to tell it to look at our specific build files and we're going to have it modify them for us. For the sake of simplicity, I'm going to paste this configuration in.
We're going to need to do one last thing. At the end of our build, I wanted to go ahead, and clean out, and remove that temporary directory, so I added a new clean target called "temp".
Let's add ng-annotate into our build step down below. After we have it clean, let's go ahead and add the ng-annotate, and at the very end we're going to go ahead and have it run our clean temp target, which will clean out the temporary directory.
Now at this point we can go ahead and run "grunt build", and you can see it went through all the steps. It ran ng-annotate on our files, it concatenated all of our files, it uglified them, and then it cleaned out the temp directory. If we come up here and we look at our app.js, you can see that it put in that array syntax for us and we're good to go.
Our code is now build-safe and ready for us to move on to the next step. There are quite a few things left we still need to do. A lot of them revolve around updating the index to HTML, dealing with our templates and our CSS as well. We'll get to those in the next videos.