1. 12
    AngularJS with Webpack - Uglifying your JavaScript
    4m 42s
⚠️ This lesson is retired and might contain outdated information.

AngularJS with Webpack - Uglifying your JavaScript

Kent C. Dodds
InstructorKent C. Dodds
Share this video with your friends

Social Share Links

Send Tweet
Published 9 years ago
Updated 2 years ago

Angular requires some careful consideration when uglifying your code because of how angular's dependency injection system works. See how easy it is to add this consideration to your webpack configuration so you can minify your Angular JavaScript with Webpack.

[00:00] Now we have our application building to our DIS directory where we can send off all of the resulting files of our application. Let's go ahead and run an http-server on that DIS directory just to see what we have here.

[00:13] If we look at our source for this page, we have this "bundle.js." We look at that bundle, and it's this huge file full of comments and white space that we're sending down to the client for no reason at all. We need to minify this JavaScript to make the payload of this JavaScript file as small as possible.

[00:29] Webpack makes this extremely easy, but there are some considerations that you need to take into account when minifying JavaScript in an Angular application. The first thing that we're going to do is when we're inside of this "Production environment," we're going to add a plugin to minify our code.

[00:46] We'll say config.plugins.pushanewwebpack.optimize.uglifyjsplugin. There are some options that you can pass in here, but we'll omit those for now. Now if we run npm run build, this is going to take a second longer. The reason for that is the uglifyjs plugin is uglifying not only our JavaScript but also Angular and any other definities that we have.

[01:14] The result is a minified JavaScript file where, if I go ahead and run our http-server DIS, I refresh this page, everything is working. Then if I look at my bundle.js, it's much smaller. This is optimized for delivery to the web.

[01:32] The problem here, though, is if I were to go into, say, "My app directives" here and if KCD Hello had something that it required -- let's say it requires log and then in here we say "Log.info I have some info" -- now if I run my build again it's going to uglify all this stuff. If you're familiar with this problem, you know exactly what's going to happen. Let's go ahead and serve up our resulting stuff.

[02:08] Everything is broken. If we look at the console here, unknown provider T provider, this is awful. The way that we overcome this is by using "Annotation." Just to make this a little bit easier, we're going to change this back from an arrow function to a regular function.

[02:26] In Angular you need to annotate your functions. You can do that a couple different ways. One way is you could say "Log" and make that array. Angular will know what to inject for you. If you don't do that, when the uglify.js plugin goes through, in our case it changed that to a T to make it as small as possible because in JavaScript the name of the parameter doesn't matter.

[02:52] Only in Angular does the name of the parameter matter. That's using the implicit dependency injection. We need to be explicit about our dependency injection. We'll use the ng-annotate plugin to do that. Webpack has an ng-annotate loader that we're going to be using. Let's npm install as a dev dependency the ng-annotate loader.

[03:17] Then inside of our loaders here in the JavaScript, we're loading it through Babel. Then after that we're going to run it through ng-annotate. Now if we run npm run build if we refresh this -- and we need to run our http-server on the DIS directory -- everything is working.

[03:43] If we look at our bundle, let's see if we can find where this dollar log is located. Here we go, KCD Hello. We have this explicit dependency injection in our function. That's being done by the ng-annotate plugin. In most cases you just need to plug this in, and everything will work.

[04:05] There may be some cases where you need to explicitly say that your function needs to be annotated. If you were to do that in our controller, for example, you'd simply add a comment here that says ng inject, and ng-annotate will say, "Oh, OK. I need to make sure that I annotate this function."

[04:25] That's how you uglify your Angular code using Webpack. In review you simply add the Webpack optimize uglify JS plugin. Then you install the ng-annotate loader and add that to the loaders for your JavaScript files.

Robin Ury
Robin Ury
~ 6 years ago

In a modern setup with Babel6 & WP2 the includes conf for the loader should look like:

  config.module = {
    rules: [{
      test: /\.js$/,
      use: [
        'ng-annotate-loader',
        'babel-loader',
      ],
      exclude: /node_modules/,
    }

Additionally, if using ES6, one must annotate their controller functions– however, this as simple as inserting a single string statement at the top of the function (including class constructors and ui-router resolves) : 'ngInject';

Markdown supported.
Become a member to join the discussionEnroll Today