Description
还记得大三开始看的第一个前端框架就是 Angular,看了一周看完文档,发现啥也没看懂,并且配套的经验文章或者书籍都非常少
所以说三大框架中,学习曲线最陡峭的是 Angular,可能大家都会表示赞同,除了繁杂的概念设计较多之外,RxJS 和 TS 都是使用这个框架的必修课,如果两者不会,那么基本上寸步难行
在辅导工作时,由于对 RxJS 和 TS 基本没接触过,所以刚入职花了仅三周才开始开发第一个小需求...使用了大半年后,对于这个框架也只能说是勉强会用,离精通还差的远
发展历史
Angular 遵循语义版本控制标准,每个主要版本号都表示潜在的重大更改
Angular 承诺为每个主要版本提供 6 个月的积极支持,然后是 12 个月的长期支持
主要版本每两年发布一次,每个主要版本有 1 到 3 个次要版本
- AngularJS
- 初始发行 - 2010 年 10 月 20 日
- 设计目标
- 将 DOM 操作与应用程序逻辑分离。代码结构的方式极大地影响了这一点的难度。
- 将应用程序的客户端与服务器端解耦。这允许开发工作并行进行,并允许双方重用。
- 为构建应用程序的旅程提供结构:从设计 UI,到编写业务逻辑,再到测试。
- 特点
- 双向数据绑定
- 依赖注入
- Angular 2 - 2016 年 9 月 14 日发布(“Angular”不带“JS”指的是版本 2 及更高版本)
- Angular 4 于 2016 年 12 月 13 日发布
- 引入HttpClient,一个更小、更易于使用且更强大的库,用于发出 HTTP 请求。
- Guards 和 Resolver 的新路由器生命周期 GuardsCheckStartGuardsCheckEndResolveStartResolveEnd
- 加入了 NavigationStart 等现有的生命周期事件集
- 有条件地禁用动画
- Angular 5 于 2017 年 11 月 1 日发布。
- 主要改进包括对渐进式 Web 应用程序的支持
- 构建优化器和与 Material Design 相关的改进
- Angular 6 于 2018 年 5 月 3 日发布
- 这是一个主要版本,较少关注底层框架,更多关注工具链,以及在未来更容易使用 Angular 快速移动,例如:ng update、ng add 、Angular 元素、Angular Material + CDK 组件、Angular Material Starter 组件、CLI 工作区、库支持、Tree Shakable 提供程序、动画性能改进和 RxJS v6
- Angular 7 于 2018 年 10 月 18 日发布
- 关于应用程序性能、Angular Material 和 CDK、虚拟滚动、改进的选择可访问性的更新,现在支持使用 Web 标准的自定义元素的内容投影,以及关于 Typescript 3.1、RxJS 6.3、Node 的依赖更新10(仍支持节点 8)
- Angular 8 于 2019 年 5 月 28 日发布
- 生成的代码在运行时更易于阅读和调试
- 更快的重建时间
- 改进的有效载荷大小
- 改进的模板类型检查
- 向后兼容
- Angular 9 于 2020 年 2 月 6 日发布
- 版本 9 将所有应用程序移动到默认使用Ivy 编译器和运行时。Angular 已更新为可与 TypeScript 3.6 和 3.7 一起使用。除了数百个错误修复之外(wtf?),Ivy 编译器和运行时还提供了许多优势:
- 较小的捆绑尺寸
- 更快的测试
- 更好的调试
- 改进的 CSS 类和样式绑定
- 改进的类型检查
- 改进了构建错误
- 改进了构建时间,默认情况下启用 AOT
- 改进的国际化
- 版本 9 将所有应用程序移动到默认使用Ivy 编译器和运行时。Angular 已更新为可与 TypeScript 3.6 和 3.7 一起使用。除了数百个错误修复之外(wtf?),Ivy 编译器和运行时还提供了许多优势:
- Angular 10 于 2020 年 6 月 24 日发布
- 新的日期范围选择器(Material UI)
- 关于 CommonJS 导入的警告
- 可选的更严格的设置
- 与生态系统保持同步
- 新的默认浏览器配置
- 弃用和删除
- Angular 11 于 2020 年 11 月 11 日发布
- Angular 12 于 2021 年 5 月 12 日发布
- 已弃用对 IE11 的支持
没错 NG 11 和 12 没什么改动,但是他就是升级了,嗯...
特性
脏检测
变更检测周期
- 开发人员更新数据模型,例如通过更新组件绑定
- angular 检测变化
- 变更检测从上到下检查组件树中的每个组件,以查看相应的模型是否已更改
- 如果有新值,它将更新组件的视图(DOM)
Zone.js
一般情况下,zone可以跟踪并拦截任何异步任务
Zone 通常具有以下阶段:
- 开始稳定
- 如果任务在区域中运行,它将变得不稳定,
- 如果任务完成,它将再次变得稳定
简而言之,如果发生以下事件之一,则框架将触发更改检测
- 任何浏览器事件(单击,键入等)
setInterval()
andsetTimeout()
- HTTP 请求
尽管Angular在后台进行了大量优化,但是在大型应用程序上性能仍然会下降
变更检测策略:
-
OnPush
- 这种更改检测策略可以 跳过对此组件及其所有子组件的不必要检查
- 使用此策略,Angular知道仅在以下情况下才需要更新组件:
-
输入属性已更改, 标记为@input() 的属性;
-
该组件或其子组件之一触发事件处理程序
-
手动触发变化检测
-
通过异步管道链接到模板的可观察对象发出新值, 如 data | async
让我们仔细看看这些事件类型。
-
-
Default
- 每当事件触发更改检测(例如用户事件,计时器,XHR,promise等)时,此默认策略都会从上到下检查组件树中的每个组件。这种不对组件的依赖项做任何假设的保守检查方法称为脏检查。它可能会对包含许多组件的大型应用程序的性能产生负面影响。
RxJS in Angular
angular 官方使用了 RxJS 来管理和处理异步请求,这个库的理念和我们之前的 Promise 的理念完全相反,一般我们使用的是拉取的数据处理逻辑,我去 “拉” 取用户信息,然后处理展示等
而 RxJS 使用的是流的概念,是一种“推”的概念,我们将 userId 推送给用户信息请求函数,然后就能拿到用户信息,自动展示
并且 RxJS 提供了较多的内置 operator,需要一定的时间上手,但是一旦上手之后,处理起一些复杂的业务逻辑也会更加得心应手
RxJS 就是这样的一个工具,你用我推荐,我用我不用
使用心得
社区生态
有篇文章详细分析了 NG 的各种问题 ,比如
NG 的官方团队貌似出现过几次人员变更,核心成员的离开必然导致大量的维护问题 (见下方 github issues 趋势),现在 Angular 还有 1.7k 待解决的 issues..(seriously?)
除此之外,NG 的高质量学习资料基本上可说是少得可怜,按照使用情况来看,应该是英文资料较多,实际上也很难查找到一些高质量的 NG 原理或者是是特性的深入解析文章,反而是中文的比较多,着实有些令人奇怪..
版本迭代问题
NG 不能不说的一个问题,就是版本迭代,从我使用 NG 以来,NG 就升级了两个版本,对于小型业务方来说,升级不是一个很大的问题,但是对于公司这个体量的使用者来说,问题就暴露出来了
升级的主要步骤如下
- NG 升级:
- 由于升级中 NG 新增或者删除了一些特性,需要一定的时间进行调整,并且测试功能的可用性,如果你不升级,你就无法使用一些你应该能使用的特性,如 HMR
- AntD 升级
- 升级完主框架后,需要升级 UI 框架,这里面和 NG 升级拥有者同样的问题,你需要回测所有功能
- 并且有个很重要的点,由于 NG 的库无法或者很难向前兼容,所以库的维护方基本上只在最新的版本上修复库的问题,这就导致了用户必须升级库,才能解决自己发现的已知问题...
- 公司内部依赖库升级
- 如果前面都做完了,那么恭喜你,你成功了一半,接下来你就要检查项目是否能够正常启动了
- 如果这个时候你发现有 warning,并且功能正常,那么还能接收,如果有 error,那么抱歉
- 你需要升级依赖的库,如果依赖库的业务方没升级,那么更抱歉了,要么推动他们升级,因为在此之前你的升级都没完成
- 如果他们不升级,那么要不自己帮助升级,或者回退上述的两个步骤,乖乖使用老版本的 NG
所以说,真的很难,求求了,别再发新版本了,没什么大变动,为啥发新版本呢,为了 KPI 吗?
坑多
- 反直觉。在用了 React 之后发现,如果你想做一件事,用 React 可能会很绕,但是也能完成;用 NG 就会发现,很绕,而且不能完成...
- 莫名其妙的依赖冲突。如果你使用官方的 demo, npm install 的时候就会发现有 peer-dep 冲突,太莫名其妙了...
- 使用 FormGroup.value() 来获取 form 的 value 很正常对吧,但是如果你这么用了,你会发现少值了。disable 状态下的 formControl 的 value 不会在其中,如果需要,你得使用 FormGroup.getRawValue()....
- this.$http.get() 为什么不能帮我把传入的非字符串对象序列化一下?为啥还得使用方自己做呢...
- ...
微前端兼容问题
还记得说 Angular 适合大型项目的说法,到用起来,才发现根本不是这么回事
我们主站的班课项目非常之大,里面糅合了所有班课相关的模块,包括班课详情,用户详情,营销,教务等等的功能,本地 dev 需要 5 分钟,热更新 1 分钟,build 需要 40 分钟
这合理吗,这不合理...
首先,功能多了自然会带来此问题,但是 NG 官方并没有提供这类问题的解决方案,首先是不支持在项目内进行多页配置,必须得拆分项目才能拆开页面,由于项目模块的耦合,这高昂的成本, 前期也就不考虑了
后续调研发现,公司内部都在尝试迁移到 React 解决这个问题,主要有两类:
- 使用 NG 加载 React 的组件进行渐进式迁移
- 使用 qiankun 或者其他微前端框架进行迁移
我们本质是为了解决开发难的问题,所以组内其他小伙伴前期尝试了 qiankun 的方案,结果发现踩的坑太多,进行不下去了。最后还是回到拆分项目这一步,进度也十分缓慢
好不容易拆分得差不多了,结果公司凉了...可见这个问题的解决成本之高昂
没有 Debug Tool
Angular 没有官方可用的 debug tool,至少在 2021 年 五月为止的半年时间内,这太令人费解了
刚开始用的时候找了半天以为是没找到,所以去 github 提了 issues,发现是官方就没提供过....唯一能有的 Angury 已经在 NG9 的时候不再支持了,并且性能也很差
想念有 Vue 和 React Debug Tool 的日子...
除此之外,RxJS 也没有 debug tool,由于本身是流的概念,很多时候根本不知道,那个流出发了刷新,每次 debug,都需要加一大堆 tap tap...
很无奈,不知道这个生态的开发者是真的都已经熟悉到不需要这类工具了吗...
IDE 问题
Angular 的 IDE 兼容,目前也只有 webstorm 做的比较好,vscode 的插件基本还是不要使用了,如果还是要用 vscode,还是建议关闭所有 ng 插件,真的不好用
主要原因:
- 性能很差
- 跳转很慢
- 启动后进行模块解析,风扇直接起飞
- 插件不好用,各种没法跳转
- ...
优缺点
- 优点
- 依赖注入很香。不用关心各类 service 的引入,直接在 constructor 中声明即可
- 可复用性高。人人写的代码都长得一样
- async pipe 很香。直接在模板中传入 userId$ | appGetUserName$ | async 即可获取用户名
- 缺点
- 上手成本高,前置依赖 RxJS 和 TS
- 版本迭代太快,兼容成本太高