javascriptangularbrowserslist

Browserslist not honored in Angular 15


I want to compile an Angular 15 project which should run on Chrome 75 for Android.

Angular's documentation claims that this is browser is not supported. However the documentation also claims that it has support for browserslist to specify compatability.

Does that mean that the browserslist can only be used to further limit the supported browsers and not increase the support? I don't find Angular's documentation very clear on this point.

Here's an example project where the problem can be seen:

First we create a new project and build it:

$ ng new foo --routing --style css
$ cd foo
$ npm ci
$ npm run build

The js output contains the optional chaining operator, which is not supported in Chrome 75:

$ grep -oE '.{20}\\?\\..{20}' dist/foo/main.*.js
egate:r}=si;return r?.setTimeout?r.setTime
egate:t}=si;return(t?.clearTimeout||clearT
on td(e){return ne(e?.lift)}function Se(e)
on sd(e){return ne(e?.then)}function ad(e)
...

To ensure compatibility we try to use the browserslist support in Angular:

$ ng generate config browserslist
$ echo 'ChromeAndroid >= 75' >> .browserslistrc
$ cat .browserslistrc
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries

# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support

# You can see what browsers were selected by your queries by running:
#   npx browserslist

last 2 Chrome versions
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
ChromeAndroid >= 75

Building again, we see that the built javascript still uses the optional chaining operator:

$ npm run build
$ grep -oE '.{20}\\?\\..{20}' dist/foo/main.*.js
egate:r}=si;return r?.setTimeout?r.setTime
egate:t}=si;return(t?.clearTimeout||clearT
on td(e){return ne(e?.lift)}function Se(e)
on sd(e){return ne(e?.then)}function ad(e)
...

I would at least expect a warning or error from Angular that it will not respect my browserslist, if that is the case.


Solution

  • I solved my problem by running babel manually on the dist folder after Angular is done building:

    {
      "presets": [
        [
          "@babel/preset-env",
          {
            "useBuiltIns": "entry",
            "corejs": "3.29.1"
          }
        ]
      ]
    }