在选择Web前端框架之前,你需要了解Angular的六个问题以及选择Angular的原因
2019年12月4日追記:
@okunokentaroさん为我们写了一篇热门答复文章。
Angularでの開発を快適に進めるために知っておきたいこと
https://qiita.com/okunokentaro/items/503ab7a4c7601b564de0
https://gist.github.com/okunokentaro/dc4cd470999fd90aba73423d09a37485
真的非常感激。在这么短的时间内能写出这么高质量的文章真是太厉害了。今天真是感受到了Angular社区的温暖和热情。请一定参考这篇文章。
然而,“Angular 都是80分”的说法明显存在误导,好像无论是谁写的代码都会变成一样。实际上,不同的人编写代码时,使用RxJS的方式当然不同,模块的划分、服务、指令、管道等各种功能的使用方式也各不相同,甚至在编写表单时,每个人的方式也都会有所不同。
这是Angular #2 Advent Calendar 2019的第X天的文章。由于会给社区的人们带来麻烦,我决定取消参加这个圣诞日历活动。特别是对于制作这个日历的@lacolaco先生,非常抱歉。
这是我在 Qiita 上的首篇投稿文章。
虽然可以在搜索中找到很多比较Angular、React(以及Vue.js)的文章,但我觉得它们都只是说些无关紧要的东西。我真的希望别再有人随意地转述别人说的“Angular适合大型开发”之类的东西。
因此,我希望向面对选择前端框架的人们总结一下Angular的问题以及为什么仍然选择Angular。
(1)每6个月进行一次重大版本升级。
平常心思考一下吧,这绝不是正常行为。
让我们试着体会一下Angular开发者的心情
-
- 設計ミスしても短期間で取り消せる♪
- 実験的な機能も入れちゃえる♪
让我们试着体验成为图书馆开发者的心情。
-
- サポート続けるのツライ…
- メンテナンスに追われるぐらいならライブラリなんか開発しない方がいいんじゃないか…
让我们来换位思考,身临其境地感受一下应用程序开发者的心情。
-
- Angular を更新してたら機能追加できない
機能追加してたら Angular を更新できない
Angular 更新作業中も他のメンバーは機能追加しなきゃいけなくてカオスに…
サードパーティ製ライブラリを安心して使えない
ライブラリが Angular の新しいバージョンに対応するまで Angular のバージョンを上げられない(そもそもライブラリ作者は新しいバージョンに対応する気もないかもしれない)
アプリが Angular の新しいバージョンに対応する前にライブラリがサポート対象の Angular バージョンを引き上げるとライブラリのバージョンを上げられない
なるべくサードパーティ製ライブラリを避けて自製するハメに…
总结起来
-
- フレームワーク開発者は嬉しい
-
- エコシステムは育たない
- 古いバージョンを使い続ける覚悟が必要
尽管 Angular 更新指南非常有用,但这并不意味着只有这个就 OK 。
据说,我的朋友实际上仍在使用 Angular 2 这个产品。尽管 Angular 9 已经发布了……。
React自2017年9月发布的16.0.0版本以来,除了一些带有unstable_前缀的特性外,已经超过两年没有发生过重大的改变。这意味着我们可以使用新功能(如Hooks,从16.8版本开始),而不用担心兼容性问题而无法升级版本。
(2) 组件定义的痛苦
用Angular编写组件很痛苦。
冗长的组件定义
仅仅为了定义一个简单的组件,就需要编写一个带有繁杂修饰器的类,并且还需要在NgModule中进行声明,显得过于冗长。
而且,组件的名称在文件名、类名和选择器中稍有不同的形式出现。这真的是最糟糕的事情。如果想要改变组件的名称,必须改变文件名、类名、选择器,甚至还必须在NgModule中改变导入语句和声明。虽然编辑器会有一些帮助,但这仍然是日常的压力。(关于更名问题,Angular CLI的问题似乎已经被忽略了。重命名/删除/移动组件·Issue #900 · angular/angular-cli)
当然,这并不意味着只要能够通过工具更改名称就行了。问题在于相同的词语(而且稍有不同的形式)出现在各个地方,并且冗长无必要。
无法在(实质上的)一个文件中写入多个组件。
我认为这是一个意外的大问题,严重影响了开发者的体验。(顺便说一句,在编写 Vue.js 的单文件组件时我也有同样的感觉。)
如果你正在使用React或lit-html开发,那么你可以在不改变导出组件的接口的情况下,在文件内拆分或合并组件进行重构。为了缩小变量和样式的作用域,保持组件的粒度小是非常重要的。
在Angular中,这种重构变得非常困难。
-
- 公式のスタイルガイドに「常に従うべきもの」として「サービスやコンポーネントなどは1ファイルにつき1つだけの定義としてください。」というガイドラインがある(Angular スタイルガイド Style 01-01)
-
- ファイル内でしか使えないコンポーネントを作るためには、そのファイル内に NgModule も合わせて記述しなければならない(コンポーネントの公開範囲が TypeScript のモジュール単位ではなく NgModule 単位であるため)
- そもそもコンポーネント定義コードが冗長すぎて、ひとつ定義するだけでファイルを区切るだけの大きさになる
由于这个限制,Angular 中分割组件的动机减弱了,每个组件往往变得更大。当组件变得更大时,它们更难以维护、更难分割,并且可能会变得更加庞大。
使用Angular编写组件非常痛苦。
一个组件定义需要3个文件吗?
在Angular中,不仅无法将多个组件写入一个文件中,而且默认情况下每个组件定义需要分成三个文件(HTML模板、样式表、脚本)。每次都要跑来跑去处理这三个文件(加上测试就是四个文件),真的非常麻烦到让人发疯。
当然,我们没有必要接受这种荒谬的默认设置。如果要使用Angular,我们应该使用单文件组件。这样可以提高代码的可读性。例如,在文件内搜索就可以找到HTML元素和应用的样式,还可以使用多重光标选择(多个光标)来轻松进行替换。如果在VS Code中安装angular2-inline扩展,还可以进行语法高亮和代码补全。如果你觉得使用单文件组件会让文件过大,那么很可能这个组件承担的责任过重。与将HTML模板、样式表和脚本分离成不同文件相比,应该考虑拆分组件本身。
(3) HTML模板语法
Angular具有独特的HTML模板语法,例如。
作为与React的比较,我觉得以下表达更合适。
Angular – 将 JavaScript 引入 HTML
React – 将 HTML 引入 JavaScript另一种观点是 Angular 允许在 HTML 中进行编程,而 JSX 则可以从 JavaScript 中生成 HTML。
Angular和React在处理HTML模板结构的语法上有所不同。Angular使用独特的HTML模板语法,在这个世界里编写脚本。而React的代码则完全在JavaScript的世界中运作。
因此,Angular存在以下这些不足之处。
-
- ECMAScript が進歩してもメリットを享受できない
Optional Chaining, Partial Application, Wavy Dot, …
きっと今後も機能が増えていく…
Babel プラグインなどによる機能拡張もできない
独自構文分の学習コストがかかる
(JSX も学習コストはかかるが Angular のそれは比じゃない)
きっと今後も独自機能が増えていく…
(ちなみに Optional Chaining は使えたりしますが Angular 8 現在 array?.[0] が使えないなど不完全な実装になっています)
用Angular编写组件非常痛苦。
(4) 因為DI機構的原因,測試經常毫無意義地故障。
比如,如果某个组件所依赖的“服务”增加,那么即使组件的行为没有改变,组件的测试也会失败。这给日常带来了很大的压力。
有人声称使用DI容器可以更轻松地编写测试,但真的吗?与直接使用Jest或Sinon.JS进行模拟相比,我认为使用DI容器只会增加一些必要的魔法咒语。
首先,DI容器在依赖关系逆转方面是完全不必要的。使用DI容器会引入不必要的复杂性和不透明性。
并且,通过DI容器进行的DI是污染性的。例如,Angular的HttpClient类的实例是通过DI容器提供的。与类似axios的库不同,仅仅引入是无法使用的(这本身就很不方便)。并且使用HttpClient的服务将参与整个模块的依赖关系图。这意味着对于使用该服务的其他服务也会强制使用DI容器(参与整个模块的依赖关系图)。
可能會被認為是什麼不好呢?可能會隨著測試咒語的增加,失去了邏輯的可移植性,使重構更加困難,甚至可以說可能會受到 DI 容器本身的錯誤困擾。像 DI 容器中潛藏的像內存洩漏一樣的錯誤非常難以發現,而且很容易變得致命。(順帶一提,Java EE 的 CDI 的參考實現 Weld 在 Glassfish 4.0 的版本中曾有多個致命的錯誤… DI 容器真可怕…)
我知道有些人非常喜欢使用 DI 容器。像我这样对 DI 容器感到厌恶的人也有。如果 DI 容器的使用是可选的,那就没关系。但由于 Angular 的 API 基本上都是通过 DI 容器提供的,所以强制使用 DI 容器就成了问题。
但是事实上,阻止对 DI 容器的依赖污染的合理方法是颠倒依赖关系。这不是皮肉,只是事实而已。
(5) 强迫使用旧版本的 TypeScript
目前的@angular/cli 8.3.20仍在建议使用TypeScript 3.5系列。尽管已经过去一个月,3.7.2已经发布了,但…如果Angular本身的升级很困难,可能会继续使用非常旧版本的TypeScript。虽然可以通过disableTypeScriptVersionCheck标志来控制…
(6) 响应式编程库 RxJS
有些人可能认为 RxJS 不错。但我认为 RxJS 不好。
使用 RxJS 编写的代码难以阅读。
使用RxJS编写代码非常有趣!
「这像是个谜题呢♪」
「不需要自己保留中间状态啊!」
「还有哪些操作员呢?(知识的空白)」
当你拥有RxJS这个工具时,你会发现所有的事物都像是流一样呈现在眼前。
用RxJS阅读别人写的代码真的很困难…
「这是什么样的谜题…?」
「这段代码到底想做什么呢…?」
「mergeMap() 是什么鬼… 这个 flatMap() 名字真是让人困惑…不对,也许用 exhaustMap() 更合适吧…?」
「怎么没调用 shareReplay(1),这个 map() 会被调用成几万次啊…」
我曾经进行过一次有趣的重构,将前任使用 RxJS 编写的代码转换为纯粹的 TypeScript 代码。这是因为我觉得仅仅在现有的 RxJS 代码基础上添加功能是对品质不负责任的(而且后来可能会变得难以阅读)。对你来说,RxJS 可能只是一种微不足道的简单东西,但是否有可能将其继续交接给像我这样遗憾的责任人呢?
不要对我这个无法掌握 RxJS 的人嘲笑!
在中国只需要一个选项进行本地化后重述:RxJS 容易出错,但很难察觉到错误。
-
- 購読解除(unsubscribe() or complete())漏れ
takeUntil() で解除したつもりが switchMap() で漏れたり
裏で API を呼びつつ重い処理してるつもりが subscribe() するまで呼べてなかった
combineLatest() と withLatestFrom() との取り違え
distinctUntilChanged() 漏れ
shareRelay(1) 漏れ
combineLatest() のグリッチによるチラつき
共通祖先を持つ複数のストリームを結合してストリームを生成すると、イベントの伝搬順序によっては一時的に不正な(意図しない)状態が発生する場合があります。このような現象をグリッチと呼ぶそうです。 RxJS ではグリッチが発生します(発生しないよう気を付ける必要があります)が、 flyd など対策済みのストリームライブラリも存在するようです。グリッチ対策にはランタイムコストがかかるようですので対策すべきとも言い切れません。
https://en.wikipedia.org/wiki/Reactive_programming#Glitches
https://github.com/paldepind/flyd#atomic-updates
也许对于 RxJS 的高级使用者来说,他们可以想象出更多更容易出错的代码。麻烦的是,这些代码在运行时往往能正常工作,导致错误和性能问题的发现被延迟了。
学习成本非常昂贵.
据说仅仅操作员就有100个以上的选择。不仅数字庞大,而且每个都需要相当长的时间来掌握(也有人说这只是因为我的大脑不够强大)。
此外,scan()、publish()、mergeMap()等API的命名太过通用,导致其行为难以联想和记忆(也可能是因为我记性不好)。首先,从Hot和Cold这两个模式的名称来看…
码的多样化
根据不同书写习惯和技术水平,编码的质量和样式可能会有很大差异。
反应式编程的问题?是RxJS独有的问题吗?
我认为之前列举的 RxJS 的问题更多是属于 RxJS 特有的问题,而不是反应式编程的一般性问题。
第一次接触到.NET反应式扩展时,听说可以像LINQ一样使用接口处理间歇性时间序列事件的时候,我感到非常震撼。不过,RxJS…
为什么 Cycle.js 的作者需要费心重新发明流数据库呢?
安德烈·斯塔尔兹 – 我们为什么构建了XStream?
https://staltz.com/why-we-built-xstream.html
为何仍要选择 Angular 的原因
因为选择多个库进行组合似乎很麻烦。
“用 React 构建 DOM,使用 Linaria 进行 CSS-in-JS,可能还需要 axios,用 TypeScript 进行类型检查并使用 Babel 进行编译,使用 Rollup 作为模块打包工具,使用 ESLint 进行检查,使用 Jest 进行单元测试,是否需要使用 Redux 进行状态管理呢?如果只是使用 Mobx 的话,可能可以考虑用 Vue.js 了… 可能还是用 Vue.js 吧,但是…”
在经过大量的研究、尝试和困惑后,最终选出的库集合。即使如此,我还是感觉可能会后悔。问题在于,这里的困难并不是环境建设的复杂性,而是决策的艰难性。
如果选择使用Angular,那么就只需要决定是否使用NgRx。
另外,如果要結合許多庫,因為每個庫都有各自的版本,所以在半年的時間內可能會有一兩個主要版本更新。版本更新的週期也會變得更加難以預測。(然而,每個庫版本更新的影響應該是非常小的。)
那么选择Angular吗?
我不选择 Angular。
首先,如果您创建一个小型专用库集合,那么当出现问题时,您可以通过部分替换进行修复,这是一种保险措施。
例如,如果您使用React创建并遇到问题,您可以尝试使用Preact或Inferno。如果lit-html存在问题,您可以尝试使用hyperHTML或lighterhtml来代替。如果Linaria不适合您,您可以考虑使用emotion或styled-components。如果真的需要,您甚至可以自己制作一个小型专用库。
选择Angular可能无法回头。Angular存在一个叫做”Angular的决定问题”。
然后,在我选择图书馆时最烦恼的点实际上是状态管理。不管选择Angular,还是选择使用NgRx,都会面临最令人烦恼的抉择点。
用Angular写组件最痛苦了。测试失败更加痛苦。作为一个JSON着色员的日常生活变得不幸。
尽管如此,我仍然选择 Angular 的理由。
我对谷歌充满信任。
我理解你的感受,但你是否有一种谷歌总是轻易放弃各种事物的印象呢?
谷歌墓园 – Google 的祭拜者
https://killedbygoogle.com
顺便提一句,好像以前有一个类似高分子的库… (我很喜欢 lit-html)
不过,AngularJS似乎非常努力进行支持呢。Angular可能是受到了AngularJS的教训而开发出来的主要解决方案。如果能够忽略之前提到的问题,信任Google的话,Angular可能会成为选择之一。
开发团队中有人具备Angular的经验,但没有其他与前端相关的知识。
在这种情况下,Angular是一个比较保险的选择。
从AngularJS迁移
不管怎么想,虽然看起来不同,但可能与React等相比较容易迁移吗?很抱歉,我对此不了解。
我听说它适合大规模开发。
那是谎言。由于太长,我省略了一些句子。
Angular 适合大规模开发吗?
我看到了有这样论述的文章,但是它们没有完整地描述根据,要么只凭借Google的权威性,要么并不需要是Angular,简直就是错误的。
我查看了一些关于「Angular 大规模」的搜索结果。
Angular为什么适用于大型应用程序开发?而Angular兼容的商业UI组件”Wijmo”有哪些优势? [PR] – Publickey
请提供您需要转换的具体文本部分,以便我可以为您提供准确的翻译。
为什么Angular适合大规模开发?这个问题直截了当,但内容很薄。它提到了延迟加载和差分渲染,但当然其他框架和库也可以实现这些功能。
通过全面标准化和教育,Angular也可以在大规模开发中发挥其强大的力量——野村综合研究所的《Tools之都报告》- GrapeCity.devlog
https://devlog.grapecity.co.jp/entry/2018/08/06/forest-of-tools-nri 的内容为“NRI的工具荟萃”,请查看该链接获取详细信息。
据说,我们发现通过使用TypeScript和组件化,可以在Angular中期待高生产力和高质量,这使我们决定采用Angular。
也许这里提到的对比对象可能是原生的 JavaScript 或 jQuery。从这个意义上说,引用这篇文章可能是错误的。但是,这篇文章有趣的地方在于看起来是在宣传 Angular,实际上却在批评 Angular。
課題:
在使用Angular的应用程序中,“可行的事情”很多,即使在获得一个结果的时候,开发人员可以采用各种不同的方式。这种灵活性给项目带来了混乱的局面。对策:
据说NRI制定了与编码相关的标准化规则,通过赋予处理方法和时间的一致性,避免了这种情况的发生。
在会议中,作为标准化的具体例子,介绍了包括100多个项目的作业清单,详细定义的开发指南,以及可以通过复制和粘贴确保获得相同结果的示例代码集。
这个对策真的是好的吗?这样做的工时难道不能用在其他事情上吗?比如Lint规则的开发或者选择Angular以外的选项。
选择前端框架(React、Vue.js、Angular)时的要点 | KEYPOINT – Key Point株式会社开发日志
请在以下网址查看相关内容:https://www.key-p.com/blog/staff/archives/107055
在全套技术中几乎包含了所有模块,并且由Google维护的Angular的稳定性毋庸置疑地超过其他框架。
你只是依赖于Google的权威,对吧。几乎所有的模块是什么意思呢?不过你肯定没有预料到会被这样截取。感觉有点抱歉。
大规模在真实世界中使用Angular – Speaker Deck
请用中文转述以下内容,只需要一种选项:
请看连接中的网页,该网页介绍了实际场景下的大规模Angular使用。
在这个幻灯片中,并没有提到Angular适合大规模开发的观点。就这个幻灯片的论述而言,我基本上和你持有相同的意见。
首先就是不进行大规模开发
对对对。
画面之间的切换通常相当于页面刷新。
每个人各自。
我的观点
组件定义的痛苦和 RxJS 的问题(难以记忆、难以阅读、容易出错、代码变得复杂),以及每6个月的版本升级对规模越大的影响越严重,所以在大规模开发中,Angular 的危险性变得更加明显。
总结
不仅仅是对Angular本身的批评,还涉及到DI容器和RxJS,这可能导致了过多的敌人,但这是我坦率的想法。
Angular 不值得推荐。
如果只是要选择一个安全的选项的话,那就是 React。至少在 Vue.js 3 还没有流行起来之前是这样。(相反,如果不追求安全性的话,那么除了选择主流的 Angular 外,还有很多其他选择,比如 Svelte、Cycle.js、Vanilla JS、Elm、ReasonReact、FlutterWeb、AngularDart 等等。)
请参考 npm 趋势。
@angular/core 对比 react 对比 vue | npm 趋势
https://www.npmtrends.com/@angular/core-vs-react-vs-vue
如果挑选并组合库太困难而且不可行的话,我认为Next.js会成为首选。虽然我没有在Next.js上开发的经验,所以我不能自信地推荐它,但我有同事很喜欢并且在使用Next.js。
以上就是现场所见的全部内容。
2020年2月3日添加
由于《2019 年 JavaScript 状况报告》显示出 Angular 使用者的痛苦之情,因此我要介绍一下。作为撰写这篇文章的人,我感到“太好了!我不是唯一一个!”这给了我勇气。
请将以下内容用中文进行改述,只需提供一种选项: