How I migrated a dozen of projects to Angular 6 and then 7

In this article, I’ll share with you my experience of upgrading more than a dozen of Anguar 5 projects to Angular 6. These projects were small to medium in size, but they used lots of various Angular features because these are the projects from the second edition of our Angular book. Many of these projects had multiple apps configured in the file .angular-cli.json, and they were automatically migrated into the new project structure as defined in the new configuration file angular.json.

First of all, there’s the site https://update.angular.io that gives you an idea of how to do the upgrade from version X to version Y, and you certainly need to read the instructions there first. But the devil is in the detail, right?

Theoretically, the upgrade should be a 1-2-3 process that consists of the following three steps:

1. npm install @angular/cli@latest –save-dev
Run this command in your project’s dir, to upgrade (and install) the latest Angular CLI version in the devDependencies section of package.json. This command shouldn’t need @latest, but it does.

2. ng update @angular/cli
Run this command to convert the project configuration file .angular-cli.json into angular.json introduced by Angular 6.It also will update testing and tslint config files.

3. ng update @angular/core
Run this command to upgrade all Angular dependencies in the package.json file (except Angular Material and Angular Flex Layout, if used).

What else is needed

On my computer, I had Angular CLI 6 install globally, and my typical project had the line “typescript”: “~2.4.2” in devDependency section of package.json.

Before running and upgrade steps, bump up the TypeScript compiler version in your project or you’ll get an error “@angular/compiler-cli” has an incompatible peer dependency to “typescript” during the step 3. Start any project upgrade with manually changing this dependency to “typescript”: “~2.7.2”. If you still see that error, delete the node_module directory and re-run step 3.

If you use the Angular Material library, run ng update @angular/material to update its dependencies in package.json.

If you use the Flex Layout library, modify its version to 6.0.0-beta15 or later prior to running ng update @angular/core.

Your project’s .angular-cli.json might include the file favicon.ico in the asset’s property that’s not used in your app. Angular 5 would still launch your app even if this file was missing. In Angular 6, you need to explicitly remove all occurrences of favicon.ico in the newly generated angular.json.

After migration, I noticed some strange behavior in the UI rendering, which seems like a bug. In some of my apps, I had the following HTML in the component templates:

<a [routerLink]="['/']">Home</a> 
<a [routerLink]="['/product']">Product</a> 

In Angular 5, it rendered just fine, but after migration to Angular 6, the browser rendered both links without the space between them: HomeProduct. Adding &nbsp; after the first anchor tag helped. I thought it might be related to the Angular compiler’s option preserveWhitespaces, but it didn’t.

Starting from TypeScript 2.7, you may need to take care of the error TS2564: Property ‘SoAndSo’ has no initializer and is not definitely assigned in the constructor. For example, the following class variable declaration won’t compile:

product: Product[];

Either set the TypeScript compiler’s option strictPropertyInitialization to false or explicitly initialize class variables, e.g.

product: Product[] = [];

Upgrading your app to RxJS 6

During the upgrade, I spent the most time updating the code related to breaking changes in RxJS 6.

Your updated package.json will include the dependency “rxjs-compat”: “^6.0.0-rc.0” after step 3. At the time of this writing, the current version of rxjs-compat is 6.1.0, so if you decide to keep rxjs-compat, update its version in package.json and reinstall dependencies. Theoretically, having the rxjs-compat package should allow you to run your app without making any changes in the app code that uses RxJS API. In practice, this may not be the case and the app may fail either during the build- or runtime.

So I decided to remove the rxjs-compat dependency and modify my code to conform to RxJS 6 structure. Remove rxjs-compat from your package.json file to avoid unnecessary increase of your app bundle size. Then run ng serve and fix the RxJS errors (if any) one by one. Then load your app in the browser and keep the browser console wide open so you won’t miss the RxJS-related runtime errors, if any.

The internal structure of RxJS 6 has changed, and you need to change the import statements to get the classes and operators from the proper places. You may start with reading this upgrade guide. Disclaimer: I didn’t follow my own advice and started learning by doing.

In the past, the golden rule was “Don’t import Observable from rxjs, import it from rxjs/observable otherwise the entire RxJS library will be included in your app bundle”. No more. The new golden rule is import { Observable } from “rxjs”; The same applies to Subject, Subscription, interval(), of(), and many other RxJS thingies.

You need to stop using the dot-chainable operators (they simply won’t work without rxjs-compat package). Now you have to use the RxJS pipeable operators, and your imports should look like this:
import { debounceTime, map } from ‘rxjs/operators’;

The ng update command added the rxjs-compat package to your project, and if you’re lucky, your app might run as before without changing the code. But some of my apps gave me build errors, while others crashed at runtime.

For example, in one of my apps, I had this:

import { Observable } from "rxjs";
...
const myObservable$ = Observable.fromEvent(...)

Got the TypeScript error “error TS2339: Property ‘fromEvent’ does not exist on type ‘typeof Observable’.” Here’s the fix:

import { fromEvent } from "rxjs";
...
const myObservable$ = fromEvent(...)

In another app, I had this:

import {Observable} from 'rxjs';
...
return Observable.empty();

It also gave me the error TS2339. This time the fix included replacing the deprecated function empty() with the constant EMPTY:

import {EMPTY} from 'rxjs';
...
return EMPTY;

Another app had this:

numbers$ = Observable.interval(1000)...

This code sneaked through the build phase, but crashed my app during runtime. Here’s the fix:

import {interval} from "rxjs";
numbers$ = interval(1000)...

Don’t bet too heavily on rxjs-compat. This package may help you to quickly get your app running in Angular 6, but until you remove rxjs-compat from your project, don’t report to your boss that migration is done. Find the time and fix the code in your Angular 5 app to conform to RxJS 6. After this is done, migrate your app to Angular 6.

The next one is for those two people who also use RxJS WebSocketSubject. The API has changed in RxJS 6. In the past, you’d do this:

import { WebSocketSubject } from 'rxjs/observable/dom/WebSocketSubject';
...
let myWebSocket = WebSocketSubject.create(wsUrl);
...
myWebSocket.next(JSON.stringify(objectToSend));

To make it work in RxJS 6, I’ve changed it to the following:

import { WebSocketSubject } from 'rxjs/websocket';
...
let myWebSocket = new WebSocketSubject(wsUrl);
...
myWebSocket.next(objectToSend);

And one more thing. If you use Angular Material library, you may run into some breaking changes in the UI components. But overall, conversion of a project to Angular 6 is not a time-consuming process.

P.S. If you use NGRX, don’t forget to upgrade all ngrx packages to version 6 (at the time of this writing, it’s 6.0.0-beta.3).

Update. Yesterday, I’ve upgraded all these projects to Angular 7. In each project I ran just one command that updated dependencies in package.json:

ng update –all

This was easy.

What’s coming in Angular 6+

The release of Angular 6 is around the corner, and in this blog, I’d like to highlight some of its new features announced by the Angular Team.

I started working with Angular when it was in its early alpha versions. Every new Alpha, Beta, and Release Candidate was full of breaking changes, and the announcement of each new release was giving me goosebumps.

After the official release of Angular 2 in September of 2016, the Angular Team started to care about us the developers from the trenches; new major releases come twice a year and switching from one release to another is an easy task. Angular is gaining popularity in the enterprise world leaps and bounds, and the Angular team continues improving this framework. To the best of my knowledge, these are the new and upcoming features:

Angular Elements. While Angular is a great choice for developing Single-Page Applications, creating a widget that can be added to any existing web page was not a simple task. The package called Angular Elements will allow you to create an Angular component and publish it as a Web Component, which can be used in any HTML page. Say there is an existing non-SPA app built using JavaScript and jQuery. The developers of this app will be able to use Web Components built in Angular in the pages of such an app. In our opinion, this killer feature will open many enterprise doors to the Angular framework.

Ivy renderer. This is a code name of a new renderer that will make the size of the app smaller and the compilation faster. The size of the Hello World app is only 3KB gzipped. The Angular Team promises that switching to Ivy rendered will be smooth, and I’ll take my hat off if they’ll be able to make it a non-breaking change.

Bazel and Closure Compiler. Bazel is a build system used for nearly all software built at Google, including their 300+ apps written in Angular. Closure Compiler is the bundling optimizer used to create JavaScript artifacts for nearly all Google web applications. The Closure Compiler consistently generates smaller bundles and does a better job in dead code elimination compared to Webpack and Rollup bundlers. In the upcoming releases of the Angular framework, you’ll be able to use this toolchain for building your apps as well.

Component Dev Kit (CDK). This package is already used by the Angular Material library, which offers 30+ UI components. What if you don’t want to use Angular Material but want to build your own library of UI components and control page layouts? CDK allows you to do this. It also supports Responsive Web Design layouts eliminating the need for using libraries like Flex Layout or learning CSS Grid. CDK was released in December of 2017, but the Angular Team keeps improving it.

Schematics and ng update. Angular CLI generates Angular artifacts using the technology called Schematics. If you decide to create your own templates and have Angular CLI use it, Schematics will help you with this. Staring from Angular CLI 1.7, you can use the ng update that automatically updates your project dependencies and makes automated version fixes. With Schematics, you’ll be able to create your own code transformations like ng update.

I’ looking forward to these features that will make Angular even better, but what else could be improved, that’s not on the roadmap yet? Angular CLI is a great tool, but it has lots and lots of dependencies on the third-party software. Over the last year, several times I’ve experienced broken builds in the latest releases of Angular CLI that were caused by some erroneous release of a third-party package.

The Angular CLI folks are pretty good at releasing patches when errors are reported, but the process of regression testing should be improved, so these errors wouldn’t even sneak in. I stopped using the ^ sign for the version of @angular/clip in package.json. I use the exact version that works for me unless I have a compelling reason for upgrade.

Go Angular!

Always commit your yarn.lock file into the source code repo

I use the Yarn package manager for all my Angular projects. Besides being faster than npm, yarn creates a file yarn.lock that stores the exact versions of installed dependencies. Last year, I wrote about a specific use case that caused a breaking change during one of my Angular workshops.

Yesterday, I had to create a new project using Angular CLI. The project was successfully generated and started with ng serve. Then, I wanted to create a production build with ng build –prod, but the build failed with the error Cannot find module ‘uglifyjs-webpack-plugin’. I know that Webpack uses UglifyJS for optimizing sizes of the bundles, which is great, but my production build fails, which is not great at all.

The generated package.json file located in the root of my project has no direct dependency on uglifyjs-webpack-plugin, but there is one deep inside node_modules in one of the thousand (literally) dependencies used in Angular CLI projects.

To make the long story short, the WebPack team pushed to npmjs.org the new version 1.1.7 this plugin, which was empty. The Angular team got in touch with them, and an hour later, the fixed version 1.1.8 of the Webpack UglifyJS plugin was pushed to the npm central repo.

My project already had the yarn.lock file with an erroneous version of this plugin. I deleted it and ran yarn install again. This time it picked up the fixed 1.1.8 version and the ng build –prod command started working again. Thank you, the Webpack team for the quick turnaround! Happy end!

This was a specific issue with the newly generated project created at the “wrong time”. But imagine a team working on a project for some time, and their github repo didn’t include the yarn.lock file that stored the reference to the working version 1.1.6 of that plugin, and Mary (the QA engineer) decided to make a production build. A minute later, the entire team got an email titled “Who broke the build?”

The bottom line: Push the yarn.lock of the project that works and builds correctly into your version control system to ensure that the entire team has a reproducible and working build. This way, your project won’t depend on someone from across the globe submitting erroneous packages to the npmjs.org.

P.S. While npm 5 also creates the file package-lock.json with the registry of all installed dependencies, it doesn’t guarantee that each npm install will install exact versions of the packages listed there.

Creating an Angular app that weighs only 55KB

With Angular CLI, generating a new app and installing dependencies takes 30 seconds. Creating a production build takes another 15 seconds. And the best part is that the size of the deployed app can be as small as 55KB gzipped. Let’s do it.

1. Generate a minimalistic app with the inline template and styles with the following Angular CLI command:

ng new hello-world --minimal

2. If you’re not creating custom decorators and perform the AoT build, you don’t need to import the reflect polyfill, so comment out the following line in the generated file polyfills.ts:

import 'core-js/es7/reflect';

3. In the generated file app.component.ts remove most of the HTML markup from the component template so it looks as follows:

template: `Welcome to {{title}}!`

4. Make a production build (it performs the AoT compilation by default):

ng build -prod

5. The npm package serve is a small web server that can gzip static files on the fly. Install it globally:

npm install serve -g

6. Change to the dist directory where the application bundles were generated and serve the app (it’ll run on port 5000 by default):

serve .

7. Enjoy the small size!

To see it in action, watch this 5-minute video.

Update. Hello World in the upcoming rendering engine Ivy is only 3.3KB!
See https://ng-ivy-demo.firebaseapp.com/

Offline generation of Angular CLI projects with Yarn

There are situations when an ability to generate new Angular CLI projects from the locally installed packages is quite useful, for example:

  • You’re running a live workshop at a conference in a hotel and the students have to install project dependencies multiple times. When 20-30 people are installing Angular dependencies at the same time on a hotel’s connection, it can take three minutes or more.
  • You’re on a long flight and want to try something new with Angular.

In this post, I’ll show you how to generate Angular CLI projects in a disconnected mode.

First of all, I don’t use npm. I use Yarn for two main reasons:

  1. Yarn is faster than npm (including npm 5).
  2.  Yarn creates a file yarn.lock that keeps track of the exact version of packages installed.

For example, if package.json has a dependency “@angular/core”: “^5.0.0”, running yarn install today would include the version of 5.1.0 of this package. If you want to make sure that all devs in your team use this version even after 5.2.0 is available, push yarn.lock in the source control repo, and everyone who pulls the code will get 5.1.0. Reproducible builds are guaranteed. While npm 5 also creates a file package-lock.json, it doesn’t guarantee the same versions for all developers.

To configure Yarn as a default package manager for Angular CLI, run the following command:

ng set --global packageManager=yarn

Now let’s see how to create a local directory (a.k.a yarn offline mirror) with cached packages so Yarn can use it without the need to connect to the Internet.

Perform the following steps before boarding the plane while the Internet connection is still available.

1. Configure a directory for locally cached packages by running this command:

yarn config set yarn-offline-mirror ~/npm-packages-offline-cache

This will create a file .yarnrc in the user’s directory on your computer. In my case (I use MAC OS), this command creates the file .yarnrc with the following content

# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


lastUpdateCheck 1512857190418
yarn-offline-mirror "/Users/yfain11/npm-packages-offline-cache"

2. Generate a new project with Angular CLI without installing dependencies:

ng new hello-cli --skip-install

3. Copy the file .yarnrc into the newly generated directory hello-cli

4. Change directory to hello-cli:

cd hello-cli

5. Install the project dependencies using Yarn:

yarn install

Important: Make sure that there is no file yarn.lock in hello-cli when you run this command for the first time.

This command not only will install dependencies in the node_modules directory but will also create a directory npm-packages-offline-cache in your user’s directory. This directory will contain about a thousand of compressed package files required for the offline installation. These are gzipped files with extension .tgz. This is your Yarn offline mirror with npm packages.

6. Just in case, clear the existing yarn cache to make sure we’ll be using only the files from the mirror:

yarn cache clean

Now let’s board the plane. Turn off the wi-fi or unplug the network wire. Our aircraft is airborne.

In the hello-cli directory, run the following command:

yarn install --offline

Yarn will install all the dependencies from the offline mirror. Now you can create as many Angular CLI projects as you need without being connected:

1. Generate a new project:

ng new hello-cli2 --skip-install 

2. Copy the file .yarnrc into the hello-cli2 directory

3. Change to the project directory

cd hello-cli2

4. Run the offline installation of the project dependencies

yarn install --offline

Have a safe flight!

P.S. If you’re running a workshop, have a flash drive with the yarn offline miror directory and ask the participants to copy it into their user’s directories. Then they’d just need to run a command to create the .yarnrc file as explained in step 1.

Angular CLI: dev and prod builds with JiT and AoT

I’m happy to announce that my colleague Anton and I started working on the second edition of our Angular book published by Manning. The new TOC is here. The major changes in the second edition are:

– Get rid of any mention of SystemJS – use Angular CLI only
– Replace the chapter on Webpack with the chapter on ngrx
– Add more code samples illustrating various features and techniques

I just finished re-writing the first chapter and would like to offer you a fragment that illustrates the use of Angular CLI for creating dev and prod builds. Your feedback is appreciated.

To make this article more practical, generate a new project Hello CLI using Angular CLi:

ng new hello-cli

Then build the bundles, start the dev server and open the browser on port 4200 by running a single command:

ng serve -o

Now goes the chapter fragment.

Production Builds

The ng serve command bundled the app files but didn’t optimize our Hello CLI application. Open the Network tab in the dev tools of your browser and you’ll see that the browser had to load 2.4MB to render this simple app. In dev mode, the size of the app is not a concern because you run the server locally and it takes the browser only 802 milliseconds to load this 2.4MB of code as shown below.

Now visualize a user with a mobile device browsing the Internet over a regular 3G connection. It’ll take 10 seconds to load the same Hello CLI app. Many people can’t tolerate waiting for 10 seconds for any app except Facebook (30% of the Earth population just lives on Facebook). We need to reduce the size of the bundles before going live.

Applying the -prod option while building the bundles will produce much smaller bundles by optimizing your code, i.e. it’ll rename your variables into single-letter ones, will remove comments and empty lines, and will remove the majority of the unused code. There is another piece of code that can be removed from the app bundles – the Angular compiler. Yes, the ng serve command included such compiler into the vendor.bundle.js. In the next section will talk about production builds and how to remove the Angular compiler from your deployed app.

JiT and AoT Compilations

Take a look at the code of the generated app.component.html.

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!
  </h1>
  <img width="300" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAw...">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
  <li>
    <h2><a target="_blank" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
  </li>
  <li>
    <h2><a target="_blank" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
  </li>
  <li>
    <h2><a target="_blank" href="http://angularjs.blogspot.com/">Angular blog</a></h2>
  </li>
</ul>

For the most part, it consists of standard HTML tags, but there is one line that browsers won’t understand:

Welcome to {{title}}!

These double curly braces represent binding a value into a string in Angular, but this line has to be compiled by the Angular compiler (it’s called ngc) to replace the binding with something that browser would understand. A component template can include another Angular-specific syntax (e.g. structural directive *ngIf and *ngFor) that need to be compiled before asking the browser to render the template.

When you run the ng serve command, the template compilation is performed inside the browser. After the browser loads your app bundles, the Angular compiler (packaged inside vendor.bundle.js)performs the compilation of the templates from main.bundle.js. This is called Just-in-Time (JiT) compilation. This term means that the compilation happens in time of the arrival of the bundles to the browser.

The drawbacks of the JIT compilation are:

1. There is a time gap between the loading bundles and rendering the UI. This time is spent on JiT compilation. On a small app like Hello CLI this time is minimal, but in real world apps, the JiT compilation can take a couple of seconds, so the user needs to wait longer for just seeing your app.

2. The Angular compiler has to be included in the vendor.bundle.js, which adds to the size of your app.

Using the JiT compilation in the prod is discouraged, and we want the templates to be pre-compiled into JavaScript before the bundles are created. This is what Ahead-of-Time (AoT) compilation is about.

The advantages of the AoT compilation are:

1. The browser can render the UI as soon as you app is loaded. There is no need to wait for code compilation.

2. The ngc compiler is not included in the vendor.bundle.js and the resulting size of your app might be smaller.

Why use the word “might” and not “will”? The removing of ngc compiler from the bundles should always result in smaller app size? Not always. The reason being that the compiled templates are larger than those that use a concise Angular syntax. The size of the Hello CLI will definitely be smaller as there is only one line to compile. But in larger apps with lots of views, the compiled templates may increase the size your app so it’s even larger than the JIT-compiled app with ngc included in the bundle. But you should use the AoT mode anyway because the user will see initial landing page of your app sooner.

Creating bundles with the -prod option

When you build the bundles with the -prod option, Angular CLI performs code optimization and AoT compilation. Let’s see it in action by running the following command in our Hello CLI project:

ng serve -prod

Open the app in your browser and check the Network tab as shown in the next image. Now the size of the same app is only 120KB (compare to 2.4MB) and the load time is 573 milliseconds (compare to 802 milliseconds).

What a great result! Google home page weighs more than 200KB. As a matter of fact, the size of the app could be reduced even more after applying the gzip compression to the bundles. Note that the file names of the bundles now include a hash code of each bundle. Angular CLI calculates a new hash code on each prod build to prevent browsers from using the cached version if a new app version is deployed in prod.

Recently released Angular CLI 1.3.0 offers a new option –build-optimizer, which does a better job in eliminating unused code. Even in our simple app it reduced the size of this app to 111Kb. On larger apps the effect of this option can be even bigger. In one of our apps that uses Angular Material it reduced the app size from 290KB to 200KB (lots of dead code there?). The option –build-optimizer works with both ng serve and ng build commands.

ng serve -prod --build-optimizer

Shouldn’t we always use AoT? Ideally, you should unless you use some third-party JavaScript libraries which produce errors during the AoT compilation. If you run into this problem, turn the AoT compilation off by building the bundles with the following command:

ng serve -prod -aot=false

The next screen shot shows that both the size and the load time increased compared to the AoT compiled app.

We were using the ng serve -prod command, which was building the bundles in memory. If you’re ready to generate prod files, use the ng build -prod command instead. We’ll go over the process of building production bundles and deploying the app on the server in chapter 8.

The goal of this section was to get you started with Angular CLI, and we’ll continue its coverage in chapter 2.

Angular CLI: multiple apps in the same project

You may need to have an Angular project that has multiple apps so you can run the build of a particular app, say depending on the customer you’re preparing the build for. In my case, I wanted to create a project with multiple apps that I use in my Angular workshops. Having a single project with multiple apps allows you to run a time-consuming npm or yarn install once and just modify the name of the app you want to run.

For example, you may have multiple versions of the main bootstrap file that load different root modules. The file .angular-cli.json has the apps section with the property main, and to run a particular app, I’d instruct the students to modify .angular-cli.json to point at a particular app, e.g. "main": "main1.ts". To run another app, I’d instruct them to change this line to "main": "main2.ts".

But then I figured out that you can configure multiple apps in the same .angular-cli.json and run the build for a particular app by name. The apps property is an array, and you just need to configure each app there. For example, the following fragment shows how I configured two applications – app1 and app2 in the same .angular-cli.json:

"apps": [
    { "name":"app1",
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main-resolver.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "styles.css",
       "../node_modules/@angular/material/core/theming/prebuilt/indigo-pink.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    },
    { "name":"app2",
      "root": "src",
      "outDir": "dist2",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main-luxury.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "styles.css",
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],

Now to bootstrap the app main-resolver.ts I run the following command:

ng serve --app app1

To bootstrap the main-luxury.ts, I run this:

ng serve --app app2

You can also refer to each app by its index in the apps array:

ng serve --app 0
or
ng serve --app 1

The option –app is available for the ng build command as well. The following screenshot shows my project after I built the app1 into dist and app 2 into dist2.

This is a pretty useful Angular CLI feature and I wanted to share my findings with you.

Update. The angular team is working on the Angular Elements module that will allow you to create Angular widgets that you’ll be able to embed into any HTML app. This should allow you to have multiple apps on the same HTML page as well. This feature should be available in the upcoming Angular 6 releases.
Also, Angular CLI 6 makes it easier to configure multiple apps in the same project in their new configuration file angular.json (a replacement for .angular-cli.json).

Upgrading to the latest Angular CLI

As of the Angular CLI beta 30, the command to install Angular CLI looks as follows:

npm install -g @angular/cli

To get rid of the old version of Angular CLI and install the new one, run the following commands:

npm uninstall -g angular-cli
npm cache clean
npm install -g @angular/cli

To update the existing CLI projects, modify the CLI dev dependency in package.json to this:

"@angular/cli": "1.0.0-beta.32"

Then update the CLI version on top of the angular-cli.json, remove your node_modules dir and run npm install.

My Angular 2 presentations for 2017

In 2017 I’m planning to speak at several conferences related to development of Web applications with the new Angular 2 framework. Below is the list of my presentations (each one is 90-min long). All of them can be delivered as a 2-day workshop in your organization.

Mastering TypeScript

TypeScript is a superset of JavaScript, which allows you to be more productive in writing JavaScript applications. The syntax of this language is pretty easy to pick up for anyone who’s familiar with such object-oriented languages as Java or C#. During this presentation you’ll learn the syntax of this language and will understand the benefits it brings to the table.

Make a facelift to your Angular 2 app with UI libraries

Commercial applications need to be good looking, which means that you should pick up a rich library of UI components for your app. While Angular Material library offers two dozen of great looking components, this may not be enough for your application needs. The good news is that there are other libraries that you can use. In this presentation we’ll start with an overview of Angular Material components. Then we’ll proceed with another open-source library called PrimeNG, which offers more than 70 UI components. Finally, we’ll review the code of an Angular 2 app that uses both Angular Material and PrimeNG components.

Angular 2 for Java developers

Angular 2 is a complete re-write of the super popular Web framework AngularJS. According to Pluralsight survey, Angular leads the list of what developers want to learn in 2016. Angular 2 is a component-based framework that will have an effect in JavaScript community similar to what Spring framework did for Java. This presentation is an overview of this hot framework, which in combination with TypeScript, finally made Web development understandable for Java developers. At the end of the presentation you’ll see a sample Web application written in Angular 2 on the front and Java on the server.

Angular 2: Working with the component router

In this session you’ll see how to use the router that comes with Angular 2 Final. We’ll start with configuring the navigation in a simple app. Then you’ll see how to pass data to routes, work child routes, and create apps with multiple router outlets (auxiliary routes). We’ll also review a unit-test configuration for testing router. Finally, you’ll see how how to lazy load modules using the router.

Angular 2: Communication with the server via HTTP and WebSocket protocols

In this session you’ll see how create an Angular 2 app that can communicate with the servers via a pull (HTTP) and push (WebSocket) modes. We’ll program a simple Node server and then will go through a number of code samples that communicate with it using HTTP and WebSocket protocols. We’ll start with creating a simple NodeJS server, and then will enable it to handle HTTP requests from an Angular 2 app. Then you’ll see how to wrap a service into an observable stream. Finally, we’ll teach our server to perform a data push to an Angular 2 client using the WebSocket protocol.

Implementing inter-component communication in Angular 2

Angular 2 is a component-based framework with a well-defined API for passing data to and getting data from a component. Any application is a tree of components that often need to communicate with each other.
In this presentation you’ll see how to create reusable application components that can exchange data with each other in a loosely-coupled manner. You’ll see how components can communicate via a common parent or via an injectable service. You’ll see how to pass data using component router, input and output parameters, events and callbacks. You’ll also learn how to use projection (formerly known as transclusion) to pass HTML fragments to a component’s template. We’ll also touch upon the incorporation of the third-party JavaScript libraries into an Angular 2 app.

Using Observable Streams in Angular 2

Angular 2 includes RxJS, which is a library of reactive extensions built on the premise that everything is an observable stream.

Observables allow to introduce the push model to your application. First we’ll get familiar with the RxJS library, and then will continue reviewing observables in Angular 2. In this presentation you’ll see how to treat UI events, HTTP, and WebSocket connections as observable streams that push data. You’ll see how to wrap up any service into an observable stream so your application components can subscribe to it.

Angular 2 Tooling

Learning Angular 2 is easier than AngularJS, and developing in TypeScript is more productive than in JavaScript. But setting up the project and deploying the application is not straightforward. This presentation is not about the Angular 2 syntax. We’ll discuss the development process with Angular 2 starting from setting up the project to deploying an optimized application. We’ll start with discussing the Angular/TypeScript project structure and the proceed with such topics as using the module loader SystemJS, installing type definition files, bundling the app with Webpack and deployment in dev and prod. Finally, we’ll go through the process of scaffolding and bundling projects using the Angular CLI tool.

Angular CLI: Speed up installing dependencies with Yarn

Initially, the entry barrier into the world of Angular development was pretty high because of the need to learn and manually configure multiple tools. Even to get started with a simple application, you need to know and use the TypeScript language, the TypeScript compiler, ES6 modules, SystemJS, npm, and a development web server. To work on a real-world project, you also need to learn how to test and bundle your app.

To jumpstart the development process, the Angular team created a tool called Angular CLI (see https://github.com/angular/angular-cli), which is a command-line tool that covers all the stages of the Angular application lifecycle, from scaffolding and generating an initial app to generating boilerplate for your components, modules, services, and so on. The generated code also includes pre-configured files for unit tests and bundling with Webpack.

All this is good but a project generated by Angular CLI has a lot of dependencies that have to be downloaded and installed in the node_modules directory of your project. What’s “a lot”? Let’s use the Unix tree command to see how many files and directories exist in a project freshly generated by Angular CLI. Enter the following command in the root directory of such project:

tree node_modules

You’ll see a nicely formatted tree structure of all packages installed in the node_modules directory ai a summary line at the end, which will look like this:

6233 directories, 38656 files

This is what I mean by a lot. Actually all is relative. It clearly a lot if you compare with the content of node_modules of a jQuery project:

7 directories, 13 files

On the hand, the rumor has it that React Native installs 120K files. The software becomes more complicated every year and we have to deal with it. Anyway, Angular CLI has already created the project with all packages installed. Now, let’s delete the node_module dir in the project and reinstall it with npm install. On my laptop it takes at least 90 seconds. Can this time be improved? Yes, if you’ll use Yarn – an alternative to npm client.

Yarn is a new package manager that can be used instead of npm package manager. The plan is to use npm one last time to install Yarn, and then npm is not needed. Here’s the command to install Yarn globally:

npm install yarn -g

Now let’s run Yarn from within the root dir of our project:

yarn

This command reads (an equivalent of npm install) the list dependencies from your package.json file and installs all of them either from npmjs.org or from local cache. It takes anywhere from about one minute on the first run to install those 38K files. on the consecutive runs (after deleting node_modules) it takes 30 seconds. This is three times faster than npm! Pretty impressive.

To create a new Angular CLI project called sampleProj you can run the following command:

ng new sampleProj

The above command will generate the boilerplate code of the project in the directory sampleProj with package.json and will immediately run npm install there. On my MacBook Pro it takes at least 90 seconds. Now that we are fans of yarn, we’d like to integrate it in the initial project generation. This could be done in three steps:

1. Instruct Angular CLI to not run npm install:
ng new --skip-install sampleProj
2. cd sampleProj
3. yarn

If you use Mac or Unix-based OS, you can combine the above three steps as follows:

ng new --skip-install sampleProj && cd $_ && yarn

The bash parameter $_ refers to the last argument of the previous command, which is sampleProj in our case. Running the above command completes in 30 seconds, which is a lot better than 90, isn’t it?

For a regular non-CLI Angular project Yarn needs about 19 seconds on the first run and 12 seconds or less thereafter. On your computer, the results may be different.

Being more performant is not the only advantage of using Yarn over npm, and you can read more about Yarn’s architecture and benefits in Yarn blog. At the time of this writing, Yarn is still at its early stages, but you can start using it today.

Angular CLI allows you to set Yarn as your default package manager so Angular CLI will use it during generation of new projects:

ng set --global packageManager=yarn

I recorded the video showing how to do this.

UPDATE: In this blog I explain how to use Yarn for the offline project generation.