手记

Angular v18 正式发布了!

今天我们非常激动地分享 Angular 发展历程中的下一个重要里程碑!在过去三个版本中,我们已经引入了许多新功能和改进。这次的重点是打磨之前发布的成果,将许多新的 API 升级至稳定状态,满足了开发者常见的需求,并实验性地发布了路线图上最令人期待的项目之一:无区(zoneless)变化检测。

这次更新的重点包括:

  • 实验性支持无区变更检測
  • Angular.dev 现已成为 Angular 开发者的新家
  • Material 3、惰性加载视图和内置控制流现已稳定,并融入了一系列改进
  • 服务器端渲染改进包括 i18n 水合支持、更好的调试、Angular Material 中的水合支持,以及由与 Google 搜索相同的库支持的事件回放功能 详情请参阅这篇博客文章

想快速了解情况,看看我们发布会的视频:

演变中的变化检测

历史上,一个名为 zone.js 的库一直负责触发 Angular 的变化检测。这个库带来了一些开发体验和性能上的缺点。多年来,我们已经努力了多年,希望能找到一种不依赖 zone.js 的 Angular 使用方法。我们非常激动地分享首个无 zone.js 实验性 API 功能。

你可以从今天开始尝试一下 Angular 中的无区的实验性支持!将 provideExperimentalZonelessChangeDetection 添加到你的应用启动过程中。

启动应用程序(应用程序, {  
  提供项: [  
    提供实验性的无区变更检测()  
  ]  
});
// 启动应用程序,提供实验性的无区变更检测功能

在添加提供者之后,在 angular.json 文件中的 polyfills 部分移除 zone.js。

向前迈进,无边界为开发者开启了众多机会。

  • 提高微前端的可组合性和与其他框架的互操作性
  • 加快初始渲染和运行时
  • 更小的打包体积和更快的页面加载
  • 更易读的堆栈追踪
  • 简化调试

在你的组件中使用 zoneless 的最好方式是使用信号:

    @Component({  
      ...  
      template: `  
        <h1>来自 {{ name() }} 的嗨!</h1>  
        <button (click)="handleClick()">切换到无区</button>  
      `,  
    })  
    export class App {  
      protected name = signal('Angular');  

      handleClick() {  
        this.name.set('无区Angular');  
      }  
    }

如下示例中,点击按钮会调用 handleClick 方法,该方法更新信号值并刷新 UI。这与使用 zone.js 的应用类似,但有一些差异。使用 zone.js 时,Angular 会在应用程序状态可能发生变化的任何时候运行变更检测。而没有 zone 的情况下,Angular 只在较少的触发事件(如信号更新)时才进行检测。此变更还包括一个具有去重功能的新调度器,以避免短时间内重复检测变更。

当用户点击上面的按钮时,Angular 仅会因为调度器的合并功能而运行一次变更检测。更多关于无区(zoneless)的内容,请参阅我们的文档

更新到无区域模式

最近,Angular 正经历着激动人心的演变,而 zoneless 是其中的核心部分。随着框架的不断发展,我们确保现有的所有 API 都能继续正常运行,并且新加入的内容都能很好地配合使用。

Zoneless 还是我们在互操作性方面的另一种尝试。除此之外,我们还希望确保将现有应用迁移到 Zoneless 也尽可能简单。如果你的组件兼容 Angular 的 ChangeDetectionStrategy.OnPush 变更检测策略,它们也应与 Zoneless 兼容,使之迁移也更为顺畅!

默认聚合
默认情况下,数据会被自动合并在一起

从 v18 开始,我们为无区段的应用和启用了 合并 的 zone.js 应用使用相同的调度程序。为了减少新 zone.js 应用中的更改检测周期,我们默认启用了 区段合并 功能。

这种行为仅对新应用可用,因为它可能引起依赖旧变更检测机制的应用程序出现问题。合并能减少不必要的变更检测周期,显著提高某些应用的性能。

为了为现有项目启用事件合并,请在 bootstrapApplication 中配置您的 NgZone 提供者:

您可以:

bootstrapApplication
(强调符号,不是代码块)

启动应用(App, {
  提供者: [  
    提供Zone变更检测({ eventCoalescing: true })  
  ]  
});
原生等待无地域限制的应用程序

Zone.js 拦截了许多浏览器调用,以便插入 Angular 的变更检测。不幸的是,async/await 是 zone.js 无法修补的 API 之一,因此我们需要通过 Angular CLI 将其降级到 Promise。这不太理想,因为所有现代浏览器都支持 async/await,而 async/await 不仅更具表达力,而且在 JavaScript 运行时中得到了更好的优化。

如今,如果你今天开发一个使用无区域变更检测功能的实验性应用,Angular CLI 将直接采用原生的 async/await,而不再将其转换为 promises。这不仅让调试更加方便,还能够使你的包体积更小。

支持无需分区的组件

我们在 Angular CDK 和 Angular Material 中启用了无区支持功能。这也有助于我们发现并改进了一些与无区模型相关的粗糙点。

Angular 开发者的理想之地

在过去18个月里,我们一直在努力工作在 angular.dev,致力于提供一个直观且动手的入门体验,并改进了深入指南。今天,我们很高兴地告诉大家,angular.dev 成为了 Angular 的官方文档网站!

除了全新的现代界面外,你还可以找到一个基于 WebContainers互动的手把手教程,一个带有示例的互动 沙盒,由 Algolia 提供支持的改进搜索,更新的指南和教程,简化了的导航,以及其他更多新东西!

Angular.dev 主页

所有对angular.io的请求现在都会自动跳转到angular.dev。以确保现有链接仍然有效,我们会将这些请求引导到v17.angular.io

可以去angular.dev看看。

终于搞定第3种材料了!

几个月之前,我们引入了对 Material 3 的实验性支持,根据开发者反馈进行了改进并完善了我们的 Material 3 组件,我们很高兴将它们升级到稳定状态!

我们还一起用新的 Material 3 主题和文档更新了 material.angular.io。

你可以在我们的指南中找到如何在你的应用程序中使用Angular Material 3组件。

信号API功能正在开发者预览中

在 Angular 17.1 和 17.2 版本中,我们宣布了一些新特性,包括信号输入属性、基于信号的查询,以及新的输出语法。

查阅我们的信号指南,了解如何使用这些APIs。在接下来的几个月里,我们将根据您的反馈持续改进这些功能,直到它们达到稳定版本。

延迟视图现在稳定了

在过去的六个月中,我们听到了很多关于可延迟视图的激动人心的消息,以及它们如何帮助开发人员轻松提升其应用的核心网络基准。例如,Bill.com 分享说,通过使用 @defer,他们将其中一个应用的包体积减少了 50%。现在,延迟加载视图已经可以稳定使用了!你可以在你的应用 以及库 中使用它们。

内置的控制流已经很稳定了

除了可延迟视图外,在v17版本中,我们还宣布了一种新的内置控制流功能,该功能改进了性能。我们很高兴看到这种新语法得到了广泛采用,并经过我们对社区反馈的回应,我们现在很高兴宣布该API稳定!

在预览期间,我们进一步完善了控制流的类型检查,增加了更多更符合人体工学的隐式的变量别名,并为某些性能相关的反模式设置了防护措施。

服务端渲染:改进

大约在一年前,我们引入了 hydration 并将其稳定下来。根据公共 HTTPArchive 数据集的信息,使用了 prerendering 或服务器端渲染的 Angular v17 应用中,76% 的这些应用已经开始使用 hydration。

有一个主要障碍阻碍了更多人使用hydration功能——缺少i18n支持。与Chrome Aurora团队合作后,我们很高兴地告诉大家,i18n块的hydration支持已经在v18的开发者预览版本中可用!

事件重播

不到两个月前,我们宣布了一个长期整合项目,目的是将Angular与谷歌内部框架Wiz整合。提醒大家,过去,Angular和Wiz服务于不同的应用程序领域——Wiz主要用于面向消费者的高性能应用,特别注重性能;而Angular则侧重于提高开发效率和提升开发者体验。

为了实现整合的努力,Wiz 在其渲染模型中全面集成了 Angular Signals。我们在 ng-conf 上分享了 YouTube 如何使用 Angular Signals。同样地,Angular 正在不断引入更多以性能为中心的功能,例如我稍后会详细介绍的部分水合技术。

无论是哪种情况,我们都会利用你的功能请求和其他需求来激励我们,使两个框架的主要功能合并,以满足这些要求。

今天,我们很高兴地分享,运行在Google.com的核心库之一是事件分发(以前称为jsaction的库),现已加入Angular 单一代码库。从v18版本起,事件分发将在使用混合渲染时提供事件回放。

大多数开发人员不会直接处理事件分发,所以我们来看看为什么事件回放是有用的。下面是一个简单的电子商务网站的模拟示例。为了模拟非常慢的网络连接,我们故意引入了加载延迟。想象一下,当页面还在加载,尚未完全初始化时,用户想要向购物车中添加多个耳机。如果页面还没初始化完成,还不能交互,那么所有用户操作都将被丢弃。从 Angular v18 版本开始,事件分发功能将开始记录用户的事件。一旦应用程序初始化完成,事件分发会回放这些事件,购物车中最终将有六个项目。

在 Angular 中的事件调度和事件重播

事件回放功能在v18开发者预览版中可用。你可以使用withEventReplay()来启用它,例如:

启动应用程序(App),并提供客户端水合功能,包含事件重放功能。

更棒的调试体验

我们将 Angular DevTools 更新为可视化 Angular 的渲染过程。每个组件旁边都有一个图标来表示该组件的渲染状态。要预览 Angular 在页面上渲染的组件,您可以启用覆盖视图。如果您的应用程序有任何渲染错误,Angular DevTools 将在组件查看器中可视化它们。

Angular DevTools 水合作调试

特别感谢我们的社区贡献者同学 Matthieu Riegler (推特用户名)实现了这个功能!

CDK和Material中的补水支持

在 v17 中,一些 Angular Material 和 CDK 组件不被用于 hydration,导致它们需要重新渲染。在 v18 中,所有组件和基本组件都支持 hydration。

我们的部分补水计划

我们在 ng-conf 和 Google I/O 上宣布了部分 hydration 技术。这是一种技术,允许你在服务器端渲染之后逐步激活应用的状态。这样可以使你在启动时加载较少的 JavaScript 代码,并提高应用性能。

部分水合化建立在可延迟视图的相同基础之上。与现在服务器端渲染 @placeholder 块不同,你可以启用一种模式,在这种模式下,Angular 将在服务器端渲染 @defer 块的内容。在客户端,Angular 将在满足模板中指定的触发条件时下载相关的 JavaScript 并对延迟块进行水合化。例如,这里有一个假设的 API 示例。

@defer (延迟服务器渲染和客户端视口呈现) {  
  <app-calendar/>  
}

在服务器端渲染日历组件。当它到达客户端时,Angular 会下载相应的 JavaScript 并使日历组件活化,使其在进入视口后才变得可交互。

我们一直在积极地进行部分数据预渲染的原型设计,它已经可以通过交互触发器进行使用了。我们正与合作伙伴一起评估数据触发器的重要性,例如,组件传递接收属性或绑定值的变化。

如果你正在开发一个对性能要求极高的大规模应用,并希望加入我们的早期访问计划以塑造部分 hydration 的未来,请发邮件联系我们 devrel@angular.io

Firebase 的强大应用托管服务

随着 web 平台变得越来越复杂,你的应用托管在性能、可靠性、生产力和扩展性方面扮演着至关重要的角色。使用混合渲染的应用程序在服务器端渲染、预渲染和客户端渲染方面有不同的托管需求。手动管理这些复杂性可能会非常麻烦。Firebase 应用托管现在可以为开发者透明地搞定这一切!

Firebase 今年在 Google I/O 上宣布了 App Hosting。App Hosting 简化了动态 Angular 应用程序的开发和部署过程,提供内置框架支持、GitHub 集成,以及与 Authentication、Cloud Firestore 和 Vertex AI for Firebase 等其他 Firebase 产品的集成。

我们已经和 Firebase 合作了差不多一年的时间,努力确保 Angular 开发者拥有流畅的开发体验。看看他们的[快速入门]指南,现在就可以开始使用 App Hosting 了!

还有更多呢……

在我们推进的大计划中,我们总是花时间解决开发者的常见需求。这里有一些来自v18的主要更新:

为 ng-content 指定备用内容

为 ng-content 指定备用内容是指设置一个默认显示的内容,当 ng-content 没有匹配到任何内容时使用。

我们最受欢迎的请求之一是为 ng-content 指定默认内容。从 v18 开始,您现在可以使用这个功能。这里有一个快速示例(如下)。

    @Component({  
      selector: 'app-profile',  
      template: `  
        <ng-content select=".greeting">嗨 </ng-content>  

        <ng-content>未知的用户</ng-content>  
      `,  
    })  
    export class Profile {}

现在我们可以使用这个组件了。

    <app-profile>  
      <span class="早上好">早上好 </span>  
    </app-profile>

这意味着:

    <span class="greeting">早</span>  
    这位朋友
统一控制状态变化事件

FormControlFormGroupFormArray 这些 Angular 表单类现在提供了一个名为 events 的属性,允许你订阅这些表单控件的事件流。通过它,你可以追踪值变化、未修改状态、是否被触碰以及控件的有效性状态的变化。

你现在可以使用了:

    const nameControl = new FormControl<string|null>('name', Validators.required);  
    nameControl.valueChanges.subscribe(value => {  
      // 处理每个变化  
    });

此功能请求议题在GitHub上获得了超过440个赞同。感谢我们社区的贡献者Matthieu Riegler,他将这一功能提供给了所有人!

将迁移自动化到应用构建器

在 Angular v17 中,我们宣布“application builder”已稳定,并默认启用以供新项目的使用。其内部使用 Vite 和 esbuild 替代了之前使用的 webpack。

对于大多数应用来说,开发人员可以通过更新他们的 angular.json 来升级到新的构建系统。在过去六个月里,我们收集了更多用户反馈并改进了更新体验,以使每个人能够顺利过渡到新的构建体验并获得编辑和刷新的改进。

您可以在我们的更新指南中找到我们开发的工具,这些工具可帮助您自动化更新流程。

因为 Webpack 不是新构建系统的关键路径,我们将对 Webpack 的依赖变为可选,这使我们减少了 Angular CLI 的总依赖项数量超过 50%。这将加快您的 Angular CLI 安装速度。

作为函数的路由重定向

例如,在Web开发中,我们可能会使用这样的函数来处理URL重定向。

为了增强处理重定向的灵活性,Angular v18 中,redirectTo 现在可以接受一个返回字符串的函数。例如,如果你想根据某些运行时状态重定向到某个路由,你可以在函数中实现更复杂的逻辑:

    const routes: Routes = [  
      { path: "first-component", component: FirstComponent },  
      {  
        path: "old-user-page",  
        redirectTo: ({ queryParams }) => {  
          const errorHandler = inject(ErrorHandler);  
          const userIdParam = queryParams['userId'];  
          if (userIdParam !== undefined) {  
            return `/user/${userIdParam}`;  
          } else {  
            errorHandler.handleError(new Error('尝试导航到用户页面但未提供用户ID,导致导航失败.'));  
            return `/not-found`;  // not-found 页面路径
          }  
        },  
      },  
      { path: "user/:userId", component: OtherComponent },  // 获取用户ID参数
    ];
TypeScript 5.4 版

最后但同样重要,我们更新了对 TypeScript 的依赖,让你可以利用到所有的最新功能!TypeScript 5.4 功能

社区亮点

在社区中,我们也看到了大量的进步和创新,随着 Angular 的不断创新。

一些流行的 state 管理库,比如 ngrx、ngxs 和 rxAngular,已经开始使用 Angular 信号,从而使组件中的反应性更加细腻。

两个月之前,Angular GDE(Angular 开发专家)Brandon Roberts 发布了 Analog.js 的 1.0 版本——这是一个由社区驱动的 Angular 元框架(Meta Framework)。它提供了一些很酷的功能,例如基于文件的路由、API 路由、一流的 Markdown 支持功能等等。Analog.js 团队一直在试验一种 单文件组件格式,并且社区对此反应非常积极!

确实令人兴奋的是,其他生态系统中的流行库也在为 Angular 构建适配器。Chau TranArnoud de VriesCorbin Crutchley 分别发布了对 Angular 的 TanStack StoreTanStack QueryTanStack Forms 的支持!

我们也很高兴能够参与世界各地的许多Angular社区会议,并期待今年晚些时候即将举行的会议。组织一场有数百名与会者和数十位演讲者的会议是一项艰巨的任务,向所有让这项艰巨任务变为现实的人致敬,包括ng-confAngular Belgradeng-deng-beNGPolandngRomeNG KenyangIndiaAngular TLV等这些会议!如果我们遗漏了任何会议,请在评论中与我们分享。

从v16以来,除此之外,我们还收到了超过290位贡献者的贡献!感谢所有帮助Angular变得更好的人,无论他们通过代码、问题、内容、组织社区或其他方式🙏

回想一下我们的进展

作为Angular复兴的一部分,我们在过去两年里做了很多事情,未来我们还有很多创新的想法。我想在这里回顾一下现状,并庆祝我们所处的位置。

在将 Angular 演进为一个真正反应式的框架并引入 Signals 等功能的同时,我们始终坚守使命,让开发者能够自信地交付应用程序。全球第二大网站 YouTube 已经使用了 Angular 的反应式原语,我们正作为更大工作组的一部分,共同将 Signals 添加到 web 平台,详见 GitHub 提案

我们还密切与ViteNxCypressPuppeteerStorybook等工具的开发者合作,以提升所有开发者的体验。同时,我们非常幸运地拥有一群充满热情的开发者、社区组织者、作者和演讲者,他们不断挑战Angular的极限。

感谢大家参与 Angular 的复兴潮!

0人推荐
随时随地看视频
慕课网APP