Целевые предупреждения машинописного текста после обновления 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, но на самом деле она никогда не вступает в силу для кода приложения. Не знаю почему.