Angular 版本兼容性完全指南:Node.js、TypeScript、RxJS 与浏览器支持策略详解
本文以 Angular 官方文档中心(本仓库
adev/src/content/reference/)中的版本兼容性页面为主体,系统解读 Angular 22/21/20 等各主版本对 Node.js、TypeScript、RxJS 的具体版本要求与半区间语义,梳理 v9 之前「Angular 与 CLI 不同步」的历史特殊性、以 Baseline「widely available」为准的浏览器支持策略,并完整演示 CLI 与非 CLI 两类项目如何正确加载 polyfills(含 zone.js 的启动优化开关)。读完本文,你可以对照版本表校验自己的开发环境、理解每个 semver 区间表达式的含义,并能为老旧浏览器项目搭建出一套可落地的 polyfill 加载方案。
文档定位:这张兼容性表解决什么问题
版本兼容性页面是 Angular 官方文档的「环境体检表」。Angular 框架对运行时依赖的版本要求非常严格:Node.js 负责构建工具链与 CLI 的运行,TypeScript 是源码编译的类型编译器,RxJS 则是 Angular 响应式编程模型的底层依赖。三者任一版本不匹配,都会导致安装解析失败(peerDependencies 冲突)、AOT 编译报错或运行时行为异常。
该页面因此给出了三组权威数据:
- 当前处于支持窗口内的 Angular 各版本与其依赖版本要求;
- 已退出长期支持(LTS)的版本及其当时的依赖要求(仅作历史参考);
- Angular 对主流浏览器的支持策略,以及为兼容旧浏览器而需要加载的 polyfills 方案。
其中提到的"活跃支持版本"判定依据,出自同目录下的 releases.md 支持策略文档。
版本区间表达式:看懂 ^、>=x <y 与 ||
在解读下面的表格前,先统一理解 Angular 文档使用的版本区间语法(遵循 npm semver 约定):
^20.19.0表示>=20.19.0 <21.0.0,即允许该大版本内的所有后续版本,但不会跨入下一个主版本;>=6.0.0 <6.1.0表示一个显式的闭半区间,只允许6.0.x系列;||表示"或",列出多个可同时接受的候选区间。例如^22.22.3 || ^24.15.0 || ^26.0.0意味着 Node.js 只要落在其中任意一个区间内即可通过校验。
需要特别说明的是,TypeScript 列中的写法(如 >=6.0.0 <6.1.0)描述的是 @angular/compiler-cli 等包所能接受的 TypeScript 编译器版本范围,超出下限或上限都会导致类型检查或 AOT 编译行为不一致。这也是为什么版本表同时把"下限"和"上限"都写清楚——TypeScript 的小版本之间也存在破坏性变更风险。
活跃支持版本:当前受维护的 Angular 与依赖矩阵
下表覆盖处于活跃支持窗口的 Angular 版本(截至本仓库文档维护时的快照)。其中每个小版本列出的 Node.js 候选区间通常与 LTS 发布节奏挂钩,工程上建议直接选用对应大版本线中最新的 LTS:
| Angular | Node.js | TypeScript | RxJS |
|---|---|---|---|
| 22.0.x | ^22.22.3 || ^24.15.0 || ^26.0.0 | >=6.0.0 <6.1.0 | ^6.5.3 || ^7.4.0 |
| 21.0.x || 21.1.x || 21.2.x | ^20.19.0 || ^22.12.0 || ^24.0.0 | >=5.9.0 <6.0.0 | ^6.5.3 || ^7.4.0 |
| 20.2.x || 20.3.x | ^20.19.0 || ^22.12.0 || ^24.0.0 | >=5.8.0 <6.0.0 | ^6.5.3 || ^7.4.0 |
| 20.0.x || 20.1.x | ^20.19.0 || ^22.12.0 || ^24.0.0 | >=5.8.0 <5.9.0 | ^6.5.3 || ^7.4.0 |
这张表有两个值得注意的细节:
- RxJS 列几乎全部一致(
^6.5.3 || ^7.4.0)。这是因为 RxJS 7 是 Angular 自 v13 起主推的响应式库版本,而^6.5.3是为尚未完成迁移的老项目保留的向下兼容路径;支持窗口内的版本不强制要求升级 RxJS 主版本,但新项目应直接使用 RxJS 7。 - 同一主版本的不同小版本,TypeScript 上限会逐步放开。对比 20.0.x 的
>=5.8.0 <5.9.0与 20.2.x/20.3.x 的>=5.8.0 <6.0.0可以看出,Angular 会在小版本中扩大对更新 TypeScript 的支持(而不是收窄),这正是 releases.md 中"minor 版本扩展 peerDependencies 支持范围"策略的体现。
仓库本身就是一个很好的佐证样本:根目录 package.json 声明当前主版本为 22.2.0-next.4,其依赖中 typescript: 6.0.3、rxjs: ^7.0.0、zone.js: 0.16.2,与上表 v22 行"TypeScript >=6.0.0 <6.1.0、RxJS ^7.4.0"的约束方向完全一致。
已退出 LTS 的版本:历史参考矩阵
Angular 每个大版本通常支持 24 个月(活跃 12 个月 + LTS 12 个月),详见 releases.md 支持窗口说明。下表覆盖已退出 LTS 的版本。文档明确提示:这些信息在各版本退出 LTS 时是正确的,此后不作任何持续保证,仅用于帮助历史项目回溯"当时官方推荐的环境配置"。
| Angular | Node.js | TypeScript | RxJS |
|---|---|---|---|
| 19.2.x | ^18.19.1 || ^20.11.1 || ^22.0.0 | >=5.5.0 <5.9.0 | ^6.5.3 || ^7.4.0 |
| 19.1.x | ^18.19.1 || ^20.11.1 || ^22.0.0 | >=5.5.0 <5.8.0 | ^6.5.3 || ^7.4.0 |
| 19.0.x | ^18.19.1 || ^20.11.1 || ^22.0.0 | >=5.5.0 <5.7.0 | ^6.5.3 || ^7.4.0 |
| 18.1.x || 18.2.x | ^18.19.1 || ^20.11.1 || ^22.0.0 | >=5.4.0 <5.6.0 | ^6.5.3 || ^7.4.0 |
| 18.0.x | ^18.19.1 || ^20.11.1 || ^22.0.0 | >=5.4.0 <5.5.0 | ^6.5.3 || ^7.4.0 |
| 17.3.x | ^18.13.0 || ^20.9.0 | >=5.2.0 <5.5.0 | ^6.5.3 || ^7.4.0 |
| 17.1.x || 17.2.x | ^18.13.0 || ^20.9.0 | >=5.2.0 <5.4.0 | ^6.5.3 || ^7.4.0 |
| 17.0.x | ^18.13.0 || ^20.9.0 | >=5.2.0 <5.3.0 | ^6.5.3 || ^7.4.0 |
| 16.1.x || 16.2.x | ^16.14.0 || ^18.10.0 | >=4.9.3 <5.2.0 | ^6.5.3 || ^7.4.0 |
| 16.0.x | ^16.14.0 || ^18.10.0 | >=4.9.3 <5.1.0 | ^6.5.3 || ^7.4.0 |
| 15.1.x || 15.2.x | ^14.20.0 || ^16.13.0 || ^18.10.0 | >=4.8.2 <5.0.0 | ^6.5.3 || ^7.4.0 |
| 15.0.x | ^14.20.0 || ^16.13.0 || ^18.10.0 | ~4.8.2 | ^6.5.3 || ^7.4.0 |
| 14.2.x || 14.3.x | ^14.15.0 || ^16.10.0 | >=4.6.2 <4.9.0 | ^6.5.3 || ^7.4.0 |
| 14.0.x || 14.1.x | ^14.15.0 || ^16.10.0 | >=4.6.2 <4.8.0 | ^6.5.3 || ^7.4.0 |
| 13.3.x || 13.4.x | ^12.20.0 || ^14.15.0 || ^16.10.0 | >=4.4.3 <4.7.0 | ^6.5.3 || ^7.4.0 |
| 13.1.x || 13.2.x | ^12.20.0 || ^14.15.0 || ^16.10.0 | >=4.4.3 <4.6.0 | ^6.5.3 || ^7.4.0 |
| 13.0.x | ^12.20.0 || ^14.15.0 || ^16.10.0 | ~4.4.3 | ^6.5.3 || ^7.4.0 |
| 12.2.x | ^12.14.0 || ^14.15.0 | >=4.2.3 <4.4.0 | ^6.5.3 || ^7.0.0 |
| 12.1.x | ^12.14.0 || ^14.15.0 | >=4.2.3 <4.4.0 | ^6.5.3 |
| 12.0.x | ^12.14.0 || ^14.15.0 | ~4.2.3 | ^6.5.3 |
| 11.2.x | ^10.13.0 || ^12.11.0 | >=4.0.0 <4.2.0 | ^6.5.3 |
| 11.1.x | ^10.13.0 || ^12.11.0 | >=4.0.0 <4.2.0 | ^6.5.3 |
| 11.0.x | ^10.13.0 || ^12.11.0 | ~4.0.0 | ^6.5.3 |
| 10.2.x | ^10.13.0 || ^12.11.0 | >=3.9.0 <4.1.0 | ^6.5.3 |
| 10.1.x | ^10.13.0 || ^12.11.0 | >=3.9.0 <4.1.0 | ^6.5.3 |
| 10.0.x | ^10.13.0 || ^12.11.0 | ~3.9.0 | ^6.5.3 |
| 9.1.x | ^10.13.0 || ^12.11.0 | >=3.6.0 <3.9.0 | ^6.5.3 |
| 9.0.x | ^10.13.0 || ^12.11.0 | >=3.6.0 <3.8.0 | ^6.5.3 |
从这张历史表可以看到几个清晰的演进轨迹:
- TypeScript 上限持续上移:v9 时代只能使用 TS 3.6–3.8,到 v19 已支持 TS 5.x,再到当前 v22 已进入 TS 6.0 时代;
- Node.js 候选区间与大版本 LTS 生命周期绑定:每个 Angular 主版本一般兼容 2–3 个相邻的 Node LTS 主版本,且随 Angular 新主版本发布逐步加入更新的 Node;
- RxJS 从 v13 起统一支持
^6.5.3 || ^7.x,因此 RxJS 7 已成为事实标准配置。
注意表中出现的 ~4.8.2 这类写法表示"约等于"区间(>=4.8.2 <4.9.0),Angular 在某个新主版本刚发布时往往先用 ~ 收紧 TypeScript 范围,随后在小版本中放行(如 15.1.x 即改为 >=4.8.2 <5.0.0)。
v9 之前:Angular 与 Angular CLI 版本不同步
直到 Angular v9 为止,Angular 框架主版本与 Angular CLI 主版本是各自独立发布的,因此版本矩阵多出一列 CLI 版本。从 v7(约对应 2017 年)开始两者主版本才对齐——releases.md 同样确认了这一点:从 v7 起使用 CLI 开发 Angular 应用时,@angular/core 与 CLI 的版本需要保持一致。
| Angular | Angular CLI | Node.js | TypeScript | RxJS |
|---|---|---|---|---|
| 8.2.x | 8.2.x || 8.3.x | ^10.9.0 | >=3.4.2 <3.6.0 | ^6.4.0 |
| 8.0.x || 8.1.x | 8.0.x || 8.1.x | ^10.9.0 | ~3.4.2 | ^6.4.0 |
| 7.2.x | 7.2.x || 7.3.x | ^8.9.0 || ^10.9.0 | >=3.1.3 <3.3.0 | ^6.0.0 |
| 7.0.x || 7.1.x | 7.0.x || 7.1.x | ^8.9.0 || ^10.9.0 | ~3.1.3 | ^6.0.0 |
| 6.1.x | 6.1.x || 6.2.x | ^8.9.0 | >=2.7.2 <3.0.0 | ^6.0.0 |
| 6.0.x | 6.0.x | ^8.9.0 | ~2.7.2 | ^6.0.0 |
| 5.2.x | 1.6.x || 1.7.x | ^6.9.0 || ^8.9.0 | >=2.4.2 <2.7.0 | ^5.5.0 |
| 5.0.x || 5.1.x | 1.5.x | ^6.9.0 || ^8.9.0 | ~2.4.2 | ^5.5.0 |
| 4.2.x || 4.3.x || 4.4.x | 1.4.x | ^6.9.0 || ^8.9.0 | >=2.1.6 <2.5.0 | ^5.0.1 |
| 4.2.x || 4.3.x || 4.4.x | 1.3.x | ^6.9.0 | >=2.1.6 <2.5.0 | ^5.0.1 |
| 4.0.x || 4.1.x | 1.0.x || 1.1.x || 1.2.x | ^6.9.0 | >=2.1.6 <2.4.0 | ^5.0.1 |
| 2.x | - | ^6.9.0 | >=1.8.0 <2.2.0 | ^5.0.1 |
注意两个冷知识:
- Angular 2.x 行的 CLI 列为
-,因为彼时 Angular(2.x)仍与 AngularJS 时代遗留的工具链并存,尚未形成统一 CLI; - Angular 4.x 时代 CLI 仍停留在 1.x,会出现"同一 Angular 小版本可搭配多个 CLI 小版本"的组合(如 4.2–4.4 可配 CLI 1.3 或 1.4)。这类"一对多"在今天已不存在——v7 之后 Angular 与 CLI 严格同步。
浏览器支持策略:以 Baseline "widely available" 为准
Angular 对浏览器的支持并不采用"固定某几个浏览器版本号"的静态清单,而是动态跟随 Web 平台社区定义的 Baseline 标准中的 "widely available" 等级。每个 Angular 主版本在临近发布时选定一个日期,凡是在该日期前后 30 个月(2.5 年)内、于 Baseline 核心浏览器集合(Chrome、Edge、Firefox、Safari)中发布过的浏览器版本,都在支持范围内;该集合的目标是覆盖约 95% 的 Web 用户。
当前主版本对应的 Baseline 日期如下表所示(表中链接指向可交互的浏览器集合查看器,读者可据此展开到具体的浏览器版本明细):
| Angular | Baseline Date | Browser Set |
|---|---|---|
| v22 | 2026-05-07 | v22 对应日期下的浏览器集合 |
| v21 | 2025-10-20 | v21 对应日期下的浏览器集合 |
| v20 | 2025-04-30 | v20 对应日期下的浏览器集合 |
而 v20 之前的 Angular 版本不支持这种动态策略,官方直接维护了如下静态浏览器支持表:
| Browser | Supported versions |
|---|---|
| Chrome | 最近 2 个大版本 |
| Firefox | 最新版 + 扩展支持版(ESR) |
| Edge | 最近 2 个大版本 |
| Safari | 最近 2 个大版本 |
| iOS | 最近 2 个大版本 |
| Android | 最近 2 个大版本 |
这组规则的历史含义是:"支持 Chrome/Firefox/Edge/Safari/iOS/Android 各自最近的两个主版本"。如果你的目标用户仍然集中在旧浏览器上,就需要靠下一节的 polyfills 来补齐平台能力差异。
Polyfills:为什么需要、能解决什么
Angular 建立在 Web 平台最新标准之上(现代类语法、DOM API、异步原语等)。当目标浏览器范围很大时,必然存在部分浏览器不支持某些新特性的情况,弥补手段就是在应用启动前加载 polyfill 脚本。
关于 polyfills,文档给出两点明确提醒:
- 文档建议的 polyfill 清单只覆盖运行完整 Angular 应用所需的核心能力;如果你的应用还使用了清单之外的新特性,需要自行追加对应的 polyfill;
- polyfills 无法把老旧缓慢的浏览器"魔法般"变成现代快速浏览器——它只补齐缺失的 API,不提升旧引擎本身的执行性能。
CLI 项目如何启用 polyfills
若使用 Angular CLI 管理项目(CLI 能力概览见 tools/cli 相关文档),polyfill 的接入方式是配置 browser 与 test 两个 builder 的 polyfills 选项(builder 机制详见 CLI Builder 文档)。该选项有两种合法取值:
- 一个文件的完整路径,例如
src/polyfills.ts(相对当前工作区的路径); - 相对当前工作区的模块标识符,例如直接写包名
zone.js。
如果走"创建 TypeScript 文件"的方案,务必记得把这个文件加入 tsconfig 的 files 数组,否则编译时该文件不会被纳入类型检查与打包。官方建议的配置形态如下:
{
"extends": "./tsconfig.json",
"compilerOptions": {
...
},
"files": [
"src/main.ts",
"src/polyfills.ts"
]
...
}
polyfills 选项在 angular.json 中的实际形态,可以参考本仓库集成测试项目 integration/cli-hello-world/angular.json:它的 browser target 使用 "polyfills": ["zone.js"] 直接以模块标识符引入 zone.js,test target 则使用 "polyfills": ["zone.js", "zone.js/testing"] 额外追加测试辅助。这说明数组中每一项都可以是"路径"或"模块名",且 test 与 build 的 polyfill 集合可以独立配置。
各构建器常见约定
application/browserbuilder:polyfills数组在构建产物中会成为独立的 script 文件,保证在应用主 bundle 之前按序执行;testbuilder(Karma):polyfills数组会在测试启动前加载,其中zone.js/testing负责提供测试用的 zone 断言 API;- Angular 从 v15 起默认在
src/polyfills.ts中仅保留zone.js导入,其余按需由你添加。
非 CLI 项目的 Polyfill 接入(index.html 直引法)
不使用 CLI 时,Angular 无法替你处理 polyfill 的打包顺序,需要直接把脚本加到宿主页面 index.html 中。官方示例给出了一个极具参考价值的完整段落结构:
<!-- pre-zone polyfills -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script>
/**
* you can configure some zone flags which can disable zone interception for some
* asynchronous activities to improve startup performance - use these options only
* if you know what you are doing as it could result in hard to trace down bugs.
*/
// __Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
// __Zone_disable_on_property = true; // disable patch onProperty such as onclick
// __zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
/*
* in Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for Edge.
*/
// __Zone_enable_cross_context_check = true;
</script>
<!-- zone.js required by Angular -->
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
<!-- application polyfills -->
这个模板的加载顺序本身就是关键:core-js(旧浏览器 API 补齐)→ 全局 zone 配置开关 → zone.js(Angular 变更检测的调度基础)→ 应用级 polyfill。zone.js 必须在任何应用代码之前执行,且所有 __Zone_* / __zone_symbol__* 配置必须早于 zone.js 加载生效。
zone.js 各开关在源码中的定义与用途
模板里被注释掉的几个全局 flag,其完整语义可以从本仓库 packages/zone.js/lib/zone.configurations.api.ts 中找到类型定义与设计说明:
__Zone_disable_requestAnimationFrame(定义见源码):置为true后 zone.js 将不再对requestAnimationFrame()做 monkey-patch。文档注释中的对比示例指出:默认情况下requestAnimationFrame的回调会运行在调度它的 zone 内;关闭 patch 后,回调将直接回到<root>zone 执行,requestAnimationFrame之外某些高频回调(如动画帧)不再经过 zone 的拦截与调度,从而降低变更检测触发的开销。__Zone_disable_on_property(定义见源码):置为true后 zone.js 不再 patchonclick、onload这类onProperty(DOM 事件属性)赋值。Angular 的事件绑定依赖 zone 感知事件来触发变更检测,关闭该项会显著减少被 zone 包装的 DOM 事件数量,但任何依赖该机制进行自动检测的场景都会失效。__zone_symbol__UNPATCHED_EVENTS(定义见源码):值为字符串数组,例如['scroll', 'mousemove']。命中名单的事件不会被 zone.js 包装,常用于排除高频或低价值事件(滚动、鼠标移动等),避免每次触发都引入 zone 调度开销。__Zone_enable_cross_context_check:用于 Edge 开发者工具场景——默认addEventListener会被 zone.js 包装,置为true后 zone.js 会绕过对 Edge 的 patch。它是特定于旧版 Edge 环境的防御性开关。
之所以注释里反复强调"仅在确定自己知道后果时使用",是因为关闭 zone 对某类异步任务的拦截,意味着与之相关的自动变更检测将不再发生,极易引发"界面不刷新"这类难以追踪的 bug。更稳妥的做法是优先考虑使用 Angular 的 provideZonelessChangeDetection / Signals 体系把对 zone 的依赖降到最低,而不是盲目关闭 patch。想深入了解 zone.js 覆盖的 API 范围,可阅读仓库内的 packages/zone.js/STANDARD-APIS.md。
自建非 CLI polyfill 清单的一般步骤
- 通过 web-platform 兼容性数据(如
caniuse)确认目标浏览器集合实际缺失的 API; - 为每一类缺失能力引入对应 polyfill(ES 语法降级常用
core-js,DOM 差异可用对应 shim); - 按"基础 shim → zone 配置 → zone.js → 应用"的顺序保证执行次序;
- 对 polyfill 文件使用
defer/async以外的常规加载方式,确保它在应用入口前同步执行完毕。
升级路径中的版本兼容性实践建议
结合 releases.md 的更新策略与本版本兼容性页,可以沉淀出几条落地准则:
- 先查表再动手:执行大版本升级前,用本表核对新版本对 Node.js 与 TypeScript 的上下限要求,避免装完依赖后才发现 peerDependencies 冲突;
- 尽量每次只跨越一个主版本:Angular 官方更新工具
ng update支持"目标版本受支持、且当前版本与目标版本相差不超过一个主版本"的升级。跨多个主版本时应逐级推进(如 v19 → v20 → v21 → v22),每级都重新校验 Node/TypeScript 环境; - 把小版本当"扩围窗口"使用:同一主版本内后续小版本通常会放行更新的 TypeScript(参见 20.x 系列的变化),因此不必因为 TypeScript 新版本发布就急着跨大版本升级;
- 浏览器支持按需取舍:如果用户群已进入"widely available"区间(近 30 个月内更新的现代浏览器),可以显著裁剪 polyfill 体积;只有当确实需要服务旧浏览器(Chrome/Edge 老两个版本以外、Safari 旧版等)时才引入对应 shim。
小结
本仓库的 版本兼容性文档 是一份"以兼容性矩阵为中心、以浏览器策略与 polyfill 为落地手段"的运维型参考。它回答了三类高频问题:某 Angular 版本到底需要什么样的 Node/TypeScript/RxJS?Angular 官方到底承诺支持哪些浏览器?当目标浏览器过旧时,如何正确地把 polyfill(尤其是 zone.js)装进项目?结合仓库内 releases.md 的版本生命周期策略、zone.js 配置类型源码 以及 integration 示例工程 的配置写法,开发者在搭建新环境、规划升级或适配老旧浏览器时,都能快速定位出"当前该用什么、边界在哪里、不匹配会怎样"。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00