AngularJS 的缺點

青牛發表於2015-07-04

當一項新技術出現的時候,有時讓我們著迷,而且讓我們覺得它一切皆有可能。

正如我們觀察到的,該項技術在某些方面超出我們的預期,我們開始相信我們可以相對容易地在任何地方使用該技術。然而實際經歷證明:這簡直就是自找苦吃!我們 thoughtworks.com 技術團隊使用 AngularJS 去實現 “interactive tech radar”,我作為其中的一員,談談我的一些使用體會。

一點兒背景資訊

我們有一個 Ruby,Sinatra 和 Plain JavaScript 的技術架構。關於專案開發堆疊的背景資訊,你可以在 Andy Robinson 所寫的文章中找到。指導原則的其中一項是,程式碼庫的維護是通過最大限度地減少意外的複雜性來實現的。因此,結論就是,我們力求用庫,而不是框架。一個具體例子就是選擇 Sinatra 而不是 Rails,主要是因為前者作為一個框架,比後者輕得多。

“interactive tech radar” 專案是用 AngularJS 實現的。選擇 AngularJS 可以快速開發出最小視覺化原型(MVP)產品,可以實現更豐富的客戶端互動。比起我們之前充滿文字的靜態頁面,最終產品的使用者體驗會有極大的提升。

實戰故事

首當其衝的影響出現在我們的構建階段。AngularJS 的引入,明顯增加了測試的時間。我們的測試工具集(RSpec, Capybara, PhantomJS)很適合我們現在開發的程式:多頁面應用程式,一個頁面裡面只有有限的(但會越來越多)JavaScript 互動。AngularJS 的引入,讓我們直接面對一個有趣的挑戰:我們如何去測試需要跨越多個頁面進行 JavaScript 互動的單頁面應用?使用 AngularJS 特定的工具像 Protractor,意味著要引入一個新的測試工具集,和當前的測試工具集一起並行工作。維護兩個不同的測試工具集,增加了複雜性,而又似乎不會得到什麼好處。我們最終使用了 AngularJS 相容的測試工具集(例如 capybara-angular)。由此開始顯現了使用 AngularJS 的一個缺點:不能和非 AngularJS 特定的工具或其它程式設計庫一起使用。

進入第二輪迭代時,更多的功能和錯誤修正出現在工作列表上。在我們著手解決這些問題時,我們感覺到了由學習曲線陡增所帶來的壓力。隨著我們對 AngularJS 理解的深入,即使較小使用者故事也要花費好幾天時間。儘管我們對此已有預判,但仍低估了實際所要花費的時間。主要原因是,由於 AngularJS 框架的本質決定的。像任何其它框架一樣,它擁有自己獨特的世界觀。為了獲得使用框架的最大好處,使用者必須接受和使用它做事的方式。程式設計框架總是神奇和美妙的 - 幫你快速實現 MVP,但長遠來看,你不得不為此在程式碼的維護和進化上付出必要的代價。

在工作中,我們經常發現,解決問題的唯一途徑就是 AngularJS 提供的方式。JS 庫的使用被嚴格限制了。通常,你只能使用屬於其生態系統部分的 JavaScript 工具。例如,基於 jQuery 的庫就不能和 AngularJS 構建的頁面一起很好的工作。我們還發現,使用 JavaScript 做些簡單的事情變得很困難。一個例子就是使用 DOM onready/onload 事件(因為 AngularJS 劫持了這些事件,你不能輕鬆地使用它們)。另一個例子是,谷歌分析不能直接與 AngularJS 一起工作,你必須使用特定的 AngularJS 庫才能使其執行(如 angulartics)。此外,AngularJS 給我們的程式碼引入了 html,這和我們使用 slim 模板語言的目的一樣。出現一組新的工具意味著增加程式碼庫的意外複雜性,這將使程式碼維護和演化變得更加困難。

我們的業務需求之一,就是讓我們的網站對非 JavaScript 使用者可用。這意味著我們必須複製幾乎所有互動資訊(...破壞了 DRY 原則)所有這些都在一個大的 noscript 標籤內!我們看到的另外一個問題是,AngularJS 提供的搜尋引擎優化方案並不理想。有些解決辦法當然可能更好(見 StackOverflow 上的問題),但它們都需要額外的工作。

未來

對於 Radar 專案來說,我們所能預料到下一個問題將在語言國際化方面。這意味著在 JavaScript 中實現國際化機制,需要複製當前我們在 Ruby 中已實現的國際化。鑑於已有的痛苦經歷,我們意識到,隨著業務需求越來越複雜,繼續使用 AngularJS 進行開發,我們將很難應對。在這一點上,似乎未來可能的方法就是去除 AngularJS,使用 Ruby 頁面和純 JavaScript 來代替。儘管這看起來像是一個巨大的任務,工作量會在短時間內飆升,但如果能有效重用現有的一些 JavaScript 和 HTML 程式碼,也就是幾天的工作而已。

結論

雖然我認為所有我們遇到的小問題都有更簡單優雅的解決方案,但它仍然不能改變這一事實,AngularJS 帶來了很多意外的複雜性,卻沒有為它付出而帶來的額外的利益。如果我開發一個單頁面的 JavaScript 應用程式的話,我很樂意採用和學習 AngularJS,但若將其用作其它方面,我會三思而後行。


作者:Mircea MoiseThoughtworks 公司的一名軟體工程師,熱衷 Ruby & 敏捷開發。

原文: AngularJS: The Bad Bits

感謝: Jodoo 幫助審閱並完成校對。

P.S. 如果您喜歡這篇文章並且希望學習程式設計技術的話,請關注一下 復唧唧

相關文章