Reputation: 4802
I updated my angular app to Angular 15. It builds ok - unless some warnings like:
TypeScript compiler options "target" and "useDefineForClassFields" are set to "ES2022" and "false" respectively by the Angular CLI.
My tsconfig.json
sets the target to ES6
:
{
...
"compilerOptions": {
"target": "ES6",
...
}
}
The documentation says:
Internally the Angular CLI now always set the TypeScript target to ES2022 and useDefineForClassFields to false unless the target is set to ES2022 or later in the TypeScript configuration.
https://github.com/angular/angular-cli/blob/main/CHANGELOG.md
And my .browserslistrc looks the same for month with no changes since the beginning:
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
Thus, how can I get rid of this warning?
Upvotes: 37
Views: 42768
Reputation: 1
If modifying tsconfig.json wasn't enough, this worked for me: There were multiple ts config files (e.g. tscofig.base.json) where i have to set the target to ES2022. (I used search on 'target' to find all of them in the project) - angular 18
Upvotes: 0
Reputation: 17688
To understand this warning, we first need to understand how the Angular build works.
First, the TypeScript build needs to run. During this step, with the settings in the tsconfig.json
, your TypeScript code is being compiled into JavaScript. If you set target
to ES6
, prior to Angular 15 the TypeScript build would produce ES6 code.
Afterwards, Angular uses Babel to make the generated JavaScript code backwards compatible to older browser versions, see the docs. It goes through the browserslist configuration to get the list of browsers which you wish to support, and will make sure that the application doesn't use a feature which isn't implemented by all supported browsers yet.
Back in the days when Angular supported IE11, this was a lot more complicated. At one point the Angular CLI even generated an extra bundle just for IE11, this was called differential loading. But now that Angular dropped support for IE11, they can simplify things again and move toward modern bundles, which is probably the reason for their changes in v15.
So in my point of view, there is no good reason to set the target
in your tsconfig.json
to such an old verison like ES6
. The modern browsers support way more EcmaScript features now, and using a more up to date EcmaScript version will make your bundle size smaller. Babel will polyfill missing features anyways, so you don't have to worry. Just set the target to ES2022 like they suggest.
Upvotes: 44
Reputation: 146120
Edit: Turns out there was a bug related to this warning, fixed in Angular CLI 16.0.4. For Angular CLI 15 - 16.0.3 make sure you set target="ES2022"
to avoid the mismatch described below. Check your CLI version with ng version
.
The full message (as of Angular 16) says this:
TypeScript compiler options "target" and "useDefineForClassFields" are set to "ES2022" and "false" respectively by the Angular CLI. To control ECMA version and features use the Browerslist configuration. For more information, see https://angular.io/guide/build#configuring-browser-compatibility NOTE: You can set the "target" to "ES2022" in the project's tsconfig to remove this warning.
One quite reasonable interpretation of this might be:
Angular is IGNORING whatever I put for
compilerOptions.target
in yourtsconfig.json
, and is compiling my code as ES2022.
However, that is NOT what is happening!
To confirm, I created a simple ng new
project with Angular 16 and updated my target to ES2015:
compilerOptions: {
"target": "ES2015"
}
I wrote the following lines of code in my AppComponent, using the nullish coalescing operator which is an ES2022 feature.
const cat = null;
const dog = { catName: 'Kim' };
const animal = cat ?? dog;
Looking at the .js compiled code (not the sourcemapped .ts file) running in the browser via ng serve
you'll see the following - demonstrating that the ??
has already been transpiled to be compatible with older browsers:
const animal = cat !== null && cat !== void 0 ? cat : dog;
This of course doesn't happen out-of-the-box with the ES2022 target.
So let's say you really need to support Safari 13.0 (which doesn't support ??) and think that everything is fine.
Wrong again!
Search in the browser for ??
and you'll see numerous places where ??
is used in the vendor.js file. It is NOT being transpiled there and therefore your app won't work on Safari 13.0.
That's where the browserslist comes in, which if configured will transpile the entire application for a certain target.
Your application code is being compiled for a target older than ES2022, which may lead to a mismatch between your code and vendor code. We recommend setting your target to ES2022 and using exclusively browserslist to control transpilation for older browsers, to ensure all code is transpiled as intended.
The following commit which introduced this feature appears to set the target to ES2022 but it never actually takes effect for application code. Not sure why.
Upvotes: 12
Reputation: 391
I had the same issue and successfully silenced this warning by adding "target": "ES2022"
and "useDefineForClassFields": false
to my tsconfig
. Whether this was a good idea or not will have to await a comment from someone more knowledgeable than me. I worry that this will fail in the same way that yours now has when 2022
becomes 2023
(or whatever comes next). Surely it would be better if it could be left out completely (as I had) if Angular is going to override it anyway. But I may have an incomplete grasp of the issue.
In your case, you should be able to do (or at least attempt) the same thing in place of ES6
(which I understand to be the same as ES2015
). According to the documentation you cited, this is what Angular is doing anyway, regardless of your request, so if you only get the warning and no errors your code should be fine. If you need to restrict things further to the ES6 level, it seems you need to use your .broswerslistrc
file to do this, which may also be fine already.
I think the problem here is that the warning is not helpful, at least to people like you and me, who are the ones receiving it and not knowing what to do about it. Also the weblink that follows it ("To control ECMA version and features use the Browerslist configuration. For more information, see https://angular.io/guide/build#configuring-browser-compatibility ") doesn't seem particularly helpful in addressing the warning, telling us what we should be doing but not what to do to get rid of the warning.
Upvotes: 24