迁移 Angular 20 到 21:指南
Source: Dev.to
一个不拐弯的指南,帮助你从 Angular 20 升级到 21。涵盖了 Karma 的移除、默认的 Zoneless 模式、新的自动 HttpClient 以及如何修复破损的构建。
如果你以为 Angular 20 已经是一次大变动,那欢迎来到 Angular 21。
当 20 版致力于稳定 Signals 时,21 版提升了开发者体验:zone.js 成为可选,Karma 已经死亡,RxJS 似乎正被慢慢取代。这不仅仅是一次升级;它感觉像是全新的生态系统。
阻止一切的关键点
在运行 ng update 之前,请注意如果你依赖以下遗留模式,构建很可能会失败。
1. Karma 的灭绝事件(Vitest 成为默认)
对许多团队来说,最直接的冲击是 ng test。Angular 21 已正式用 Vitest 替代 Karma 作为默认测试运行器。
会破坏的地方
- 如果你有自定义的
karma.conf.js或依赖特定的 Karma 插件/报告器,你的测试套件现在已经是遗留代码。
解决方案
- 新项目: 从一开始就使用 Vitest。它更快、更简洁,并且使用 Vite。
- 已有项目: 你并不需要立刻切换,但终点已近。CLI 会不断提醒你。
- 迁移: 运行
ng generate @angular/core:karma-to-vitest尝试自动迁移。它会转换标准配置,但你在测试配置中对 Webpack 的自定义技巧需要手动改写为 Vite。
2. HttpClient “就在那里”
还记得在 app.config.ts 中添加 provideHttpClient() 或导入 HttpClientModule 吗?
变化
HttpClient 现在默认注入到根注入器中。
会破坏的地方
- 那些模拟
HttpClient并假设它不存在的测试可能会失败。 - 如果你在混合 NgModule/Standalone 应用中依赖
HttpClientModule来实现拦截器的复杂顺序,可能会看到细微的行为变化。
解决方案
除非你传递配置选项(如 withInterceptors 或 withFetch),否则删除显式的 provideHttpClient() 调用。清理你的配置,同时检查拦截器的执行顺序。
3. zone.js 已经离开(针对新应用)
使用 ng new 创建的新应用默认不再包含 zone.js。
会破坏的地方
对已有应用(目前仍然)没有影响。你的 polyfills.ts 仍会导入 Zone。
警告
如果你把 v21 的新教程代码复制粘贴到已有的 v20 应用中,可能会假设使用了 Zoneless 行为(更少使用 ChangeDetectorRef,依赖 Signals)。在不了解两种范式的情况下混用,可能会产生 “changed after checked” 错误或视图不更新的问题。
新玩具:你真的会用到的特性
修复构建后,v21 为开发体验(DX)带来了惊人的提升。
1. Signal Forms(实验但已稳定)
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])
});
// 直接像 signals 一样访问值!
console.log(loginForm.value().email);
为什么使用
默认类型安全,不需要精通 RxJS。
状态
实验性。可以在新功能中使用,但暂时不必重写已有的业务流程。
2. Angular Aria(开发者预览)
Opción 1
Opción 2
一个 “headless” 原语库,用于无障碍支持,省去手动管理 aria-expanded、role="button" 等属性的需求。
3. 模板中的正则表达式
@if (email() | match: /@company\.com$/) {
Empleado
}
允许在模板中直接使用正则字面量,适用于无需辅助函数的条件逻辑。
升级检查清单
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. 运行诊断
Angular 21 包含更智能的诊断。留意关于 ngClass(正逐步废弃,推荐使用 [class.my‑class])的警告,以及迁移到 standalone 的机会。
5. 检查你的测试
运行 ng test。如果炸了,决定:
- 路线 A: 保留 Karma(如果被移除,手动添加
@angular/build:karma)。 - 路线 B: 迁移到 Vitest(推荐)。
6. 可选:走向 Zoneless
如果你够大胆,执行实验性迁移:
ng generate @angular/core:zoneless-migration
注意
这属于 “代理” 领域。请参考我们的 Guía MCP 了解如何让 AI 处理这类复杂重构。
总结
Angular 21 是一次 “从头再来” 的发布。它摆脱了过去十年的负担(Zone、Karma、Modules),以与 Svelte、Solid 等现代框架竞争。虽然因为测试方面的改动升级过程可能会有点波折,但最终——一个更快、更简洁、由 signals 驱动的框架——绝对值得投入。