2023 年之前 Angular 没那么好

你可能经常听到有人这样说

Angular 会在 3 年后等你。

Angular 更适合大型或企业项目

Angular 提供了出色的更新体验

......

在这篇文章中,我将向您展示为什么我认为 Angular 在 2023 年之前没那么好

当然,在将 Angular 与其他框架/库进行比较时,我不能 100% 公平。另外,因为我试图演示 2023 年之前的 Angular 并不是那么好,所以我会过多关注其缺点。这对 Angular 来说不公平。2023 年之后,Angular 变得越来越好,但我将在其他文章中介绍这些部分。

公平起见,我在 2023 年 8 月 15 日创建 2 个项目,1 个用于 Angular,1 个用于 Vue。

对于 Angular,我使用 angular/cli@16.2.0 和ng new my-app-angular创建。

对于 Vue,我使用 create-vue@3.7.2 和npm create vue@latest创建。

我将一步步演示它。

创建新项目时

使用 Angular CLI 创建新项目时,我有 2 个选项

  • 需要路由

  • CSS格式

使用 Vue CLI 时,

除了2个选项之外,我还有4个以上的选项

  • 状态管理库
  • e2e测试库
  • ESLint
  • Prettier用于代码格式化
  • ......

在我看来,对于大型或企业项目而言,在一开始就配置好上述 4 个选项很重要

如果开发者不是高级或专业前端工程师,或者仅仅想省点事,在 CLI 不默认提供这些选项时,它们很容易丢失。

如果它们没有在一开始被配置好,在开发到一半时,让所有团队成员就一个特定的解决方案达成一致并不容易。有些人喜欢这个状态管理库,而另一些人则喜欢另一个。有些人喜欢分号,有些人不喜欢。如果团队里正好有两个偏好相反又特别坚持的,那么可能就无法统一了。

即使幸运的是,开发者在迭代的过程中重新配置了上述选项,那也依然会有一些遗留代码需要迁移,或者留下了一些不那么好的代码。

考虑到很多人会在提供的选项中直接选择第一个,所以一个完备的脚手架在不知不觉中就统一了不同项目的整体架构和编码风格。以至于开发者随意打开一个 Vue 项目,就可以直接上手,这点在 Vue2 时代尤其明显。

顺便说一句,Angular 到目前为止还没有官方的状态管理解决方案。

由于这个问题, Angular 在 2022 年将状态管理添加到了待办事项中,所以如果你认为 Angular 不需要状态管理库,似乎 Angular 和社区并不同意你的观点 。到目前为止,Angular 最受欢迎的状态管理解决方案是ngrx

实际上,也有很多人通过"RxJs"和"DI"使用自己设计的状态管理库。关于状态管理的选择,虽然不至于像 react 那么繁荣(混乱),但也不容乐观。

默认项目文件夹结构

对于 Angular,在找到CodingStyleGuide章节之前我甚至不知道如何编码。

  • 路由器视图放在哪里?
  • 共享代码放在哪里?
  • ......

而对于 Vue,我认为开发人员几乎可以立即编码。

不管怎样,我将遵循 Angular 风格指南来创建一个heroes功能模块。

演示代码是从 Angular 主页演示复制的。

这是用户界面:

默认的变更检测策略是性能杀手

您是否注意到当页面加载时该函数在控制台被调用了多少次?6*9=54次! 这是代码

而如果你将鼠标从上到下移动,该功能将被触发299次!

在这种情况下,我们可以使用该OnPush策略。

isSensitiveHeroName首次触发9次,事件触发9*9mouseenter

所以通过 OnPush 策略,性能提升了1200% 。实际上,如果我们想将Default策略更改为OnPush,我们需要应用更多更改,而不仅仅是此演示中的一行。

对于这种情况,针对 Angular 我们有更好的解决方案。

现在,我们获得了更好的性能,也许是最好的性能。这就是为什么你经常可以在 Angular 社区看到这一点。

永远不要在模板中调用函数

好的。这是我的担忧

避免在模板中使用函数真的好吗?

为了获得更好的性能,我们定义了派生状态isSensitive。所以,每次我们改变英雄的名字,我们都需要更新isSensitive

在实际应用程序中,会有许多派生状态依赖于 2 个或更多其他状态。因此,我们需要添加越来越多的代码来保持当前的性能,这将很快带来错误和维护问题。

可能还有其他方法可以在不编写更多代码的情况下保持性能。但这是我的担忧

Angular 需要开发人员花多长时间才能编写出高性能且易于维护的代码?1个月还是1年?

幸运的是,Angular 于 2023 年推出 Signals Signals目前处于开发者预览版。Signals允许您编写高性能且易于维护的代码。

复杂的 NgModule

现在,假设我想在 HeroesModule 之外使用HeroListComponent. 我需要把它从 HeroesModule 导出,然后将其导入到另一个模块(假设AppModule)。

我只能看到 1 个优点。如果我想使用从 HeroesModule 导出的其他组件,我不需要在AppModule再次导入组件。

然而,我也看到了很多缺点。

对于开发人员来说,并不知道AppModuleHeroesModule导入了多少东西. 只有 Angular 知道。

因为组件必须在模块中声明,所以开发人员不容易知道组件在模块中依赖了多少东西。例如,HeroListComponent依赖于CommonModuleHeroesRoutingModule吗? 我们需要检查一下。

因此,如果您将组件从一个模块移动到另一个模块,但它不起作用,这是很常见的,因为您需要找出该组件需要哪些依赖项并移动依赖项。因为组件中没有声明依赖关系。

总之,组件无法单独工作,如果您来自其他框架,则很难想象这一点。

幸运的是,2022 年底 Angular@15 推出了 standalone组件。Angular 团队甚至提供了一个工具供您把组件从NgModule迁移到standalone

与 RxJ 的深度绑定

许多 Angular API 使用都需要通过Observable, 甚至HttpClient. 然而,对于初学者来说,使用 RxJ 编写代码很容易犯错。

RxJ 声明式风格中需要谨慎的事项

例如,前面HeroListComponent是用声明式风格实现的。如果我们删除heroes$ | async模板中的 ,则service.getHeroes永远不会再次调用 。 如果您是 Angular 或 RxJ 的新手,这可能会让您感到震惊。

另外,如果service.getHeroes抛出错误一次,该函数将不再工作。这就是为什么您经常可以在声明性代码中看到catchError(() => EMPTY)

RxJ 命令式风格中需要谨慎的事项

事实上,许多开发人员正在使用命令式编程。在这种情况下,HeroListComponent就像

在模板中,heroes$ | async需要更改为heroes.

然而,它有缺陷。就像我们需要removeEventListener一样,我们也需要unsubscribe takeUntilDestroyed

然而,takeUntilDestroyed到目前为止,它还处于开发者预览版中。2023 年之前,我们需要添加更多代码。还有一点,这种方式对于OnPush策略来说并不友好。

简短的结论

正如您所看到的,与 RxJ 的深度绑定使开发人员更容易犯错误或编写容易有内存泄漏的代码。

我确实认为 RxJs 很强大,尤其适合边缘情况。然而,拥有一个强大的工具并不意味着我们在所有情况下都需要使用它。许多没有 RxJ 的框架/库/项目都运行得很好。

另外,我没有提到 RxJs 的学习成本以及它带来的非常具有侵入性的代码风格

Angular 的现状

正如你所看到的,Angular 带来了许多新的解决方案。这是一件好事,但如果他们不及时指出推荐的解决方案,则可能是一件坏事。社区可能会比以前更加分裂。

  • 声明式或命令式编程
  • 少或多RxJs
  • Default或者OnPush
  • NgModule或者standalone
  • zone.js或者Singals
  • ......

在这些之间进行选择将导致不同的编码风格,这也会使代码难以维护。

前两个选择已经导致社区分裂。现在我们有更多了。

在我看来,

Angular 做出了像选择typescript 这样的伟大选择,但事实证明选择NgModulezone.js可能并不那么成功。即使内置RxJsAPI 也可能不是一个好的解决方案。

Angular 并不是在 3 年后等待其他框架/库。

他正在进步和选择。许多框架和开发人员没有选择的一些解决方案通常意味着它们可能不太适合前端开发。在这些情况下,Angular 也在向其他框架/库学习,而不是等待并坚持认为自己的方向是正确的。

实际上,框架/库都是互相学习的。学习和提高自己比认为自己是最好的要好得多。

相关推荐
爱喝水的小鼠38 分钟前
Vue3(一) Vite创建Vue3工程,选项式API与组合式API;setup的使用;Vue中的响应式ref,reactive
前端·javascript·vue.js
小晗同学39 分钟前
Vue 实现高级穿梭框 Transfer 封装
javascript·vue.js·elementui
forwardMyLife1 小时前
element-plus的面包屑组件el-breadcrumb
javascript·vue.js·ecmascript
计算机学姐2 小时前
基于python+django+vue的影视推荐系统
开发语言·vue.js·后端·python·mysql·django·intellij-idea
luoluoal2 小时前
java项目之基于Spring Boot智能无人仓库管理源码(springboot+vue)
java·vue.js·spring boot
mez_Blog2 小时前
个人小结(2.0)
前端·javascript·vue.js·学习·typescript
深情废杨杨3 小时前
前端vue-插值表达式和v-html的区别
前端·javascript·vue.js
GHUIJS3 小时前
【vue3】vue3.3新特性真香
前端·javascript·vue.js
众生回避3 小时前
鸿蒙ms参考
前端·javascript·vue.js
洛千陨3 小时前
Vue + element-ui实现动态表单项以及动态校验规则
前端·vue.js