What’s new in TypeScript 2.6 ?

 

Version 2.6 of Microsoft’s TypeScript language has been changed to Release Candidate. This new version comes with more rigor in the audit to help developers better detect errors. The language introduces a strict check flag that is introduced by –strictFunctionTypes. The TypeScript language program manager explains that in strict verification any function that does not come from a method has its parameters compared “contravariantly”.

Typically, TypeScript compared the parameters in a “bivariant” way, which brings benefits such as a simpler model for working with arrays. TypeScript 2.6 has found a compromise by increasing the rigor on all types of functions except methods while allowing modeling of use cases such as event handlers and simplified table management.

Microsoft’s JavaScript language, which was five years old on Oct. 1, has gained momentum, so much so that it has been used in the recent rewriting of the Angular JavaScript framework. Version 2.5 of TypeScript was released at the end of August. Another new feature introduced by TypeScript 2.6 is error-killing comments using // @ ts-ignore comments. Microsoft avoided the removal of errors in TypeScript, because in most cases where users requested that they be removed, errors could be resolved by more precise configuration files, or by using an “any” assertion, said Rosenwasser.

He adds that “however, over time, we have seen two motivating examples of migration from JavaScript to TypeScript overcoming type checks that reside in legacy code.” When migrating JavaScript to TypeScript, removing errors can be very useful for developers because they often run into a model that is difficult to model. Rather than spend a lot of time trying to understand the model, developers can now postpone this work and concentrate on their actual work, thanks to the deletion comments that make it possible to ignore errors that do not hinder not the proper functioning of the code.

To override type checks in existing code, some large organizations update project dependencies in tandem. As a result, any code changes that introduce a type verification error will require a fix to avoid breaking the code generation job. According to Rosenwasser, “Even though error detection is useful, the reality is often that the code continues to work and that development teams have limited resources. Microsoft recommends that you use the delete comments sparingly and always provide an explanation to help understanding.

With TypeScript 2.6, model strings tagged in a module are now cached after the initial call. This new feature of TypeScript puts it as close to the latest revisions to the ECMAScript specification that underlies JavaScript. The standalone TypeScript compiler now provides localized messages via NPM when using the –locale flag. The mode –watch, for the emission of modules, has been accelerated.

Support improvements are planned for tools such as Visual Studio and Visual Studo Code with this release. Version 2.6 of the language allows developers to refactor comments in the JSDoc documentation into TypeScript annotations. Organizational changes have been made to the DOM declarations in lib.d.ts. TypeScript 2.6 can be installed via NPM by running the command npm install -g typecript @ rc or via NuGet. It can also be installed via Visual Studio 2017.

Angular 5, what’s new?

After a release in March 2017 of Angular 4, it is already time to welcome Angular 5 pending Angular 6 scheduled for March 2018. For those who do not know, Angular is the name of a tool set to provided by Google that serves to give happiness to javascript application developers. Happiness because the tool is complete, the community is large and it allows us to focus with pleasure on customer issues.

Among all the changes, we invite you to discover the most significant ones.

Build optimization

As of version 5.0.0, production builds created with Angular CLI will apply the default optimization.

The optimization tool included in Angular CLI has two main objectives. The first is to improve the tree shaking (removing parts of the application that are not needed). The second is to remove the Angular decorators that only the compiler needs.

Each of these actions reduces the size of the build and speeds up the startup of applications.

Angular Universal State Transfer API and DOM Support

Small reminder, Angular Universal allows to have a server-side pre-rendering Angular applications, which allows to take into account the search engines that do not manage javascript.

With Angular 5.0.0, it’s easier to share data between the server version and the client version. This eliminates the need for a duplicate HTTP call to retrieve data when the client version regains control.

Improved transpiler

Improvement of the incremental build, which makes it possible to accelerate the rebuilds notably for the production builds and those with AOT (Ahead-of-Time compilation).

Ability to remove the whitespaces, which until then were kept in templates. It is possible to configure it either at the level of the decorator of each component or at the global level via the file tsconfig.json. The default behavior is “true”, but it is envisaged that in the future it will be “false”.

At the component level :

@Component(
{ 
    templateUrl: 'about.component.html', 
    preserveWhitespaces: false 
} 
export class AboutComponent {}

In the tsconfig.json file :

{ 
   "extends": "../tsconfig.json", 
   "compilerOptions": { 
   "outDir": "../out-tsc/app", 
   "baseUrl": "./", 
   "module": "es2015", 
   "types": [] 
   }, 
   "angularCompilerOptions": { "preserveWhitespaces": false }, 
   "exclude": [ "test.ts", "**/*.spec.ts" ] 
}

Replacing the ReflectiveInjector with the StaticInjector

Again, this eliminates even more polyfills, reducing the size of applications for most developers.

Before :

ReflectiveInjector.resolveAndCreate(providers);

After :

Injector.create(providers);

Improved Zone Speed

Zone is faster by default and it is now possible to bypass zone completely for applications that need performance.

To bypass zone, here is the procedure to follow :

platformBrowserDynamic().bootstrapModule(AppModule, {ngZone: 'noop'}).then( ref => {} );

exportAs

We can now give several names to our components and directives, which is very convenient in case of renaming, it avoids breaking the existing code.

This possibility has been used in the case of prefix change of Angular Material.

Exemple :

@Component(
{ 
   moduleId: module.id, 
   selector: 'a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab]', 
   exportAs: 'matButton, matAnchor', . . . 
}

HttpClient

The old @angular/http module is now officially deprecated and replaced by @angular/common/http, the new HttpClient introduced in 4.3. You can probably expect that @angular/http will be removed in Angular 6.0.

HttpClient has been slightly improved with Angular 5.0, as we are now able to directly use object literals as headers or parameters, whereas we had to use the classes HttpHeaders and HttpParams.

Exemple :

const headers = new HttpHeaders().set('Authorization', 'secret');
const params = new HttpParams().set('page', '1');
return this.http.get('/api/users', { headers, params });

simplified into :

const headers = { 'Authorization': 'secret' };
const params = { 'page': '1' };
return this.http.get('/api/users', { headers, params });

Forms

Forms have a tiny but really useful addition to their API: the ability to decide when the validity and value of a field or form is updated. This is something we already had in AngularJS 1.x, but not yet in Angular.

To do so, the FormControl allows to use an options object as the second parameter, to define the synchronous and asynchronous validators, and also the updateOn option. Its value can be:

  • change, it’s the default: the value and validity are updated on every change;
  • blur, the value and validity are then updated only when the field lose the focus;
  • submit, the value and validity are then updated only when the parent form is submitted.

Exemples :

this.passwordCtrl = new FormControl('', {
 validators: Validators.required,
 updateOn: 'blur'
});
<input [(ngModel)]="user.login" [ngModelOptions]="{ updateOn: 'blur' }">
<form [ngFormOptions]="{ updateOn: 'submit' }">

RxJS 5.5

improved import

Before :

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

After :

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

New events for the Router

  • ChildActivationStart
  • ChildActivationEnd

These new events can be used to control the display of a spinner or to measure the performance of a resolver.

Here’s an example of how to start and stop a spinner :

class MyComponent { 
   constructor(public router: Router, spinner: Spinner) { 
      router.events.subscribe(e => { 
         if (e instanceof ChildActivationStart) { 
            spinner.start(e.route); 
         } else if (e instanceof ChildActivationEnd) { 
           spinner.end(e.route); 
         }  
       ); 
     } 
}

I18n

The messages extracted from your application now include the interpolations used in the template.

Before :

<source>
 Welcome to Ponyracer
 <x id="INTERPOLATION"/>
 <x id="INTERPOLATION_1"/>!
</source>

After :

<source>
 Welcome to Ponyracer
 <x id="INTERPOLATION" equiv-text="{{ user.firstName }}"/>
 <x id="INTERPOLATION_1" equiv-text="{{ user.lastName }}"/>!
</source>

A notable change in i18n is that the i18n comments are now deprecated. In Angular 4, you could use:

<!--i18n: @@home.justText -->
 I don't output an element, just text
<!--/i18n-->

Starting with Angular 5, you are encouraged to use an already possible alternative with ng-container:

<ng-container i18n="@@home.justText">
 I don't output an element, just text
</ng-container>

Other breaking changes

Using a different locale than the default one (en-US) now requires to load additional locale data:

import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';

registerLocaleData(localeFr);

All the i18n pipes now take a locale as their last parameter, allowing to dynamically override it:

@Component({
 selector: 'ns-locale',
 template: `
 <p>The locale is {{ locale }}</p>
 <!-- will display 'en-US' -->

<p>{{ 1234.56 | number:'1.0-3':'fr-FR' }}</p>
 <!-- will display '1 234,56' --> 
 `
})
class DefaultLocaleComponentOverridden {
 constructor(@Inject(LOCALE_ID) public locale: string) { }
}

The currency pipe now takes a string as it second parameter, allowing to chose between ‘symbol’ (default), ‘symbol-narrow’ or ‘code’. For example, with canadian dollars:

<p>{{ 10.6 | currency:'CAD' }}</p>
<!-- will display 'CA$10.60' -->

<p>{{ 10.6 | currency:'CAD':'symbol-narrow' }}</p>
<!-- will display '$10.60' -->

<p>{{ 10.6 | currency:'CAD':'code':'.3' }}</p>
<!-- will display 'CAD10.600' -->

if you want to keep the “old” pipes for now, as they have been kept in a new module DeprecatedI18NPipesModule, that you can import if you want to still use them:

@NgModule({
 imports: [CommonModule, DeprecatedI18NPipesModule],
 // ...
})
export class AppModule {

If you have something like this :

platformBrowserDynamic([
 MyCustomProviderA,
 MyCustomProviderB // depends on MyCustomProviderA
]).bootstrapModule(AppModule);

It must now be in 5.0 :

platformBrowserDynamic([
 { provide: MyCustomProviderA, deps: [] },
 { provide: MyCustomProviderB, deps: [MyCustomProviderA] }
]).bootstrapModule(AppModule);

That’s it 🙂

 

How to run unit tests in a VSTS CI build with Angular 5 and PhantomJS Part 1

Setting up Angular 5 project

You chose Angular 5 as FrontEnd framework, and you made a good choice!

As you can see, Angular 5 comes with Angular-CLI 1.5.

Angular-CLI  npm package installs Angular 5 as we said before and also a complete unit tests toolset :

  • Karma
  • Jasmine

Karma is a Javascript test runner, and Jasmine is a behavior-driven development framework for testing JavaScript code.

In this article I won’t describe how they work, but i will describe how to use then in a VSTS CI.

The critical phase we encounter is how unit tests are run: Karma need a browser to run units tests with Jasmine .

With Angular-CLI there is no issue with that because when you launch your tests with :

ng test

Karma launches automatically a browser like this :

Now we want to build a CI in VSTS but, there is no browser! what can we do ?

PhantomJS is here to help us!

PhantomJS is a so called Headless Browser (or headless WebKit scriptable, as they call it themselves). A headless browser is a browser that is just running in the background, that you can only interact with via code or a terminal. This is just what we need, so let’s make our test run on Phantom instead of Chrome.

WOW!

how does it work ?

Let’s install it and set up in our Angular 5 project!

Step 1, install PhantomJS itself and its runner for Karma

npm install phantomjs-prebuilt --save-dev
npm install karma-phantomjs-launcher --save-dev

Step 2, add them by modifying karma.conf.js

Add karma-phantomjs-launcher in plugins array :

plugins: [
 require('karma-jasmine'),
 require('karma-chrome-launcher'),
 require('karma-phantomjs-launcher'), 
 require('karma-jasmine-html-reporter'),
 require('karma-coverage-istanbul-reporter'),
 require('@angular/cli/plugins/karma')
 ],

Step 3, uncomment the big pollyfils block in pollyfils.ts :

import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

import 'intl'
import 'intl/locale-data/jsonp/en'

Step 4, Add a ng test script in package.json :

"scripts": {
 "ng": "ng",
 "start": "ng serve",
 "build": "ng build",
 "test": "ng test",
 "lint": "ng lint",
 "e2e": "ng e2e",
"test-single-headless": "ng test --single-run=true --browsers=PhantomJS --reporters=progress"
 },

We are done for the PhantomJS setting up! 🙂

Let’s take a look on VSTS configuration for CI