我應該選擇 Angular 還是 React?現在JS框架兩強的格局讓許多開發者選擇起來很糾結。無論你是一個正在思考如何入門的新手,還是一個為下個項目挑選框架的設計者,或是一個架構師為公司做長遠的規劃,你都有可能從學習這個主題中受益。
為了節省你的時間,提前做出如下聲明:在哪個框架更好這個問題上,本文不會給你一個明確的答案。但是,不想其他類似主題的文章。我不能告訴你答案,是因為一項特定的技術是否適合你的開發環境和使用場景取決于多種因素。
由于不能直接回答這個問題,我們會嘗試從其他的方面進行解釋。我們將會通過對比 Angular(2 ,不是老版本的AngularJS)和 React 來演示在兩個類型相似的框架中,如何選擇并調試適合自己環境的框架。你知道的,“授人以魚不如授人以漁”。這樣在以后,當這兩者被更好的框架取代的時候,你能再次用同樣的思路做出最優的選擇。
在選擇任何工具之前,你都需要回答兩個簡單的問題:“它本身是好的工具嗎?”,“它是否適合我的使用場景?”他們本身沒有什么意義,所以你需要把這兩個問題時刻放在腦海中。好吧,問題可能不是那么的簡單,所以,我們嘗試把他們分解成一些小的問題。
工具本身的問題:
自我反思的問題:
用這一系列問題,你可以評估任何工具,而我們將以 Angular 和 React 為基礎進行比較。
還有另外一件事我們需要說明。嚴格來說,拿 Angular 比較 React 不是完全公平的,因為 Angular 是一個成熟、功能完備的框架,而 React 只是一個 UI 組件庫。為了彌補差距,我們談論 React 的時候,包含了一些它經常使用的庫。
作為一個熟練開發者的主要能力就是能夠在舊技術和前沿技術之間保持平衡。慣例是,當采用還未成熟的新工具時,應注意一些風險:
React 和 Angular 都有良好的出身,所以從這方面來看,我們是沒必要擔心的。
React 是由 Facebook 開發并維護的,并且用在了他們自己的產品線上, 包括 Instagram 和 WhatsApp. 它已經出現大約 3年半 了, 所以它已經不算新了。它也是Github上最流行的庫之一 ,在撰寫本文的時候,它大約有60,000多個 star。聽起來不錯。
Angular(2及以上)出現的比 React 晚一點,但是如果算上之前的版本 AngularJS,情況就反過來了。它主要由 Google 維護并且用在AdWords 和 Google Fiber 產品上,很明顯他們對此很有信心,顯然它不會短時間內消失。
像前文提到的,Angular 比 React 多些開箱即用的特性。這是有兩面性的,取決于你看待它的角度。 兩者的核心功能是相似的:組件,數據綁定和平臺無關的渲染
Angular 提供了很多現代 web 應用所需的開箱即用的特性。一些標準特性是:
當你自己不想花費時間去挑選類庫的時候,有這么多開箱即用的特性是很方便的。 而這也意味著你被它們束縛在了一起,即使你不需要它們。并且,通常替換它們需要付出更多的努力。例如,考慮到依賴注入可以用引入來替代,我們相信使用它的小的項目相對于收益會付出更多的開銷。
使用 React,你的入門更加簡單。如果我們只看 React,那么只有:
特性不多,未必不是好事。這意味著根據需求選擇第三方類庫的時候,你有更多的自由度。不好的是你不得不自己做出選擇。經常與 React 一起使用的流行類庫有:
我們擁有了選擇類庫時的自由。這讓我們可以根據每個項目的特定需求來調整我們的技術棧,并且不會產生很高的學習成本。
回顧一下兩個框架的特性,讓我來看一下有哪些流行的高級概念。
當研究 React 的時候,有一些重要的概念涌上心頭:JSX,Flow,Redux
許多開發者對 JSX 持不同的看法:有的人喜歡它,有的人認為這是技術的巨大退步。不是遵循內容與邏輯分離的傳統方法,React 決定用一種類 XML 語言把兩者組合在一起放到組件中,這樣你可以在 JavaScript 代碼中直接編寫內容標記。
雖然關于標記和邏輯混合寫法這個話題是有爭議的,但是它有一個明顯的優勢:靜態分析。如果你的 JSX 標記中有錯誤,編譯器不會保持沉默,它會報出這個錯誤。這能幫助我們立即發現拼寫錯誤和其他一些愚蠢的錯誤。
Flow也是由 Facebook 開發的一款 JavaScript 的類型檢查工具。它能解析代碼并檢查一些常規的類型錯誤,像隱式轉換或空引用。
不像有著相似目的的 TypeScript,它不需要你遷移到一個新語言并且通過注釋你的代碼來進行類型檢查。對 Flow 來說,類型注釋是可選的,可以當做分析器的額外提示。如果你想用靜態代碼分析,但又不想重寫已有的代碼,對此而言 Flow 是一個不錯的選擇。
[擴展閱讀: Writing Better JavaScript with Flow]
Redux 是一個清晰的管理狀態變化的類庫。它受 Flux 的啟發,但是做了一些簡化。Redux 的核心思想是用單個對象來代表應用的整個狀態,該對象被叫做 reducers,通過函數實現。reducers 是純函數,通過組件分別實現。這能更好的做到關注點與測試分離。
如果你正在做一個簡單的項目,引入 Redux 可能會更加復雜,但是對中大型項目來說,它是一個很好的選擇。這個類庫變得非常流行,也可以用在 Angular 項目中實現。
所有的三項特性可以顯著的增強你的開發體驗:JSX 和 Flow 允許你快速的定位潛在錯誤,Redux 幫助你搭建一個整潔的項目架構。
Angular 也有一些有趣的東西,叫 TypeScript 和 RxJS。
TypeScript 是一門在 JavaScript 基礎上,由微軟開發的新語言。他是 ES2015 的超集,并且包含了JS語言即將到來的新版本的一些特性。你能用它替代 Babel 來編寫最新的 JavaScript。它也提供了一個極其強大的類型檢查系統,能夠通過注釋和類型推理靜態分析你的代碼。
還有一個相當微妙的優勢。TypeScript 受 Java 和 .NET 的影響很深,所以如果開發者有那些語言背景,他們會發現 TypeScript 比原生 JavaScript 學起來更輕松(注意我們如何根據個人情況選擇工具)。雖然 Angular 是第一個采用 TypeScript 的主要框架,但它和 React 用在一起,也是可行的。
[擴展閱讀: An Introduction to TypeScript: Static Typing for the Web]
RxJS 是一個響應式的編程類庫,允許對異步的操作和事件做更加靈活的處理。它是利用函數式編程把觀察者模式和迭代器模式混合的組合體。RxJS 允許你把一切都當做是一個連續的流值,并且在此之上實現各種各樣的操作,像映射,過濾,拆分或合并。
該類庫被 Angular 的 HTTP 模塊采用,也在一些內部使用。當你執行一個 HTTP 請求,它返回一個 Observable 替代通常的 Promise。雖然這個庫極其強大,但它也相當的復雜。想要精通它,你需要知道不同類型的 “觀察者”,“主題” ,以及上百種方法和操作符。呀,這看起來只是執行 HTTP 請求的一點小工作。
當需要很多連續的數據流方面的工作的時候,比如 web sockets,在這種情況下 RxJS 是十分有用的,然而,這看起來仍然很復雜。無論如何,當使用 Angular 的時,你至少要對此要有基本的了解。
[擴展閱讀: Introduction to Functional Reactive Programming with RxJS]
我們發現在提高項目的可維護性上,TypeScript 是一個強大的工具,尤其是那些代碼量巨大或業務邏輯十分復雜的項目。用 TypeScript 寫的代碼更容易閱讀與跟進。雖然 Angular 已經采用了 TypeScript,我們仍然希望更多的項目使用它。RxJS,換句話說,看起來只在特定情況下有用并且要小心使用。否則,它能給你的項目帶去難以想象的復雜度。
關于開源框架很重要的事情是圍繞它而衍生出的工具數量。有時候,那些工具甚至比框架本身更有用。我們來看一下這兩個框架最流行的工具和類庫。
現代框架的流行趨勢是通過一個命令行工具來幫助初始化項目,而不必親自配置。Angular 的工具叫 Angular CLI。它允許通過一系列的命令來生成和啟動項目。所有與創建應用,啟開發環境,跑測試有關的腳本都被巧妙的隱藏在叫 node_modules
的文件夾中。你也能在開發期間通過它生成新的代碼。這使得創建新項目十分的簡單。
[擴展閱讀: The Ultimate Angular CLI Reference]
Ionic 2 是一款用來開發移動端混合應用的流行框架的新版本。它提供了一個完美集成了 Angular 2 的 Cordova 容器,和一個漂亮的組件庫。通過它,可以輕松的創建移動端應用。如果相比原生應用更傾向于混合應用,那么它將是一個不錯的選擇。
如果你鐘愛于 material design,你可能很高興聽到 Material 組件庫可以用于 Angular。雖然當前得到了諸多支持,但其仍然處于早期階段并且有點簡陋,所以,我們希望不久的將來能有所改善。
Angular universal 是一個種子項目,被用來創建支持服務端渲染的項目。
@ngrx/store 是受 Redux 啟發,利用 pure reducers 基于狀態突變,用于 Angular 狀態管理的類庫。通過集成 RxJS,可以利用變化偵測策略達到更好的性能。
[擴展閱讀: Managing State in Angular 2 Apps with ngrx/store]
這里有更多的類庫與工具 the Awesome Angular list.
Create-react-app 是用于快速創建 React 項目的命令行工具。跟 Angular CLI 相似,它允許生成一個新項目,啟動開發服務和打包。它用 Jest 做單元測試,一款來自于 Facebook 的比較新的測試工具,本身有一些好的特性。它也支持通過環境變量做靈活的應用分析,本地環境的后端代理,Flow,和其他特性。更多內容請查看 introduction to create-react-app
React Native 是由 Facebook 開發的,用 React 編寫移動端原生應用的平臺。不像提供混合應用的 Ionic,React Native 提供真正的原生界面。它提供了一套用于綁定原生控件的標準 React 組件。也允許使用Objective-C,Java 或 Swift等原生代碼編寫的組件綁定到它們上。
同樣,這是用于 React 的 material design 組件庫。跟 Angular 的版本相比,這個更加成熟并且已經有很多可用的組件。
Next.js 是用于 React 應用在服務端渲染的框架。它提供了一個靈活的方式在服務端全部或部分渲染應用,返回結果給客戶端并繼續保持在瀏覽器中。它嘗試完成一項復雜的任務,盡可能簡單的創建一個通用應用,所以設置也被設計的盡可能簡單。
MobX 是一個管理應用狀態的可選庫。代替在一個單一穩定的倉庫中保存狀態,就像 Redux 所做的,它鼓勵你盡量存儲所必須的最小狀態并且推導出剩下的。它提供了一套修飾符來定義可見性和觀察者和介紹狀態的邏輯變化。
[擴展閱讀: How to Manage Your JavaScript Application State with MobX]
Storybook 是 React 的組件開發環境。它允許快速的創建單個應用來展示你的組件。在此基礎上,它還提供了許多組件來記錄,開發,測試和設計你的組件。在應用的其他部分,我們發現它在獨立開發組件上是極其有用的。在上一篇文章中,你能學到 關于 Storybook 的更多知識。
這里有更多的類庫與工具 the Awesome React list.
選擇一項新技術的重要標準就是學習它有多么的容易。當然,答案取決于很多因素,比如你之前的經驗,熟悉相關的概念和模式。不管怎樣,給定一個框架我們仍然能評估必須學習的新東西的數量?,F在,我們假設你已經了解 ES6 ,構建工具和所有的這些,讓我們看看你還必須要理解什么。
使用 React 遇到的第一個障礙就是 JSX。對有些開發者而言,它寫起來頗為棘手,然而,它并沒有增加太多的復雜性;就像真正的 JavaScript 表達式,和特殊的類 HTML 語法。你也需要學習如何編寫組件,用屬性來配置和管理內部狀態。你不需要學習任何新的邏輯結構與循環,因為所有的這些都是原生 JavaScript。
官方教程是入門 React 的優秀資源。一旦你完成了它,那么開始熟悉路由。React 路由 v4 版本可能有一些復雜和特別,但無需擔心。使用 Redux 需要轉變范式,學會利用類庫建議的方式完成已經熟悉的任務。免費視頻教程 Getting Started with Redux 能夠幫助你快速熟悉一些核心概念。根據項目的大小和復雜度你可能不得不尋找和學習一些額外的類庫,這可能是比較棘手的部分,但在這之后,一切都會順風順水。
我們很驚喜入門 React 是如此的簡單。甚至有后端經驗和前端經驗有限的人都能快速上手。有完善清晰的錯誤提示,并且提供了如何解決潛在問題的解釋說明。最難的部分可能就是為所需功能尋找合適的類庫,但構建和開發一個應用真的十分簡單。
學習 Angular 需要比 React 了解更多的概念。首先,你需要熟悉 TypeScript。對于有靜態類型語言像 Java 或 .NET 使用經驗的開發者來說要比 JavaScript 更好理解,但對純 JavaScript 開發者而言,可能需要付出一些努力。
框架背身就有很多主題需要學習,從基礎的開始像模塊、依賴注入、裝飾器、組件、服務、管道、模板和指令,到高級主題像變化偵測、區塊、AoT編譯和 RxJS。這些此文檔中都可以找到。RxJS 本身就是很繁重的主題,在官方網站上有更多的描述。雖然從基礎水平上使用它比較容易,但要使用高級主題會十分的復雜。
總而言之,我們注意到使用 Angular 要比 React 難得多。眼花繚亂的新概念對新手來講十分的困惑。即使你已經入門了,你也需要時刻注意像 RxJS 訂閱管理,變化偵測性能和未知的東西(是的,這是來自文檔實際建議)。我們會經常遇到難以理解的錯誤信息,所以不得不經常檢索它們并祈求得到一個精準的匹配。
這看起來好像我們更傾向于 React,的確是。結合我們利用同樣大小和復雜度的 Angular 和 React 項目,對新手開發者進行培訓的經驗,React 更加的順滑。但是,像我之前所說的,這取決于多種因素,可能對你來說會有所不同。
你可能已經注意到每個框架都有它本身一系列的功能,有好的也有壞的。但在特定環境外的分析已經完成并且沒能在選擇哪個框架上給出答案。為了做出決定,你不得不從你自己項目的角度來考查它。這些事情需要你自己來做。
現在,結合你的項目試著回答下面這些問題,順便想想是否符合關于這兩個框架你已經學到的特性。列表可能還不完全,但是應該夠開始討論了:
如果你打算啟動一個大項目,你可能想最小化做出不當選擇的風險,首先考慮做一個概念性的驗證產品。使用框架,通過簡單方式,試著實現項目的一些關鍵特性。這通常不會花費你太多的時間,但會給你一些有價值的經驗來驗證關鍵技術需求。如果你對結果滿意,你可以繼續進行完整的開發。如果不滿意,從長遠來看其實節省了你的時間。
一旦你為你的項目選擇了一個框架,你將會在接下來的項目中忍不住的想用同樣的技術棧。不要這樣。雖然保持技術棧統一是一個不錯的注意,但不要總是使用同樣的方法。每一個項目開始之前,花點時間再回答一遍上面的問題??赡軐ο聜€項目而言,答案就不一樣了。另外,如果你想用不熟悉的技術棧做一個小項目,做吧。這些經歷會帶給你寶貴的經驗。開放你的思維,并且從錯誤中不斷學習。在某一點,一項特定的技術會讓你自然而然的覺得正確。
此文由同行 Jurgen Van de Moere 和 Joan Yin 校對. 謝謝 SitePoint 所有的校對人員,你們讓 SitePoint 的內容更加的優秀!