Новая версия Angular v10 была опубликована всего несколько часов назад и анонсирована в этом сообщении в блоге. Хотя он может показаться не таким эффективным, как v9 (с Ivy и всем остальным), этот выпуск отражает стремление команды Angular поддерживать Angular в актуальном состоянии.

Нам это показалось очень захватывающим, и время было как раз подходящим, потому что мы собираемся выпустить ABP v3.0! Итак, мы углубились в подробности того, что изменилось и как перенести. Вот что мы нашли.

Значительные перемены

Поддержка TypeScript v3.9 [критическое изменение]

Angular 9 был выпущен с поддержкой TypeScript 3.7. Вскоре был выпущен TypeScript 3.8, который поддерживался Angular v9.1. Вскоре после этого выходит еще одна версия TypeScript, 3.9, и Angular отвечает v10, не отставая не только от TypeScript, но также с TSLib и TSLint.

Это отличные новости. Angular остается в актуальном состоянии. Прежде всего, TypeScript 3.9 имеет улучшения производительности, что означает более быструю сборку Angular, особенно в больших проектах. Во-вторых, все последние исправления и функции TypeScript доступны разработчикам Angular. И последнее, но не менее важное: разработчики Angular будут использовать более сложную конфигурацию TypeScript.

Более ранние версии TypeScript больше не поддерживаются, поэтому вам необходимо установить v3.9 в свой проект. Я считаю, что основной причиной этого является следующая функция, которую я опишу.

«Стиль решения» tsconfig.json Файлы

Поддержка файлов Стиль решения tsconfig.json была введена в TypeScript v3.9 для решения проблем, связанных со случаями, когда tsconfig.json существовал только для ссылки на другие tsconfig.json файлы, известные как решение. Angular 10 использует эту концепцию и улучшает поддержку IDE и, как следствие, удобство для разработчиков.

Представлен новый файл с именем tsconfig.base.json, и то, что было раньше в корне tsconfig.json, переносится в этот новый файл. Вы можете найти более подробную информацию о конфигурации решения здесь, но в основном новый tsconfig.json на корневом уровне до и после добавления библиотеки в проект выглядит так, как показано ниже.

ДО:

{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.spec.json"
    },
    {
      "path": "./e2e/tsconfig.json"
    }
  ]
}

ПОСЛЕ:

{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.spec.json"
    },
    {
      "path": "./e2e/tsconfig.json"
    },
    {
      "path": "./projects/core/tsconfig.lib.json"
    },
    {
      "path": "./projects/core/tsconfig.spec.json"
    }
  ]
}

Если вы обновитесь до Angular 10 с помощью ng update, интерфейс командной строки перенесет ваше рабочее пространство в эту структуру. Более ранние версии TypeScript не поддерживают «стиль решения», поэтому это может быть причиной критического изменения, описанного выше.

Изменения формата пакета Angular и esm5 / fesm5

Изменился формат пакета Angular, и новый формат больше не включает дистрибутивы esm5 и fesm5. Пакеты Angular (@ angular / *) не будут включать их. Поскольку Angular генерирует ES5 из ES2015, а ES2015 является языковым уровнем по умолчанию, используемым инструментами Angular, эти дистрибутивы кода устарели. Изменение формата выглядит следующим образом:

ДО:

{
  ...
  "main": "bundles/abp-ng.core.umd.js",
  "module": "fesm5/abp-ng.core.js",
  "es2015": "fesm2015/abp-ng.core.js",
  "esm5": "esm5/abp-ng.core.js",
  "esm2015": "esm2015/abp-ng.core.js",
  "fesm5": "fesm5/abp-ng.core.js",
  "fesm2015": "fesm2015/abp-ng.core.js",
  ...
}
{
  ...
  "main": "bundles/abp-ng.core.umd.js",
  "module": "fesm2015/abp-ng.core.js",
  "es2015": "fesm2015/abp-ng.core.js",
  "esm2015": "esm2015/abp-ng.core.js",
  "fesm2015": "fesm2015/abp-ng.core.js",
  ...
}

ПОСЛЕ:

{
  ...
  "main": "bundles/abp-ng.core.umd.js",
  "module": "fesm2015/abp-ng.core.js",
  "es2015": "fesm2015/abp-ng.core.js",
  "esm2015": "esm2015/abp-ng.core.js",
  "fesm2015": "fesm2015/abp-ng.core.js",
  ...
}

Если ваше приложение зависит от файлов esm5 / fesm5, вы можете расслабиться, потому что они все еще используются системой сборки. Точно так же вам не нужно беспокоиться, если ваша библиотека Angular не поставляется esm2015 или fesm2015, потому что CLI откатится к другим. Однако в пользу оптимизации пакетов и скорости сборки рекомендуется предоставлять результаты ES2015.

Список браузеров

Angular генерирует пакеты на основе конфигурации Browserlist, предоставленной в корневой папке приложения. Angular 10 будет искать .browserlistrc в вашем приложении, но вернется к browserlist, если не найден. Команда ng update переименует файл за вас.

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

  • Резольверы, возвращающие EMPTY, отменят навигацию. Чтобы позволить маршрутизатору продолжить навигацию по маршруту, передайте какое-либо значение, например of(null).
  • Регистрация неизвестных привязок свойств или имен элементов в шаблонах повышена до уровня «ошибки». Раньше это было «предупреждение». Изменение может повлиять на инструменты, не ожидающие журнала ошибок.
  • При возврате null из UrlMatcher раньше было бы выдано Type 'null' is not assignable to type 'UrlMatchResult'.. Это исправлено, но тип возвращаемого значения теперь тоже может быть null.
  • В реактивных формах была ошибка, из-за которой valueChanges элементы управления, привязанные к полям ввода с типом number, срабатывали дважды. Чтобы исправить это, прослушиваемый вечер меняется с «изменить» на «ввод».
  • Валидаторы minLength и maxLength проверяют, только если значение имеет числовое свойство length.
  • При использовании кода формата formatDate() или DatePipe и b или B произошла ошибка определения дневного интервала. Это исправлено, и, например, теперь вывод будет «ночью» вместо «AM».
  • Трансплантированные представления (объявленные в одном компоненте и вставленные в другой) имели проблемы с обнаружением изменений, но теперь это исправлено. Обнаружение после отсоединения и двойное обнаружение исключаются.

Устаревание и удаление

ModuleWithProviders без универсального типа [удалено]

Более ранние версии Angular могли компилировать возвращаемые статические методы с типом ModuleWithProviders без общего типа, то есть ModuleWithProviders<SomeModule>, потому что сгенерированные файлы metadata.json будут иметь информацию, необходимую для компиляции. После Ivy, поскольку metadata.json не требуется, Angular проверяет универсальный тип для проверки типа.

ДО:

@NgModule({...})
export class SomeModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SomeModule,
      providers: [...]
    };
  }
}

ПОСЛЕ:

@NgModule({...})
export class SomeModule {
  static forRoot(): ModuleWithProviders<SomeModule> {
    return {
      ngModule: SomeModule,
      providers: [...]
    };
  }
}

ModuleWithProviders без универсального типа ранее считался устаревшим. Начиная с Angular 10, он полностью удален.

Неукрашенные базовые классы [удалено]

Если вы используете наследование от классов, которые используют функции Angular, такие как внедрение зависимостей или декораторы Angular, теперь вам также необходимо украсить эти базовые классы. В противном случае Angular выдаст ошибку об отсутствии декоратора в родительском элементе.

ИНЪЕКЦИЯ ЗАВИСИМОСТИ:

@Directive()
export abstract class AbstractSome {
  constructor(@Inject(LOCALE_ID) public locale: string) {}
}
​
@Component({
  selector: 'app-some',
  template: 'Locale: {{ locale }}',
})
export class SomeComponent extends AbstractSome {}

Вот ошибка, которую выдает компилятор Angular 10 при отсутствии декоратора Directive:

The component SomeComponent inherits its constructor from AbstractSome, but the latter does not have an Angular decorator of its own. Dependency injection will not be able to resolve the parameters of AbstractSome's constructor. Either add a @Directive decorator to AbstractSome, or add an explicit constructor to SomeComponent.

ДЕКОРАТОР:

@Directive()
export abstract class AbstractSome {
  @Input() x: number;
}
​
@Component({
  selector: 'app-some',
  template: 'Value of X: {{ x }}',
})
export class SomeComponent extends AbstractSome {}

На этот раз компилятор Angular 10 выдает менее подробную ошибку:

Class is using Angular features but is not decorated. Please add an explicit Angular decorator.

Я уверен, что вы этого не сделаете, но если вы поместите декоратор Component на родителя и удалите декоратор на дочернем, как и следовало ожидать, компилятор Angular 10 выдаст ошибку ниже:

The class 'SomeComponent' is listed in the declarations of the NgModule 'AppModule', but is not a directive, a component, or a pipe. Either remove it from the NgModule's declarations, or add an appropriate Angular decorator.

WrappedValue [устарело]

WrappedValue устарел и, вероятно, будет удален в версии 12. Отметьте здесь и здесь, если вы никогда не слышали об этом раньше.

Было полезно запускать обнаружение изменений, даже если был создан / испущен один и тот же экземпляр объекта. Использование WrappedValue снижает производительность, а случаи, когда это помогает, относительно редки, поэтому команда Angular решила отказаться от этого.

В качестве побочного эффекта этого исключения вы можете увидеть больше ExpressionChangedAfterItHasBeenChecked ошибок, чем раньше, потому что Angular не выдает ошибку, когда WrappedValues оцениваются как равные.

Если вы столкнетесь с проблемами обнаружения изменений, попробуйте клонировать объект или инициировать обнаружение изменений вручную с помощью markForCheck или detectChanges методов ChangeDetectorRef.

Прочие устаревшие версии и удаления

  • Поддержка IE9, IE10 и IE Mobile устарела и будет прекращена позже. Основной причиной были увеличенный размер и сложность связки. Учитывая, что даже Microsoft отказалась от поддержки этих браузеров, это имеет смысл.
  • Angular прекратил дезинфекцию привязок свойств стиля. Это связано с прекращением поддержки устаревших браузеров (таких как IE6 и IE7) и снижением производительности из-за наличия дезинфицирующего средства.
  • Схема сборки Базеля не будет продолжена. Команда Angular объяснила причины и сослалась на этот монорепозиторий как на источник, за которым нужно следить, если вы заинтересованы в сборке Angular с помощью Bazel.

Заключение

Я хотел бы подчеркнуть, насколько я благодарен за то, что команда Angular пытается поддерживать Angular в актуальном состоянии. Это отличная демонстрация, и, по моему скромному мнению, столь же значимая, как и современный рендерер. Также очень приятно видеть, насколько легко перенести существующий проект. Angular не только идет в ногу со своей экосистемой, но и помогает вам идти в ногу с ней.

Поздравления и спасибо!

Эта статья изначально была опубликована в Блоге Волософт.