Angular 20 到 21 升级:实用生存指南

发布: (2025年12月13日 GMT+8 15:48)
6 min read
原文: Dev.to

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() 调用,除非你传入了配置选项(例如 withInterceptorswithFetch)。
  • 在更改后验证拦截器的执行顺序。

无 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-expandedrole="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(推荐)。

6. 可选:切换到无 Zone

ng generate @angular/core:zoneless-migration

这属于 “Agentic” 领域。请参考我们的 MCP 指南,了解如何让 AI 处理这类复杂重构。

结论

Angular 21 是一次 “全新起点” 的发布。它抛弃了过去十年的负担——Zone、Karma 与繁重的模块模式,以与 Svelte、Solid 等现代框架竞争。升级过程可能因测试变更而颠簸,但最终得到的——更快、更简洁、基于信号的框架——绝对值得。

Back to Blog

相关文章

阅读更多 »

迁移 Angular 20 到 21:指南

一本直截了当的指南,帮助将 Angular 20 升级到 21。涵盖了 Karma 的移除、默认的 Zoneless 模式、自动 HttpClient 以及如何修复……