Angular2是可怕的

banq 16-12-02
         

我们使用Angular 2作为我们的前端, 而我并没有参与这个决定,我是相对较晚才到这个项目工作。 这篇文章并不是对框架的全面评审,而是在使用了两个多星期后的一系列观察结果。 我不认为使用它了两个星期会让我成为专家,并欢迎任何更正,但对于它的价值, 我认为使用Angular 2是我们项目最大的错误之一 。

摇摇欲坠的基础
Angular 2稳定版是建立在实验语言特性(TypeScript decorators)和Rx.js 5.0测试库之上。让我重申一下:框架声称比其依赖和它所基于的语言更加稳定。这绝对是疯狂 。 当Angular2的核心依赖性没有落地成熟时,它不应该声称自身很稳定。在其上构建应用程序就像在一副牌上建造一样脆弱。如果TypeScript decorators提议的语义改变了,或者更糟糕的是,从语言中完全撤消了会发生什么?

这里没有发明
Angular 2是这个术语最真实意义上的一个框架。 它使用自己的模块加载系统(因为JavaScript没有足够的这些系统,对吗?),尝试抽象整个浏览器平台,甚至加载了一个完整的HTML解析器和杀毒程序。 它甚至说自己的语言 -结构化指令,管道,声明,模块,注入器,服务,视图封装,装饰器。

这给框架学习增加了一个很大的难度曲线。甚至对熟悉现有浏览器API和Reactive框架的人员来说,需要重新学习Angular是如何实现的。比如管道,几乎完全不像UNIX管道,或传统的模板语言的过滤器。 又如:Angular的HTTP客户端返回Observable,而不是Promise,迫使你不仅要学习另一种异步库,但是是一个完全不同的异步模式 。

这是尤其恶劣的,因为尽管文档的声明,在用于Ajax请求时,Observables提供了没有比Promises有明显的改进。

许多Rx.js方法实际上适合流数据,但是对于单值请求来说太过度设计。

一个Ajax请求是单次的,使用运行类似方法Observable.prototype.map时候会永远只能在管道中得到一个值,显然这是没有语义意义的。Promises另一方面表示一个尚未完成的值,这正是HTTP请求给出的。我花了几个小时迫使Observable行为转换回一个Promise,只是极简单地使用Promise.all ,它的效果要比Rx.js好得多。

过早抽象
Angular喜欢假装它是一个平台无关的平台。

它通过抽象出浏览器API来实现这一点 - Angular使用自己的HTML怪异变体来替换DOM,使用自己的路由和location服务替代浏览器历史和本地location API,自己的HTTP客户端替代XHR和websocket。 不幸的是,这些都是现代应用可能需要的API一个可笑的小子集。 任何时候你只需要LocalStorage, geolocation,notifications一样简单,否则很容易破坏应用跨平台兼容。

更重要的是,在许多情况下,这种抽象是完全不必要的。 一些Angular平台API只是围绕浏览器API进行薄薄的包装,除非使它更难使用,否则并不提供有用的抽象。location和HTTP客户端服务是两个很好的例子。

你在Angular学习的知识并不能再在其他地方重复使用。比如学习Angular的HTTP客户端,这个知识在Angular宇宙之外是无用的。

HTML减号
Angular声称是HTML Plus - 也就是是HTML,但更好。 但这是错误的。

首先,Angular HTML 不是 HTML。 HTML属性不区分大小写,而Angular是。 这可能看起来像一个小的不一致,但它意味着任何基于HTML建立工具不能支持Angular的版本。 WebStorm的代码自动完成,例如,建议ngif代替ngIf 这两者是等价在HTML中,但在Angular HTML中不是。

其次,ANgular HTML语法设计不当,远远要复杂得多,而且充满了小陷阱坑-只要看看模板语法参考上的红色警告框数量 。 这里有一些事情指南里没有提到.

(这里省略有关Html的问题说明..)


不必要的粗俗
组件是大多数现代JavaScript应用程序的基本构建块。在前端开发中发生的最好的事情之一是:Web应用程序应该被组织成独立的、可重用的组件。理想情况下,这意味着组件应易于创建。而Angular是完全相反的。

要在Angular中创建一个组件,你必须为JS,CSS和HTML创建单独的文件。 根据设置,JavaScript可能需要根据TypeScript和来自SCSS或LESS的CSS进行编译,因此一个组件需要五个文件。 有了这么多文件,您需要为每个组件准备单独的文件夹。 组件本身是@Component装饰,宣告组件元数据,如样式,模板和选择器,使得组件可以在其他地方重复使用。然后通过构造函数注入组件依赖项,并记住声明组件生命周期接口。 最后,你需要在应用程序的模块文件中声明组件。只是为了建立一个单一的组件这是一个很大的工作量。

单个文件组件也可以使用Angular,但是你需要在TypeScript本身中声明标记和样式,并且(据我所知)与我们需要管理CSS变量的预处理器(如SCSS)不兼容。与Vue的单个文件组件进行比较。 对于Vue,标记,样式和逻辑在单个文件中声明。 组件表示为简单对象。只有很少的仪式,使其很容易创建新的组件。

差异是否显著? 我会说是的。我们的Angular应用程序有21个组件,而我们的Vue应用程序有30多个,但是后者明显不太复杂。 Vue组件小而瘦,而Angular组件不可控制地增长,因为与将单个组件提取成单独的组件相比,将更多的东西堆积到单个组件中会更容易。

性能差和膨胀
这可能是由于我们的特定设置,但Angular 2感觉特别沉重。基于Vue的应用程序我构建的分配三个重建构建过程,在开发过程中的眨眼之间完成 - 当我切换工作区到我的浏览器,经常性此时页面已经重新加载和呈现。 我们的Angular 2应用程序在不同,会花费几秒钟重建和渲染。 这听起来可能很小,但请记住,任何改变都会导致重载刷新源代码的结果,所以这是每天必须做上百次。

我们的Vue应用程序还带有热加载模块和在开发模式下重新加载样式,而Angular应用程序没有。虽然这些可能配置Angular 2热加载模块实现,但是Vue公司的样板已经默认配置这种开箱即用的特性。

同样的,而我们的Vue模板渲染是开箱即用的提前AoT渲染,而Angular2这样做必须配置,并要求所有相关支持相同。 后者实际上更重要 -配置自己的应用程序来支持AoT编译相对简单,要求所有依赖相同是痛苦的。 这也助长规模膨胀。 我们的应用程序的初始大小就已经是1MB。
(....)

将Java放回JavaScript
我试图理解为什么我们的应用程序的分析器输出看起来不像火焰图,更像是一件抽象的后现代艺术...

篇文章讨论了Angular 2的变化检测策略:

默认情况下,即使我们必须每次检查每个组件事件发生,Angular是非常快。它可以在几毫秒内执行成千上万的检查。 这主要是由于Angular产生VM友好代码。

Angular将浏览器的JavaScript引擎视为VM,而不是完全不同于Java。 这意味着,除了使堆栈跟踪长达三页并且分析器毫无用处之外,框架的性能完全取决于其运行的引擎。虽然只有一个JVM,但是有六个JavaScript引擎,每个都有自己的性能配置文件。我只能祈祷由Angular产生的就是“VM友好”对所有的代码。希望如此。

与Java相似不止这些。 Angular不是一个JavaScript框架,而是一个TypeScript框架。TypeScript喜欢假装它是安全的,因为它是强类型。这有点真实,但TypeScript遭受与Java完全相同的问题 - 它不是null安全。 更糟糕的是,因为TypeScript没有运行时组件,并且对许多不安全的转换没有发出警告,语言只提供了安全的错觉。 例如,这是非常有效的TypeScript代码,不产生警告。


private static extractAgenda(agenda: any): Agenda {
return agenda;
}


可怕的文档
Angular 2是我见过的主要框架中最坏的文档。 它是马虎的,不完整的,写得不好。 对于初学者来说, 快速入门页面说:大多数文档是为TypeScript开发人员编写的,尚未转为JavaScript人员编写。
(...)

前端开发的未来?
当我被介绍使用Angular2时,我希望它是一个优雅的框架,像Laravel和Django一样,使得前端开发变得容易和愉快。 但是我发现得是一个不稳定、肿胀、过度设计的框架,承诺很多,但提供很少。

请为善良的缘故不要使用Angular。 对于不到其大小的十分之一的Vue.js却提供了更好的开发体验。


Angular 2 is terrible - meebleforp.com
[该贴被banq于2016-12-02 15:48修改过]

         

28
sinaID68144
2017-12-25 16:13

一个来自Vue死粉的喷子,也没有资格评价一个框架的好坏,就像一个重度微软用户评论iOS操作不好,学习成本高。你说反了,angular2提供的前端服务模块是最全面的!

sinaID18951
2018-06-29 13:03

兄dei,你说我都不敢入门了