Featured

My upcoming conferences and workshops

In May-June 2018 I’ll be participating in the following events:

1. O’Reilly Fluent conference in San Jose
2. BuzzJS in New York
3. First steps in Angular, online workshop for O’Reilly

Advertisements

Learning TypeScript: Structural vs nominal typing systems

After completing the second edition of the book “Angular Development with TypeScript“, my colleague Anton Moiseev and I started working on yet another book for Manning. This one will be called “Get Programming with TypeScript” and its tentative Table of Contents is available here.

This book will cover the main syntax elements of the TypeScript language, and to make the book more interesting, we’ll also develop a blockchain app.
Meanwhile, I’ll start a series of blogs on the TypeScript-related topics. This one is about TypeScript’s structural type system.

A primitive type has just a name (e.g. number) while a more complex type like an object or class has a name and some structure represented by properties (e.g. a class Customer has properties name and address).

How would you know if two types are the same or not? In some languages (e.g. Java) two types are the same if they have the same names, which represents a nominal type system. In Java, the last wouldn’t compile because the names of the classes are not the same even though they have the same structure:

class Person {
	String name;
}

class Customer {
	String name;
}

Customer cust = new Person();  // compiler's error

But TypeScript and some other languages use the structural type system. In the following code snippet I re-wrote the above code snippet in TypeScript:

class Person {
	name: string;
}

class Customer {
	name: string;
}

const cust: Customer = new Person(); // no errors  

This code doesn’t report any errors because TypeScript uses structural type systems, and since both classes Person and Customer have the same structure, it’s OK to assign an instance of one class to a variable of another.

Moreover, you can use object literals to create objects and assign them to class-typed variables or constants as long as the shape of the object literal is the same. The following code snippet will compile without errors:

class Person {
	name: string;
}

class Customer {
	name: string;
}

const cust: Customer = { name: 'Mary' };   
const pers: Person = { name: 'John' };

Our classes didn’t define any methods, but if both of them would define a method(s) that has the same signature (name, arguments, and the return type) they would also be compatible.

What if the structure of Person and Customer are not exactly the same? Let’s add a property age to the class Person as is the following listing:

class Person {
    name: string;
    age: number;    // 1
}

class Customer {
	name: string;
}

const cust: Customer = new Person(); // still no errors  

1 We’ve added this property

Still no errors! TypeScript sees that Person and Customer have the same shape. We want to use the constant of type Customer (it has the property name) to point at the object of type Person (it also has the property name).

Follows the link https://bit.ly/2MbHvpH and you’ll see this code in TypeScript playground (a REPL to try code snippets in TypeScript and compile them into JavaScript). Click Ctrl-Space after the dot in cust. and you’ll see that only the name property is available even though the class Person has also the property age.

Homework: Can the class Customer have more properties than Person?
In the previous code snippet, the class Person had more properties than Customer and the code compiled without errors. What if the class Customer has more properties than Person? Would the following code compile? Explain your answer.

class Person {
    name: string;
}

class Customer {
    name: string;
    age: number;
}

const cust: Customer = new Person();

How I migrated a dozen of projects to Angular 6

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).

Starting a new book on TypeScript

It’s Saturday morning and it’s raining in New York City. There is not much you can do. Why not start writing a new book? The agreement with the publisher is signed, and my colleague Anton Moiseev kindly agreed to be my co-author again. The book will have a title Get Programming with TypeScript, and its first chapters have to be released in August.

In this blog, I’ll show you the first two pages that I just wrote as well as a table of contents (subject to change). Besides introducing the code samples illustrating the syntax of the language, we’ll be developing a blockchain app using TypeScript in different environments: in Node.js, in the browser without frameworks, with Angular, with React… Meanwhile, the first two pages are ready.

Unit 1. Getting started with TypeScript

This unit starts with presenting the benefits of programming in TypeScript over JavaScript. Then we’ll install the TypeScript compiler and the IDE, and you’ll learn about the process of transforming a TypeScript program into its JavaScript equivalent that can be run in any JavaScript engine. After that, you’ll see how various TypeScript types can be used in a program. In the hands-on section, we’ll introduce you to the blockchain project and will develop a library that will be used in subsequent units.

We’d like to make a clear distinction between the syntax introduced in ECMAScript specification, and the syntax that’s unique to TypeScript. That’s why we recommend you to read the Appendix A first, so you know where ECMAScript ends and TypeScript begins.

Why program in TypeScript

TypeScript is a compile-to-JavaScript language. It’s also a superset JavaScript, which means that you can take any JavaScript file, e.g. myProgram.js, change its name extension from .js to .ts, and the file myProgram.ts becomes a valid TypeScript program without changing a single line of code.

The word superset means that it contains something additional compared to the set. The main addition to the JavaScript is static types. You can declare a variable of a certain type, and any attempt to assign a value of a different type to it results in a compilation error. This is not the case in JavaScript, where you can change the type of a variable anytime you want during runtime.

But web browsers don’t support TypeScript and this won’t change in the foreseeable future. The program written in TypeScript has to be transpiled into JavaScript first, and then it can be executed in the browser or a standalone JavaScript engine.

The difference between transpiling and compiling is that the latter turns the source code of a program into a bytecode or machine code, whereas the former converts the program from one language to another, e.g. from TypeScript to JavaScript.

Then why go through a hassle of writing a program in TypeScript and then transpiling it into JavaScript, if you could write this program in JavaScript in the first place?

In essence, TypeScript is JavaScript with static types. For example, if you declare a variable as a string, trying to assign a numeric value to it will result in the compile-time error.

let customerId: string
customerId = 123;  // compile-time error

In JavaSript, you can’t explicitly assign the type to a variable, and you could write

let customerId = "A15BN";
customerId = 123;  // no errors 

Let’s write a JavaScript function that applies the provided discount to a price. It has two arguments and both must be numbers.

function getFinalPrice(price, discount) {
  return price - price/discount;
}

How do you know that the arguments must be numbers? First of all, you wrote this function and having an exceptional memory, you may just remember all types of all functions arguments. Secondly, you use descriptive names of the arguments that hint their types. Thirdly, you could guess the types by reading the function code.

This is a pretty simple function, which is not always the case. But let’s say someone (not you) would invoke this function by providing a discount as a string, this function would print NaN during the runtime.

console.log(getFinalPrice( 100, 10));    // prints 90
console.log(getFinalPrice( 100, "10%")); // prints NaN

In TypeScript, you could provide the types for the function arguments, so if someone would try to invoke the function with a wrong type of an argument, this error would be caught as you were typing. Let’s see it in action.

The official TypeScript web page is located here. It offers the language documentation and a playground, where you could enter the code snippets in TypeScript, which would be immediately transpiled into JavaScript.

Follow this link https://bit.ly/2IyVNlj, and you’ll see our code snippet in the TypeScript playground, with the squiggly red line under “10%”. If you hover the mouse over the erroneous code, you’ll see a prompt explaining the error as shown below.

This error was caught by the TypeScript static code analyzer as I was typing. Moreover, if you specify the variable types, your IDE would offer the auto-complete feature suggesting you the argument names and types of the getFinalPrice() function.

Isn’t it nice that the errors are caught during the compile time? I think so. The vast majority of the developers with the background in such languages as Java, C++, C# and others take it for granted that the errors are caught during compile time, and they welcome TypeScript.

Having said that, I need to admit that some of the hard-core JavaScript developers say that TypeScript slows them down by requiring to use types, and in JavaScript, they’d be more productive. But the majority of the web developers are not JavaScript ninjas and can appreciate a helping hand offered by TypeScript.

This is all I got so far.

Below is the current version of the Table of Contents.

Unit 1: Getting started with TypeScript
1.1 Why developing in TypeScript
1.2 Installing and using the TypeScript compiler
1.3 Introducing the Visual Studio Code IDE
1.4 Getting familiar with TypeScript syntax
1.4.1 Type annotations and inferred types
1.5. Hands-on: Starting the blockchain project
1.5.1 Introducing the blockchain project
1.5.2 Developing a library that implements a mining algorithm

Unit 2 Classes and interfaces
2.1 Classes
2.1.1 Instance and static methods
2.1.2 Properties and access modifiers public, private, protected
2.1.3 Constructors
2.1.4 Abstract classes
2.2 Interfaces
2.2.1 Declaring custom types with interfaces
2.2.2 Interface as a contract
2.2.3 Declaring types with classes vs interfaces
2.3 Hands-on: Developing browser-based blockchain node with TypeScript
2.3.1 Working with DOM elements
2.3.2 Making AJAX requests
2.3.3 Implementing the blockchain node for

Unit 3 Generics
3.1 Intro to Generics
3.2 Creating custom generics
3.3 Hands-on: Developing Angular client for the browser-based blockchain node
3.3.1 Brief overview of Angular
3.3.2 Creating a new app with Angular CLI
3.3.3 Generating Angular components and services
3.3.4 Implementing the blockchain node in Angular

Unit 4 Tooling
4.1 Improving code quality with TSLint
4.2 Bundling the TypeScript code with Webpack
4.4 Debugging TypeScript in the browser
4.5 Unit testing TypeScript code
4.7 Hands-on: Developing React client for the browser-based blockchain node
4.7.1 Brief overview of React
4.7.2 Transpiling TypeScript with Babel
4.7.3 Creating a React app for the blockchain node

Unit 5 Advanced types
5.1 Unions, intersections, and the type keyword
5.2 Enums
5.3 Mapped types
5.4 Conditional types
5.5. Hands-on: Developing a server for discovering blockchain nodes in the network

Unit 6 Advanced TypeScript features
6.1 Decorators
6.1.1 Creating custom decorators
6.2 Mixins
6.3 Dynamic imports
6.4 Hands-on: Implementing peer-to-peer blockchain nodes communication
6.4.1 Introducing WebRTC
6.4.2 Implementing nodes communication via WebRTC

Appendix A Modern JavaScript
A.1 The keywords let and const
A.2 Functions
A.2.1 Default and optional function parameters
A.2.2 Fat arrow function expressions
A.3 Classes and inheritance
A.4. Asynchronous programming
A.4.1 From callbacks to promises
A.4.2 async and await
A.5 Destructuring
A.6 The Spread operator
A.6.1 Cloning objects with the Spread operator
A.7 The Rest operator
A.8 Iterating data collections

Appendix B Using TypeScript with JavaScript libraries
B.1 Type declaration files
B.1.1 How to create type declaration files
B.2 Using the JavaScript lodash library in TypeScript code

RxJS Essentials: Part 9: Dealing with breaking changes in RxJS 6

This article is a part of my RxJS series, and the previous post is here.

My plan for this morning was to spend 15 min skimming through my RxJS slides and code samples for the upcoming presentation. I did this presentation multiple times, and my code samples published on CodePen just worked. No more.

RxJS 6 was recently released, and my code samples stopped working. I’m not sure if these particular issues were listed somewhere as breaking changes, but I’d like to share my findings with you. I’ve been using the following CDN to get RxJS 6: https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.0.0/rxjs.umd.js.

In the past, you could use the Rx object as in Rx.Observable. No more.

rxjs is the new Rx

For example, my code sample that had Rx.Observable.create() is broken in RxJS 6 complaining that Rx is not defined. The broken code is here.

Say you need to get a hold of the Observable object in RxJS 6. I did it using the JavaScript destructuring syntax:

const { Observable } = rxjs;

Now you can just write Observable.create(). This fixed my broken code sample for Observable.create(), and the working version is here.

The next broken code sample was related to operators. I remember reading that dot-chainable operators shouldn’t be used in RxJS 6. Using pipeable operators is the way to go.

For backward compatibility of your app, you need to add the package rxjs-compat to be able to use dot-chainable operators. After replacing all dot-chainable with pipeable operators, uninstall rxjs-compat.

Here’s the broken code sample that uses dot-chainable operators map and filter.

To fix this code, I used the destructuring syntax again to get the pipeable version of the map and filter operators like this:

const { filter, map } = rxjs.operators;

Basically, I replaced this:

Rx.Observable.from(beers)  
    .filter(beer => beer.price < 8) 
    .map(beer => beer.name + ": $" + beer.price) 
    .subscribe()

with this:

const { from } = rxjs; 
const { filter, map } = rxjs.operators;

from(beers).pipe(
    filter(beer => beer.price < 8), 
    map(beer => beer.name + ": $" + beer.price) 
    )
    .subscribe()

The working version of the code sample that uses pipeable operators map and filter is here.

Disclaimer. These were quick fixes that I came up with. I wouldn’t be surprised if there was a different way to accomplished the same results. If you find one, please let me know. Gotta share, right?

And one more thing. Importing observables like this is not cool anymore:

import {Observable} from "rxjs/observable";

You need to do it like this:

import {Observable} from "rxjs";

For detailed coverage of how to migrate RxJS-related code see this doc.

Angular: When using ngrx is an overkill

State management is one of the most important aspects of any app that has UI. redux is a popular library for maintaining state in the React community. ngrx is a redux-inspired library for maintaining state in Angular apps. But if redux is a rather simple library, ngrx is not so much, and its workflow is illustrated in the diagram below.

In this blog, I’m not going to explain how ngrx works in detail. You can learn it by going through one of the online tutorials, attending our online workshop, or reading the last chapter of our Angular book. I’ll just show you a video comparing two small apps that have the same functionality, but one of them implements state management by using RxJS BehaviorSubject in an Angular service, while the other uses ngrx.

The app that doesn’t use ngrx has about 80 lines of code and its production build size is 268KB. The ngrx version of this app has about 160 lines of code and its production build weighs 315KB.

In short, I do not recommend using ngrx for state management of small and mid-size apps.

Typically, you use a library to write less code, but the current version of ngrx requires you to write more code.

RxJS Essentials: Part 8: Pipeable operators

In this article, we’ll discuss pipeable operators introduced in RxJS 5.5. The previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject
5. The flatMap operator
6. The switchMap operator
7. Handling errors with the catch operator

Pipeable operators are those that can be chained using the pipe() function, whereas dot-chaining operators are chained with the dot as shown in this blog. Let’s discuss the dot-chaining operators first to understand why the pipeable operators were introduced in RxJS.

If you have RxJS installed, the dot-chaining operators can be imported from the directory rxjs/add/operator, for example:

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';

These operators patch the code of the Observable.prototype and become a part of this object. If later on, you decide to remove say filter operator from the code that handles the observable stream but will forget to remove the corresponding import statement, the code that implements filter remains a part of the Observable.prototype. When the bundlers will try to eliminate the unused code (a.k.a. tree shaking), they may decide to keep the code of the filter operator in the Observable even though it’s not being used in the app.

RxJS 5.5 introduced pipeable operators that are pure functions and do not patch the Observable. You can import operators using the ES6 import syntax (e.g. import {map} from ‘rxjs/operators’) and then wrap them into a function pipe() that takes a variable number of parameters, i.e. chainable operators.

The subscriber in the next code snippet will receive the same data as the ones from the first code sample in this blog, but it’s a better version from the tree-shaking perspective because it uses pipeable operators. The next code sample includes the import statement assuming that RxJS is locally installed.

import {map, filter} from 'rxjs/operators'; // 1
...
Rx.Observable.from(beers)
    .pipe(  // 2
         filter(beer => beer.price < 8) ,
         map(beer => ${beer.name}: $${beer.price})
      ) 
    .subscribe( 
        beer => console.log(beer),
        err => console.error(err),
        () => console.log("Streaming is over")
);

1.Importing pipeable operators from rxjs/operators instead of rxjs/add/operator
2. Wrapping pipeable operators into the function pipe()

Now if you’ll remove the line filter from the above code snippet, the tree-shaking module of the bundlers (e.g. Webpack 4) can recognize that the imported function is not used and the code of the filter operator won’t be included in the bundles.

To see it in action in CodePen, follow this link.

NOTE: Since the pipeable operators are standalone functions, to avoid conflicts with the JavaScript catch statement the pipeable version of the catch operator is called catchError.

Debugging observables

The operator do and its pipeable equivalent tap performs a side effect (e.g. log some data) for every value emitted by the source observable, but returns an observable that is identical to the source. In particular, these operators can be used for debugging purposes.

Say, you have a chain of operators and want to see the observable values before and after a certain operator is applied. The tap operator will allow you to log the values:

import { map, tap } from 'rxjs/operators';

myObservable$
  .pipe(
    tap(beer => console.log(`Before: ${beer}`)),
    map(beer => `${beer.name}, ${beer.country}`),
    tap(beer => console.log(`After: ${beer}`))
  )
  .subscribe(...);

In this example, we print the emitted value before and after the map operator is applied. The tap operator doesn’t change the observable data – it just passes it through to the next operator or the method subscribe().

Refactor your code to use exclusively pipeable operators, because starting from RxJS 6, the dot-chaining operators will be supported only if you install a compatibility package.

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!