Angular 20 到 21 升级:实用生存指南
Source: Dev.to
介绍
一份简明扼要的指南,帮助你从 Angular 20 升级到 21。内容涵盖了 Karma 的移除、全新的默认无 Zone 模式、自动注入 HttpClient,以及如何修复构建时的破坏性问题。
如果你觉得 Angular 20 已经是一次大变动,那么欢迎来到 Angular 21。20 版侧重于信号(Signals)的稳定,21 版则移除了旧的守护。所谓的 “Angular 方式” 已经根本改变:zone.js 成为可选,Karma 已不复存在,RxJS 正在慢慢退居边缘。这不仅是一次更新,更是一个全新生态系统。下面列出会出现的破坏以及对应的解决方案。
测试变更:Karma → Vitest
会破坏的地方
- 自定义的
karma.conf.js或依赖特定 Karma 插件/报告器的配置会导致失败。 - 模拟缺失
HttpClient的测试也可能出错(参见 HttpClient 部分)。
解决方案
-
新项目:默认提供 Vitest。它更快、更简洁,基于 Vite。
-
已有项目:暂时仍可继续使用 Karma,但 CLI 会给出警告。
-
迁移:运行脚本
ng generate @angular/core:karma-to-vitest它会自动转换标准配置。测试环境中自定义的 Webpack hack 需要手动改写为 Vite 兼容的写法。
HttpClient 变更
变更内容
HttpClient 现在默认注入到根注入器。除非需要自定义配置,否则不再需要在 app.config.ts 中添加 provideHttpClient() 或导入 HttpClientModule。
会破坏的地方
- 期望
HttpClient不存在的测试可能会失败。 - 在混合使用 NgModule 与独立组件的应用中,拦截器的顺序可能出现细微行为变化。
解决方案
- 移除显式的
provideHttpClient()调用,除非你传入了配置选项(例如withInterceptors或withFetch)。 - 在更改后验证拦截器的执行顺序。
无 Zone 模式(zone.js 可选)
变更内容
使用 ng new 创建的新应用默认不再引入 zone.js。
会破坏的地方
- 现有应用仍会从
polyfills.ts中导入zone.js(不会立即报错)。 - 将新 v21 教程中的代码复制粘贴到 v20 应用时,可能会假设是无 Zone 行为,导致 “changed after checked” 错误或视图不更新。
建议
在混用两种范式之前,先了解基于 Zone 与无 Zone 的变更检测之间的差异。
新特性
使用 Signals 的响应式表单
import { form, field } from '@angular/forms/signals';
import { Validators } from '@angular/forms';
// 定义响应式表单模型
const loginForm = form({
email: field('', [Validators.required, Validators.email]),
password: field('', [Validators.required])
});
// 直接以 signal 方式访问值!
console.log(loginForm.value().email);
- 为何使用:默认类型安全,无需深入了解 RxJS。
- 状态:实验性——适合新功能,但暂不建议重写大量已有业务。
无头可访问性原语
<Option 1>
<Option 2>
不必手动管理 aria-expanded 与 role="button",使用这些指令即可处理可访问性逻辑,同时自行定义样式。
模板中的正则字面量
@if (email() | match: /@company\.com$/) {
Employee
}
小而强大:现在可以在模板中直接使用正则字面量,适合无需辅助函数的简单 @if 逻辑。
升级步骤
1. 备份
提交所有更改。真的要认真对待。
2. 更新全局 CLI
# 可选:先卸载旧的全局版本以避免冲突
npm uninstall -g @angular/cli
# 验证 npm 缓存
npm cache verify
# 安装最新的全局 CLI 版本
npm install -g @angular/cli@latest
3. 更新本地项目
ng update @angular/cli@21 @angular/core@21
4. 运行诊断
查找已废弃的用法,例如 ngClass(已软废弃,建议使用 [class.my‑class]),并识别可进行独立组件迁移的机会。
5. 检查你的测试
ng test
- 如果炸了,决定:
- 路径 A – 保留 Karma(如果被移除,手动添加
@angular/build:karma)。 - 路径 B – 迁移到 Vitest(推荐)。
- 路径 A – 保留 Karma(如果被移除,手动添加
6. 可选:切换到无 Zone
ng generate @angular/core:zoneless-migration
这属于 “Agentic” 领域。请参考我们的 MCP 指南,了解如何让 AI 处理这类复杂重构。
结论
Angular 21 是一次 “全新起点” 的发布。它抛弃了过去十年的负担——Zone、Karma 与繁重的模块模式,以与 Svelte、Solid 等现代框架竞争。升级过程可能因测试变更而颠簸,但最终得到的——更快、更简洁、基于信号的框架——绝对值得。