Skip to content

Commit 0b18cfc

Browse files
committed
feat(@angular/build): expand browser support policy to widely available Baseline
This commit includes a Baseline widely-available date which is hard-coded in `buid_vars.bzl` and used to generate a `.browserslistrc` file at build-time. Using a browser outside of Angular's minimum defined browser set is still allowed as we expect that _most_ of the time this will work just fine. However, we log a warning to be clear to users that they are outside Angular's supported browserset. I've currently pinned Angular to the March 31st baseline, but this will likely be updated again as we get closer to the v20 release. The current set of browsers generated are: ``` Chrome >= 107 ChromeAndroid >= 107 Edge >= 107 Firefox >= 104 FirefoxAndroid >= 104 Safari >= 16 iOS >= 16 ```
1 parent f50b578 commit 0b18cfc

File tree

5 files changed

+70
-23
lines changed

5 files changed

+70
-23
lines changed

constants.bzl

+7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ ANGULAR_FW_VERSION = "^20.0.0-next.0"
88
ANGULAR_FW_PEER_DEP = "^20.0.0 || ^20.0.0-next.0"
99
NG_PACKAGR_PEER_DEP = "^20.0.0 || ^20.0.0-next.0"
1010

11+
# Baseline widely-available date which defines Angular's browser support.
12+
# This date serves as the source of truth for the Angular CLI's default
13+
# browser set used to determine what downleveling is necessary.
14+
#
15+
# See: https://web.dev/baseline
16+
BASELINE_DATE = "2025-03-31"
17+
1118
SNAPSHOT_REPOS = {
1219
"@angular/cli": "angular/cli-builds",
1320
"@angular/pwa": "angular/angular-pwa-builds",

modules/testing/builder/projects/hello-world-app/.browserslistrc

-4
This file was deleted.

packages/angular/build/BUILD.bazel

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
load("@devinfra//bazel/api-golden:index_rjs.bzl", "api_golden_test_npm_package")
22
load("@npm2//:defs.bzl", "npm_link_all_packages")
3+
load("//:constants.bzl", "BASELINE_DATE")
4+
load("//packages/angular/build/tools/baseline_browserslist:baseline_browserslist.bzl", "baseline_browserslist")
35
load("//tools:defaults2.bzl", "copy_to_bin", "jasmine_test", "npm_package", "ts_project")
46
load("//tools:ts_json_schema.bzl", "ts_json_schema")
57

@@ -39,6 +41,12 @@ copy_to_bin(
3941
srcs = glob(["**/schema.json"]),
4042
)
4143

44+
baseline_browserslist(
45+
name = "angular_browserslist",
46+
out = ".browserslistrc",
47+
baseline = BASELINE_DATE,
48+
)
49+
4250
RUNTIME_ASSETS = glob(
4351
include = [
4452
"src/**/schema.json",
@@ -49,6 +57,7 @@ RUNTIME_ASSETS = glob(
4957
) + [
5058
"builders.json",
5159
"package.json",
60+
":angular_browserslist",
5261
]
5362

5463
ts_project(

packages/angular/build/src/builders/application/tests/behavior/browser-support_spec.ts

+28-8
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
8484
});
8585

8686
it('warns when IE is present in browserslist', async () => {
87-
await harness.appendToFile(
87+
await harness.writeFile(
8888
'.browserslistrc',
8989
`
90-
IE 9
91-
IE 11
92-
`,
90+
IE 9
91+
IE 11
92+
`,
9393
);
9494

9595
harness.useTarget('build', {
@@ -102,10 +102,30 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
102102
expect(logs).toContain(
103103
jasmine.objectContaining({
104104
level: 'warn',
105-
message:
106-
`One or more browsers which are configured in the project's Browserslist ` +
107-
'configuration will be ignored as ES5 output is not supported by the Angular CLI.\n' +
108-
'Ignored browsers: ie 11, ie 9',
105+
message: jasmine.stringContaining('ES5 output is not supported'),
106+
}),
107+
);
108+
109+
// Don't duplicate the error.
110+
expect(logs).not.toContain(
111+
jasmine.objectContaining({
112+
message: jasmine.stringContaining("fall outside Angular's browser support"),
113+
}),
114+
);
115+
});
116+
117+
it("warns when targeting a browser outside Angular's minimum support", async () => {
118+
await harness.writeFile('.browserslistrc', 'Chrome >= 100');
119+
120+
harness.useTarget('build', BASE_OPTIONS);
121+
122+
const { result, logs } = await harness.executeOnce();
123+
expect(result?.success).toBeTrue();
124+
125+
expect(logs).toContain(
126+
jasmine.objectContaining({
127+
level: 'warn',
128+
message: jasmine.stringContaining("fall outside Angular's browser support"),
109129
}),
110130
);
111131
});

packages/angular/build/src/utils/supported-browsers.ts

+26-11
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,55 @@
77
*/
88

99
import browserslist from 'browserslist';
10+
import * as path from 'node:path';
1011

1112
export function getSupportedBrowsers(
1213
projectRoot: string,
1314
logger: { warn(message: string): void },
1415
): string[] {
15-
browserslist.defaults = [
16-
'last 2 Chrome versions',
17-
'last 1 Firefox version',
18-
'last 2 Edge major versions',
19-
'last 2 Safari major versions',
20-
'last 2 iOS major versions',
21-
'last 2 Android major versions',
22-
'Firefox ESR',
23-
];
16+
// Read the browserslist configuration containing Angular's browser support policy.
17+
const angularBrowserslist = browserslist(undefined, {
18+
path: path.join(require.resolve('../../.browserslistrc')),
19+
});
20+
21+
// Use Angular's configuration as the default.
22+
browserslist.defaults = angularBrowserslist;
23+
24+
// Get the minimum set of browser versions supported by Angular.
25+
const minimumBrowsers = new Set(angularBrowserslist);
2426

2527
// Get browsers from config or default.
2628
const browsersFromConfigOrDefault = new Set(browserslist(undefined, { path: projectRoot }));
2729

2830
// Get browsers that support ES6 modules.
2931
const browsersThatSupportEs6 = new Set(browserslist('supports es6-module'));
3032

33+
const nonEs6Browsers: string[] = [];
3134
const unsupportedBrowsers: string[] = [];
3235
for (const browser of browsersFromConfigOrDefault) {
3336
if (!browsersThatSupportEs6.has(browser)) {
37+
// Any browser which does not support ES6 is explicitly ignored, as Angular will not build successfully.
3438
browsersFromConfigOrDefault.delete(browser);
39+
nonEs6Browsers.push(browser);
40+
} else if (!minimumBrowsers.has(browser)) {
41+
// Any other unsupported browser we will attempt to use, but provide no support for.
3542
unsupportedBrowsers.push(browser);
3643
}
3744
}
3845

39-
if (unsupportedBrowsers.length) {
46+
if (nonEs6Browsers.length) {
4047
logger.warn(
4148
`One or more browsers which are configured in the project's Browserslist configuration ` +
4249
'will be ignored as ES5 output is not supported by the Angular CLI.\n' +
43-
`Ignored browsers: ${unsupportedBrowsers.join(', ')}`,
50+
`Ignored browsers:\n${nonEs6Browsers.join(', ')}`,
51+
);
52+
}
53+
54+
if (unsupportedBrowsers.length) {
55+
logger.warn(
56+
`One or more browsers which are configured in the project's Browserslist configuration ` +
57+
"fall outside Angular's browser support for this version.\n" +
58+
`Unsupported browsers:\n${unsupportedBrowsers.join(', ')}`,
4459
);
4560
}
4661

0 commit comments

Comments
 (0)