Целевые предупреждения машинописного текста после обновления Angular 15

Я обновил свое угловое приложение до Angular 15. Он строится нормально, если только не появляются такие предупреждения, как:

Для параметров компилятора TypeScript «target» и «useDefineForClassFields» в Angular CLI установлены значения «ES2022» и «false» соответственно.

Мойtsconfig.jsonустанавливает цель наES6:

      {
  ...
  "compilerOptions": {
      "target": "ES6",
      ...
  }
}

В документации говорится:

Внутри Angular CLI теперь всегда устанавливает цель TypeScript на ES2022 и useDefineForClassFields на false, если цель не установлена ​​на ES2022 или более позднюю версию в конфигурации TypeScript.

https://github.com/angular/angular-cli/blob/main/CHANGELOG.md

И мой .browserslistrc месяц выглядит одинаково без изменений с самого начала:

      last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR

Таким образом, как я могу избавиться от этого предупреждения?

3 ответа

Чтобы понять это предупреждение, нам сначала нужно понять, как работает сборка Angular.

Во-первых, сборка TypeScript должна быть запущена. На этом этапе с настройками в файле ваш код TypeScript компилируется в JavaScript. Если вы установите значение , до Angular 15 сборка TypeScript будет создавать код ES6.

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

В те дни, когда Angular поддерживал IE11, это было намного сложнее. В какой-то момент Angular CLI даже сгенерировал дополнительный пакет только для IE11, это называлось дифференциальной загрузкой . Но теперь, когда Angular прекратил поддержку IE11, они могут снова упростить вещи и перейти к современным пакетам, что, вероятно, является причиной их изменений в v15.

Так что, на мой взгляд, нет веских причин устанавливатьtargetв вашейtsconfig.jsonк такой старой версии, какES6. Современные браузеры теперь поддерживают гораздо больше функций EcmaScript, и использование более новой версии EcmaScript уменьшит размер вашего пакета. В любом случае Babel заполнит отсутствующие функции, так что вам не о чем беспокоиться. Просто установите цель на ES2022, как они предлагают.

У меня была такая же проблема, и я успешно отключил это предупреждение, добавив"target": "ES2022"и"useDefineForClassFields": falseк моемуtsconfig. Была ли это хорошая идея или нет, придется ждать комментария от кого-то более знающего, чем я. Я беспокоюсь, что это потерпит неудачу так же, как у вас сейчас, когда2022становится2023(или что будет дальше). Конечно, было бы лучше, если бы его можно было полностью исключить (как я сделал), если Angular все равно собирается переопределить его. Но я могу иметь неполное представление о проблеме.

В вашем случае вы должны быть в состоянии сделать (или хотя бы попытаться) то же самое вместоES6(что я понимаю, это то же самое, что иES2015). Согласно приведенной вами документации, это то, что Angular делает в любом случае, независимо от вашего запроса, поэтому, если вы получаете только предупреждение и никаких ошибок, ваш код должен быть в порядке. Если вам нужно ограничить что-то еще до уровня ES6, кажется, вам нужно использовать свой.broswerslistrcфайл, чтобы сделать это, что уже может быть хорошо.

Я думаю, проблема здесь в том, что предупреждение бесполезно, по крайней мере, для таких людей, как вы и я, которые получают его и не знают, что с этим делать. Также следующая за ней веб-ссылка («Для управления версией и функциями ECMA используйте конфигурацию списка браузеров. Для получения дополнительной информации см. https://angular.io/guide/build#configuring-browser-compatibility ») не кажется особенно полезной в обращаясь к предупреждению, говоря нам, что мы должны делать, но не что делать, чтобы избавиться от предупреждения.

Изменить: Оказывается, с этим предупреждением произошла ошибка, исправленная в Angular CLI 16.0.4. Для Angular CLI 15–16.0.3 обязательно установитеtarget="ES2022"во избежание несоответствия, описанного ниже. Проверьте версию CLI с помощьюng version.


Будьте осторожны, чтобы не истолковать неверно предупреждение и его последствия!

Полное сообщение (на момент Angular 16) гласит следующее:

Для параметров компилятора TypeScript «target» и «useDefineForClassFields» Angular CLI устанавливает значения «ES2022» и «false» соответственно.Для управления версией и функциями ECMA используйте конфигурацию Browserslist. Для получения дополнительной информации см. https://angular.io/guide/build#configuring-browser-compatibility . ПРИМЕЧАНИЕ. Чтобы удалить это предупреждение, вы можете установить в качестве цели «ES2022» в tsconfig проекта.

Одна вполне разумная интерпретация этого может быть такой:

Angular ИГНОРИРУЕТ все, что я ставлюcompilerOptions.targetв вашейtsconfig.jsonи компилирует мой код как ES2022.

Однако это НЕ то, что происходит!

Для подтверждения я создал простойng newпроект с Angular 16 и обновил свою цель до ES2015:

      compilerOptions: {
   "target": "ES2015"
}

Я написал следующие строки кода в своем AppComponent, используя нулевой оператор объединения , который является функцией ES2022.

      const cat = null;
const dog = { catName: 'Kim' };

const animal = cat ?? dog;

Просмотр скомпилированного кода .js (а не файла .ts с исходным кодом), работающего в браузере черезng serveвы увидите следующее, демонстрируя, что файл уже транспилирован для совместимости со старыми браузерами:

       const animal = cat !== null && cat !== void 0 ? cat : dog;

Это, конечно, не происходит «из коробки» с целью ES2022.

Итак, допустим, вам действительно нужна поддержка Safari 13.0 (которая не поддерживает ??) и вы думаете, что все в порядке.

Опять неправильно!

Выполните поиск в браузере, и вы увидите множество мест, где??используется в файлеvendor.js. Он НЕ переносится туда, и поэтому ваше приложение не будет работать в Safari 13.0.

Вот тут-то и появляется список браузеров, который, если он настроен, будет транспилировать все приложение для определенной цели.


Что на самом деле означает это сообщение на практике:

Код вашего приложения компилируется для целевой системы старше ES2022, что может привести к несоответствию вашего кода и кода поставщика. Мы рекомендуем установить в качестве цели ES2022 и использовать исключительно браузерслист для управления транспиляцией для старых браузеров, чтобы гарантировать, что весь код транспилируется должным образом.


Почему я до сих пор в замешательстве:

Следующий коммит, в котором представлена ​​эта функция, похоже, устанавливает цель ES2022, но на самом деле она никогда не вступает в силу для кода приложения. Не знаю почему.

https://github.com/angular/angular-cli/pull/23936/commits/cdac700b93d5593ce92b44b1691941673eaf25b0#diff-2d55449c69797885b38f6b957a1fd03d27beda366a9270293719ec041cf15d0f

Другие вопросы по тегам