Хабрахабр

[Перевод] Готовьтесь: Angular 8 уже близко

Автор материала, перевод которого мы публикуем, предлагает поговорить об Angular 8. Здесь будут рассмотрены некоторые особенно горячие темы, поднятые на мероприятиях NgConf и Google I/O 2019. Поэтому, если вы интересуетесь Angular, но по каким-то причинам не видели докладов с этих мероприятий, полагаем, вам любопытно будет узнать о том, чего можно ждать от Angular 8.

Основные положения

Уверен, что вы сейчас, с нетерпением ожидая выхода Angular 8, испытываете те же чувства, что испытывал я после NgConf 2019. В докладе Игоря Минара затронуто множество ожидаемых новшеств — от инструментов до технологий вроде дифференциальной загрузки и многих других замечательных вещей.

А именно, рассмотрим новые возможности и поговорим о том, приведёт ли их появление к признанию устаревшими существующих механизмов, или к тому, что новое окажется несовместимым со старым. Обсудим то, как всё это может повлиять на ваши проекты.

Новые возможности

▍Дифференциальная загрузка

При применении технологии дифференциальной загрузки (differential loading), Angular, в процессе сборки проекта, может создать отдельный бандл для полифиллов (polyfills). Это зависит от файла browserlist. Вот как это, в общих чертах, будет выглядеть.

Сверху — новый способ упаковки проектов (источник)

Использование этой возможности позволит уменьшить размеры бандлов.

Экономия благодаря применению дифференциальной загрузки (источник)

Как же это работает?

Angular будет собирать дополнительные файлы с полифиллами и они будут внедряться в код с помощью атрибутов nomodule:

<body> <pp-root></pp-root>
<script type="text/javascript" src="runtime.js"></script> <script type="text/javascript" src="es2015-polyfills.js" nomodule></script> <script type="text/javascript" src="polyfills.js"></script> <script type="text/javascript" src="styles.js"></script> <script type="text/javascript" src="vendor.js"></script> <script type="text/javascript" src="main.js"></script>
</body>

Атрибут nomodule, логический, предотвращает загрузку и выполнение скрипта в браузерах, поддерживающих ES6-модули. Такие браузеры игнорируют подобные скрипты. Старые браузеры загружают и выполняют их.

▍SVG-шаблоны

Теперь SVG файлы можно будет использовать в качестве шаблонов. До сих пор в качестве шаблонов можно было использовать встроенный или внешний HTML-код.

@Component({ selector: "app-icon", templateUrl: "./icon.component.svg", styleUrls: ["./icon.component.css"]
})
export class AppComponent

▍Экспериментальный движок рендеринга Ivy

Движок Ivy всё ещё находится в экспериментальной стадии. После выхода Angular 8 его можно испытать, воспользовавшись при создании нового приложения флагом --enable-ivy. Ниже показан соответствующий код. Помните о том, что Ivy пока ещё не вполне готов (он ещё находится в статусе «opt-in preview»), и, как сказал Игорь Минар на NgConf 2019, при создании новых приложений всё ещё рекомендуется использовать движок View Engine.

Для того чтобы включить использование Ivy в существующем проекте, нужно в файле tsconfig.app.json установить в true параметр enableIvy option в angularCompilerOptions:

"angularCompilerOptions": {"enableIvy": true}

Можно и создать новое приложение, в котором будет использоваться Ivy:

$ ng new my-app --enable-ivy

Ivy предлагает следующие полезные возможности, появление трёх первых из которых ожидается в Angular 9:

  1. Более быстрая компиляция.
  2. Улучшенная проверка типов для шаблонов.
  3. Уменьшение размеров бандлов. Вот, если вы ещё этого не видели, демонстрация приложения размером 4.3 Кб с Google I/O 19.
  4. Обратная совместимость.
  5. И моя любимая возможность — отладка шаблонов. Уверен, что, как и мне, это нужно многим разработчикам.

▍Поддержка Bazel

Bazel — это очередной инструмент, переведённый Google в разряд опенсорсных. Игорь Минар говорит, что Bazel долгое время использовался для внутренних нужд компании, а теперь он доступен всем. Для того чтобы узнать подробности об этом сборщике проектов — загляните в документацию и почитайте о том, как использовать Bazel с Angular.

Если кратко ответить на этот вопрос — то ещё не готов. Возможно, вы сейчас задаётесь вопросом о том, готов ли Bazel к практическому применению. Позволю себе процитировать Алекса Игла, который руководит в Google командой по разработке инструментов Angular: «Если вы уже входили в воды Bazel раньше, то не могли не заметить, что там было множество акул… Теперь с акулами уже справились, но вода всё ещё может оказаться холодной». Сейчас он пребывает в статусе «opt-in preview».

Bazel пока доводят до ума, ожидается, что его включат в @angular/cli в версии 9.

Вот какие полезные возможности способен дать нам Bazel:

  1. Ускорение времени сборки проектов. Первая сборка занимает определённое время, но параллельные сборки выполняются гораздо быстрее. Angular уже использует Bazel, и теперь CI-процедуры завершаются за 7.5 минут, а не за час, как было до Bazel.
  2. Инкрементальная сборка проектов. Можно будет собирать и разворачивать не всё приложение, а лишь то, что в нём изменилось.
  3. Возможность работы с файлами Bazel, которые, по умолчанию, скрыты.

Добавить в существующий проект поддержку Bazel можно так:

ng add @angular/bazel

Можно и создать новое приложение с использованием Bazel:

$ npm install -g @angular/bazel
$ ng new my-app --collection=@angular/bazel

▍API Builders

Новая версия Angular позволяет использовать API Builders, известный так же как Architect. Angular использует сборщики (builder) для выполнения основных операций: serve, build, test, lint и e2e. Вот пример использования сборщиков из файла angular.json:

... "projects": { "app-name": { ... "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", ... }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", ... }, "test": { "builder": "@angular-devkit/build-angular:karma", ... }, "lint": { "builder": "@angular-devkit/build-angular:tslint", ... }, "e2e": { "builder": "@angular-devkit/build-angular:protractor", ... } } }
}

Теперь можно создавать собственные сборщики. Мне они видятся подобными командам gulp/grunt, используемым в «прежние времена».

В целом, сборщик — это просто функция с набором команд, которую передают методу createBuilder() из пакета @angular-devkit/architect:

import { createBuilder } from '@angular-devkit/architect';
function customBuild(options, context) { return new Promise((resolve, reject) => { // набор команд })
}
createBuilder(customBuild);

На встроенные сборщики Angular можно взглянуть здесь. Вот отличный материал о них в блоге Angular.

▍Изменения в ленивой загрузке

В новой версии Angular будет и новая версия системы ленивой загрузки модулей, появление которой приводит к тому, что существующий синтаксис loadChildren:string будет признан устаревшим.

Раньше это выглядело так:

loadChildren: './lazy/lazy.module#LazyModule';

С выходом Angular 8 — так:

loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)

Если у вас есть множество модулей, при работе с которыми применяется механизм ленивой загрузки, и вы хотите автоматизировать их перевод в новый режим работы — взгляните на этот материал.

▍Поддержка API $location AngularJS

Команда разработчиков Angular стремится к тому, чтобы поддержать тех, кто пользуется AngularJS и помочь им перейти на Angular. В результате в систему, в пакет angular/common/upgrade, добавлена поддержка сервиса $location. Речь идёт о следующих возможностях:

  1. Получение состояния от сервиса $location.
  2. Отслеживание изменений адреса.
  3. Получение тех же сведений о составных частях адреса, которые можно было получить в AngularJS (hostname, protocol, port, search).
  4. Тестирование сервиса с помощью API MockPlatformLocation.

▍Веб-воркеры

В Angular 8 добавлена поддержка веб-воркеров. С их помощью можно организовать фоновое выполнение ресурсоёмкого кода. Для того чтобы создать новый веб-воркер можно воспользоваться следующей командой интерфейса командной строки Angular:

ng g webWorker <name>

▍Сервис-воркеры

Так как в последнее время наблюдается серьёзный рост популярности прогрессивных веб-приложений, было сделано множество улучшений сервис-воркеров. В частности, одним из таких улучшений стало добавление параметра SwRegistrationOptions. Ещё одним улучшением стала поддержка нескольких приложений на одном домене.

Почитать подробности о сервис-воркерах можно в этом разделе документации Angular.

▍Улучшения форм

Добавлен метод markAllAsTouched, который позволяет отметить все элементы внутри FormGroup как touched. Это весьма полезно в тех случаях, если нужно запустить валидацию всех элементов управления внутри FormGroup. До этого то же самое делалось так:

validateFormAndDisplayErrors(form: FormGroup) { Object.keys(form.controls).map((controlName) => { form.get(controlName).markAsTouched({onlySelf: true}); });
}

В новом Angular для очистки FormArray можно воспользоваться методом clear, который удаляет из него все элементы. Ранее нужно было пользоваться следующей конструкцией, удаляя первый элемент в каждой итерации цикла:

while (formArray.length) { formArray.removeAt(0);
}

Больше так делать не придётся. Теперь достаточно вызвать единственный метод:

formArray.clear()

▍Настройка момента получения ответа при использовании директив ViewChild и ContentChild

Эта новая возможность подразумевает использование флага static, который позволяет указать момент разрешения запроса, определяемого директивой ViewChild или ContentChild.

Иногда результаты поиска доступны в методе жизненного цикла ngOnInit, а иногда их нет до вызова ngAfterContentInit или ngAfterViewInit. Возможно, вы сталкивались со следующими примерами непоследовательного поведения системы. Вот как пользоваться флагом static:

// Обеспечивает проведение обнаружения изменений перед предоставлением доступа к элементу
@ContentChild('foo', { static: false }) foo!: ElementRef;
// Позволяет получить доступ к элементу в методе жизненного цикла ngOnInit
@ViewChild(TemplateRef, { static: true }) foo!: TemplateRef;

Надо отметить, что эти возможности недоступны для директив ViewChildren и ContentChildren. Соответствующие им запросы на поиск элементов выполняются после выполнения обнаружения изменений.

В систему добавлено правило Schematics, позволяющее перевести существующий код на использование нового синтаксиса. При использовании static: true стоит проявлять осторожность, так как применение этого флага не позволит получать результаты из динамических шаблонов (то есть *ngIf). Этот синтаксис будет использоваться с Ivy.

→ Подробности об этой возможности можно почитать здесь.

▍Поддержка Typescript 3.4.x

Angular теперь использует TypeScript 3.4 (в седьмой версии Angular применяется TypeScript 3.2.x). В новой версии TS не так уж и много серьёзных изменений. Они, вероятно, не приведут к неприятным последствиям.

4 можно узнать здесь. → Подробности о новшествах TS 3.

▍Улучшение производительности

В текущих условиях ServerRendererFactory2 создаёт новый экземпляр DomElementSchemaRegistry для каждого запроса, что довольно затратно в плане ресурсов. Теперь же будет организовано совместное использование глобального экземпляра DomElementSchemaRegistry.

▍Развёртывание Angular-приложений на хостинге Firebase

Если вы пользуетесь хостингом Firebase для развёртывания Angular-приложений, то вам, определённо, понравится это нововведение. Речь идёт о том, что теперь в Angular CLI имеется специальная команда для выполнения этой операции:

ng run [PROJECT_NAME]:deploy

→ Тут можно узнать подробности об этой возможности.

API, признанные устаревшими

▍Использование типа any при работе с TesBed.get

Метод TesBed.get имел две сигнатуры. Одна — типизированная, вторая — принимающая и возвращающая тип any. Теперь сигнатура метода, предусматривающая применение типа any, признана устаревшей. Пользоваться этим методом можно только с указанием конкретного типа. Это, например, окажет воздействие на случаи работы со строковыми токенами (которые не поддерживаются) и с некоторыми другими токенами.

Раньше использовались такие конструкции:

TestBed.configureTestingModule({ providers: [{ provide: "stringToken", useValue: new Service() }],
});
let service = TestBed.get("stringToken"); // тип any

Теперь применяется следующий подход:

const SERVICE_TOKEN = new InjectionToken<Service>("SERVICE_TOKEN");
TestBed.configureTestingModule({ providers: [{provide: SERVICE_TOKEN, useValue: new Service()}],
});
let service = TestBed.get(SERVICE_TOKEN); // тип Service

▍Удаление DOCUMENT из angular/platform-browser

Из пакета @angular/platform-browser удаляют DOCUMENT. Если вы пользуетесь DOCUMENT из этого пакета — вам стоит начать импортировать его из @angular/common.

▍Удаление пакета angular/http

Пакет @angular/http был признан устаревшим в Angular 5, но был всё ещё доступен, так как @angular/platform-server был от него зависим. Теперь этот пакет удаляют из списка пакетов.

Критические изменения

▍Автоматическое исправление кода

Немногие знают о том, что Angular автоматически исправлял ошибки при использовании HTML-элементов tr и col.

Исправления заключались в автоматическом помещении элемента в tbody. В случае с tr исправления выполнялись в том случае, если соответствующий элемент не находился внутри тега tbody, tfoot или thead.

В случае с col исправлениям подвергался код, в котором этот элемент не находится внутри тега colgroup.

Делается это для того чтобы избежать конфликтов и ошибок. Теперь Angular оставляет исправление этих ошибок на усмотрение разработчиков. Как результат, тем, кто привык к этой возможности, нужно будет заботиться о правильности кода самостоятельно.

→ Подробности об этом можно почитать здесь.

▍Переименование Angular Material

Проект Angular Material переименован в Angular Components. Имена пакетов не изменились.

Итоги

Angular 8 выйдет уже очень скоро. Команда разработчиков Angular делает большое дело. Результаты их усилий облегчают работу и жизнь тех, кто пользуется Angular. В частности, например, с каждой новой версией фреймворка всё проще и проще выполнять переход на неё с предыдущей версии. Вот, например, как это выглядит в случае с Air France.

Время, необходимое для перехода на новые версии Angular (источник)

В результате можно надеяться на то, что переход с Angular 7 на Angular 8 не займёт много времени и не потребует серьёзных усилий.

Тут можно найти пошаговые руководства по переходу на новые версии Angular.

0. Примерно месяц назад Игорь Минар говорил, что всё указывает на то, что Angular 8. 24 мая вышел Angular 8. 0 вполне может выйти в конце мая. 0-rc. 0. 5.

Всё остальное зависит от нас. Будущее Angular выглядит достаточно оптимистичным.

Уважаемые читатели! Чего вы ждёте от Angular 8?

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть