Motivation
Migration process
New features: Angular
New features: TypeScript
Other updated or deprecated API
Show us the benchmarks!
The biggest pain in the ***
What about the Ivy?
Q&A
Deadline
Security
vulnerabilities
Feeling fresh and clean
Migration
process
Update globally
Configure yarn as the default package manager
yarn global add @angular/cli@9.1.7
# whenever, global config
ng config -g cli.packageManager yarn
# in the root directory of your app, locally
ng config cli.packageManager yarn
It will traverse your code and make changes to compiler's config and update changed APIs.
ng update --force @angular/cli@^9 @angular/core@^9
# install newest dependency of Angular
ng add @angular/localize
angular.json
tsconfig*.json
New features
New features
// tsconfig.json
{
compilerOptions: {
incremental: true,
outDir: "./lib"
},
include: ["./src"]
}
Saves information about the project graph from the last compilation. For the next compilation it will use that information to detect the least costly way to type-check and emit changes to your project.
type Person = {
name: string;
age: number;
location: string;
};
type QuantumPerson = Omit<Person, "location">;
// equivalent to
type QuantumPerson = {
name: string;
age: number;
};
type S = { done: boolean; value: number };
type T = { done: false; value: number } | { done: true; value: number };
declare let source: S;
declare let target: T;
// now it's OK, earlier this would fail
target = source;
interface User {
name: string;
age: number;
location: string;
}
declare function getUserData(): Promise<User>;
declare function displayUser(user: User): void;
async function f() {
displayUser(getUserData());
// ~~~~~~~~~~~~~
// Argument of type 'Promise<User>' is not assignable to parameter of type 'User'.
// ...
// Did you forget to use 'await'?
}
// now works
type Json =
| string
| number
| boolean
| null
| { [property: string]: Json }
| Json[];
// before
if (foo && foo.bar && foo.bar.baz) {
// ...
}
// after
if (foo?.bar?.baz) {
// ...
}
/* also works in case of */
// functions
let phoneNo = this.service.getPhoneNo?.();
// arrays
let firstUser = this.service.users?.[0];
// before
let x = foo !== null && foo !== undefined ? foo : bar();
// after
let x = foo ?? bar();
// What's the difference between `??` and `||`?
// `??` fallbacks when the value is `null` or `undefined`
// `||` fallbacks when the value is falsy
class Person {
#name: string;
constructor(name: string) {
this.#name = name;
}
greet() {
console.log(`Hello, my name is ${this.#name}!`);
}
}
let jeremy = new Person("Jeremy Bearimy");
jeremy.#name;
// ~~~~~
// Property '#name' is not accessible outside class 'Person'
// because it has a private identifier.
Other changed APIs
TesBed.get() for unit tests is marked as deprecated. Change its usage to TestBed.inject().
ng2-webstorage (https://github.com/PillowPillow/ng2-webstorage) - seems unmaintained and neglected for quite some time. After some consultancy I decided to remove it in favor of using localStorage and sessionStorage object build-in natively in JS.
ngx-progressbar changed API for 5>6 migration. Details: https://github.com/MurhafSousli/ngx-progressbar/wiki/Migration-from-v5-to-v6
ngx-permissions changed API for 6>7 migration. Details: https://www.npmjs.com/package/ngx-permissions. Especially concerns usage of NgxPermissionsOnly directive.
The biggest pain...
+327%
+261%
+152%
+86%
// styles.scss
// before
@import "~bootstrap/scss/bootstrap";
// after
@import "~bootstrap/scss/bootstrap-grid";
@import "~bootstrap/scss/bootstrap-reboot";
@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/badge";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/breadcrumb";
@import "~bootstrap/scss/list-group";
@import "~bootstrap/scss/card";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/alert";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/type";
@import "~bootstrap/scss/utilities/position";
@import "~bootstrap/scss/utilities/background";
@import "~bootstrap/scss/utilities/text";
@import "~bootstrap/scss/utilities/float";
@import "~bootstrap/scss/utilities/spacing";
@import "~bootstrap/scss/utilities/sizing";
// styles.scss
// before
@import "~@progress/kendo-theme-bootstrap/scss/all";
// after
@import "~@progress/kendo-theme-bootstrap/scss/input";
@import "~@progress/kendo-theme-bootstrap/scss/combobox";
@import "~@progress/kendo-theme-bootstrap/scss/grid";
@import "~@progress/kendo-theme-bootstrap/scss/menu";
@import "~@progress/kendo-theme-bootstrap/scss/datetime";
@import "~@progress/kendo-theme-bootstrap/scss/dropzone";
@import "~@progress/kendo-theme-bootstrap/scss/slider";
@import "~@progress/kendo-theme-bootstrap/scss/calendar";
@import "~@progress/kendo-theme-bootstrap/scss/upload";
@import "~@progress/kendo-theme-bootstrap/scss/tabstrip";
@import "~@progress/kendo-theme-bootstrap/scss/panelbar";
@import "~@progress/kendo-theme-bootstrap/scss/splitter";
Show us the benchmarks!
+152%
+86%
-33%
-16%
-39%
+32%
-7%
+85%
+25%
-38%
-28%
-54%
+327%
+261%
+30%
-10%
+123%
+67%
-22%
-31%
What about Ivy?
Angular team itself also encourages to do so for any Angular libraries that are developed. It is due to compatibility reasons (source: https://angular.io/guide/ivy#ivy-and-libraries).
Angular team provided the new ngcc (Angular Compatibility Compiler) to pre-compile all Angular libraries to be compatible with Ivy.
Ivy will add potentially more unpredictable behaviors to your application, that can be unique to your project and may take time to fix it. I think it's better to do this migration iteratively - changing the Angular version itself comes with many changes as it is.
You can enable Ivy for your app individually by setting "enableIvy" : true. Also open the package.json and add new script: "postinstall": "ngcc".