Перейти к содержанию

Angular Ivy

Angular Ivy представляет собой абсолютно новый компилятор, который пришел на смену View Engine. Разработка Angular Ivy началась задолго до его официального релиза, и начиная с версии 8 он стал доступен в тестовом режиме, а стабильная версия появилась уже в Angular 9.

Обзор

Преимущества Angular Ivy:

  • Более быстрая сборка за счет того, что зависимые компоненты и директивы теперь не включаются в зависящий компонент, вместо этого в зависящем компоненте указываются ссылки на зависимости, Таким образом, при изменении одной из зависимостей нужно перекомпилировать только ее, а не весь использующий ее код;
  • Меньший размер файлов сборки из-за преобразования всех декораторов в статические методы класса и большей подверженности файлов процессу под названием Tree Shaking;
  • Усовершенствованная отладка;
  • Использование динамической загрузки.

Важно

Angular Ivy работает только с AoT-компиляцией и начиная с Angular 9 используется по умолчанию.

Для активации/деактивации Angular Ivy в уже созданном проекте, необходимо в файле tsconfig.app.json изменить значение параметра enableIvy в блоке angularCompilerOptions.

tsconfig.app.json

1
2
3
4
5
{
    "angularCompilerOptions": {
        "enableIvy": true
    }
}

Важно

Приложения, использующие Angular Ivy, могут беспрепятственно использовать библиотеки, скомпилированные с помощью View Engine.

Отладка

Рассмотрим на примере, как в Angular Ivy изменился формат вывода ошибок.

app.component.ts

1
2
3
4
5
6
7
8
9
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
})
export class AppComponent {
    title = 'Angular ivy';
}

app.component.html

1
2
3
4
5
6
7
<h1>{{title}}</h1>

<select (change)="selectValueChanged($event)">
    <option value="1">Faster compilation</option>
    <option value="2">Small bundle size</option>
    <option value="3">Informative debugging</option>
</select>

Здесь на событие изменения значения выпадающего списка вызывается несуществующий метод selectValueChanged(), что инициирует возникновение ошибки.

Вывод ошибки с View Engine.

Вывод ошибки с View Engine

Вывод ошибки c Angular Ivy.

Вывод ошибки c Angular Ivy

Динамическая загрузка

Angular Ivy поддерживает динамический импорт ES6. В View Engine все асинхронно подгружаемые модули загружаются следующим образом.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const routes: Routes = [
    {
        path: ':lang',
        children: [
            {
                path: 'auth',
                loadChildren:
                    './auth/auth.module#AuthModule',
            },
        ],
    },
];

Загрузка в Angular Ivy выглядит так.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const routes: Routes = [
    {
        path: ':lang',
        children: [
            {
                path: 'auth',
                loadChildren: () =>
                    import('./auth/auth.module').then(
                        ({ AuthModule }) => AuthModule
                    ),
            },
        ],
    },
];

Динамический импорт также дает возможность загружать отдельные компоненты без их объявления в модуле.

app.module.ts

1
2
3
4
5
6
7
@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

app.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import {
    Component,
    ɵrenderComponent,
    Injector,
} from '@angular/core';

import { ChildComponent } from './child.component';

@Component({
    selector: 'app-root',
    template: `
        <h1>Root component</h1>

        <button (click)="loadChild()">
            Load ChildComponent
        </button>
    `,
})
export class AppComponent {
    constructor(private injector: Injector) {}

    loadChild() {
        import('./child.component').then(
            ({ ChildComponent }) => {
                ɵrenderComponent(ChildComponent, {
                    host: 'app-root',
                    injector: this.injector,
                });
            }
        );
    }
}

child.component.ts

1
2
3
4
5
6
7
8
9
import { Component } from '@angular/core';

@Component({
    selector: 'app-child',
    template: `
        <h1>Dynamically loaded "ChildComponent"</h1>
    `,
})
export class ChildComponent {}

Для отображения загружаемого компонента используется функция ɵrenderComponent(), которая первым параметром принимает тип компонента, а вторым — объект конфигурации со следующими свойствами:

  • host — селектор компонента, в который будет загружен подгруженный компонент;
  • injector — экземпляр текущего объекта injector, который указывается, только если подгружаемый компонент имеет зависимости.

Комментарии