Angular 2 Dependencies: Features from the Future

Angular 2 is the next version of Google’s popular SPA framework. If you’re not yet familiar with it, you can find an overview here. In this article, I will focus on the dependencies of Angular 2. Whereas AngularJS (1.x) could either be run stand-alone or on top of jQuery, Angular 2 requires some third-party dependencies, which we’ll take a look at in this article:

  1. Node.js and npm
  2. ES6 Shim
  3. ES6 Promise
  4. Metadata Reflection API
  5. zone.js
  6. RxJS

Node.js Package Manager

Note: If you are already familiar with Node.js and npm, you may want to skip this paragraph.

The Node.js Package Manager (or npm for short) is your starting point when creating a new Angular 2 application. In the Node.js world, all applications and libraries are organized in packages. Hence, your new application will be just another package. This however does not mean that it’s automatically being published anywhere.

And finally, packages can reference other packages, which is what we call a dependency. All dependencies are placed in a subdirectory called node_modules.

Before you start, make sure that you have installed an up-to-date version of Node.js. The installation includes npm. In order to begin, create a new directory where you want your app to reside and run npm init in this directory from your command line. This allows you to specify some properties of the newly-created package and eventually creates a file called package.json based on your input. This file also contains the list of dependencies.

Angular 2

Logo of Angular 2 Now let’s continue with installing Angular 2. On your command line, run npm install angular2. npm will now fetch the latest version of Angular 2 and store it as a dependency for your package. The angular2 package already includes a set of external dependencies. But there is more, as Angular 2 requires some peer dependencies (i.e. dependencies that you have to install side-by-side). Starting from npm version 3, peer dependencies are no longer installed automatically. Therefore, you will see the following output:

├── [email protected]
├── UNMET PEER DEPENDENCY [email protected]^0.35.0
├── UNMET PEER DEPENDENCY [email protected]
├── UNMET PEER DEPENDENCY [email protected]
└── UNMET PEER DEPENDENCY [email protected]^0.6.6

Note: At the time of this writing, Beta 12 was the latest version of Angular 2. This could have changed in the meantime.

Those dependencies on the same hierarchical level have to be installed separately: For example, the es6-shim package is required and @^0.35.0 means that we need version 0.35.0 of it (or a later version, because of the circumflex, ^—also referred to as caret dependency). You can achieve this by calling npm i [email protected], where npm i is a short-hand syntax for npm install. Please note that we intentionally omitted the caret dependency here and lock the version to 0.35.0. In the past, there were some unpleasant surprises, as later versions introduced breaking changes. Things you don’t want.

This step has to be repeated for all of the packages noted above. By the way: You can pass more than one argument to npm i, so npm i [email protected] [email protected] will do the trick as well.

Now let’s have a look at the dependencies we have to install explicitly.

ES6 Shim

Logo of JavaScript ECMAScript is the standardized edition of JavaScript managed by TC39 of ECMA International. ECMAScript 2015, also referred to as ES6 or Harmony, is the latest published edition, while its successor ECMAScript 2016 (ES7) is already in the works. Despite its name, ECMAScript 2015 isn’t completely supported by any browser at the time of this writing. Microsoft Edge and Google Chrome already support a majority of the ES6 features. However, especially older browsers don’t understand this language level at all.

Luckily, due to the flexible nature of JavaScript, certain functionality can be back-ported to earlier language versions by using polyfills or other techniques. We call this a shim. ES6 Shim is a collection of such shims which makes legacy JavaScript engines behave like ES6-enabled engines as close as possible.

It’s quite likely that this dependency won’t be required any longer at some point in the future. As soon as your targeted browsers or platforms understand the required language features of ECMAScript 2015, you can drop this dependency.

Please note: Internet Explorer (Angular 2 supports versions 9, 10 and 11) requires an additional set of shims as described here.

ES6 Promise

Note: ES6 Promise is no longer required starting from Beta 12. ES6 Shim contains a shim for Promises as well.

ES6 Shim however doesn’t cover all language features of ES6. ES6 Promise is a polyfill which adds support for ES6-style Promises to legacy JavaScript engines. Promises represent operations that haven’t completed yet, but are expected to do so in the future. Hence, they are often used in combination with deferred or asynchronous operations.

Also this package could be dropped some day when your targeted browsers or platforms include support for ES6 promises.

Metadata Reflection API

As noted above, ECMAScript 2016 (ES7) is the next edition of JavaScript. The Metadata Reflection API is a proposal to add class decorators to ES7 including a reflection API prototype. Decorators are a language feature that we can already use today thanks to TypeScript.

The metadata reflection of Angular 2 heavily relies on this API. Setting up reflection is the very first thing that happens as soon as you call Angular’s bootstrap method.

Thus, the polyfill is included in angular2-polyfills.js, a script which is mandatory for all current browsers and platforms.

zone.js

angular2-polyfills.js also includes a second polyfill, called zone.js. Zones are a language feature of Google’s programming language Dart. Zones represent an execution context for asynchronous operations. This context simplifies the debugging, tracing, testing and mocking of those. Pascal Precht has an excellent article about Understanding Zones, and there’s a nice talk about zones from Brian Ford at ng-conf 2014.

If you have worked with AngularJS (1.x) before, you will have come across $rootScope.$apply. AngularJS can’t track any changes that happen outside of its digest cycle and hence has to be explicitly informed if something has changed outside of Angular’s realm. zone.js hooks into a whole bunch of browser functionalities by monkey-patching them, such as setTimeout, requestAnimationFrame and even attaches to browser events such as geolocation changes. This library therefore knows when asynchronous operations are done or something else could have changed due to a browser event.

Angular 2 relies on this mechanism for dirty checking and thus gets notified about almost anything that can happen in your browser window. In addition, zone.js provides strack traces across so-called async gaps, so you can track where your asynchronous operations originated from. Oh, and by the way, there’s a proposal to add zones to the JavaScript specification.

RxJS

If you ever got in touch with WPF, you might have come across the so called Reactive Extensions, another technology from Microsoft apart from TypeScript. This technology implements the Observer pattern and includes some features known from functional programming. RxJS is the JavaScript version of it.

The so called Observables represent an event stream. In contrast to promises, observables are lazy and are better suited to handle multiple events. Guess what, there’s also a specification of Observables for ES7. Following this specification is one goal of RxJS, which is currently in beta.

Observables are used all over the place in Angular 2, including its Http service, which makes heavy use of them. As a result, RxJS is also a mandatory dependency of Angular 2.

Conclusion

Feature Part of / Proposed for
ES6 language features (Promises, Object.keys, …) ES6
Metadata Reflection API ES7
Observables ES7
Zones post-ES7

As you can see, Angular 2 is built for the future, as it relies on upcoming features of JavaScript and the web. This also means that Angular 2’s blazing performance will even increase as soon as the aforementioned language features are implemented natively.

The Angular 2 logo licensed under the CC BY-SA 3.0 Unported License. The Angular 2 artwork is licensed under the CC BY 4.0 Unported License.

Published by

Christian Liebel

Hey there! I am Christian Liebel from Leimersheim, Germany. I’m working at Thinktecture in Karlsruhe. Angular, cross-platform development using Cordova and Electron, Gulp, .NET and Node.js are our day-to-day business. Feel free to contact me anytime.