JavaScript 的輕框架開發

edithfang發表於2014-09-06
為什麼我們不用 Angular, Ember 或者 Backbone!

Muut 是一個特殊的論壇平臺,它也有著巨大的夢想! 當後端的效能已經極大優化的同時,前端也有著自己的目標:簡單API,小體積,快速迭代。寫程式碼就像在紙上先起個草稿,然後寫入到許多檔案中即可(猜譯)。任何一個前端框架,比如,Angular 或者 Ember 都沒問題!

下面是我們自己實現,而不用它們的原因。

首先是 API 方面的因素

開發 Muut 客戶端時,我們基本的要求是簡單的 API。它必須易用,沒有額外的屬性方法,不應該提供新的程式設計習慣(即不要製造另類的程式碼語法)。它應該易上手。不僅終端使用者用它,而且個人也要用它,因為所有的網頁介面都建立在它之上。

開始設計API之前,通常要先打好草稿。一個乾淨的桌子、一支筆、一張紙。我開始站在使用者角度構思API。從沒有一切框架開始。

API 在 MVC 中是一個模組,要用 POJO(Plain Old JavaScript Object) 的形式。因為框架提倡API的設計必須"single source of truth“。API不僅能跑在瀏覽器上,也能在後端(node.js)執行。它必須完全獨立且易單元測試。

我不喜歡交差相關的方法及屬性把API搞雜亂。Backbone.Model.extend 和 Em.Object.extend 都新增了大量的方法,給使用者使用增加了複雜度。違背簡單的目標,它不被我們接受!

小體積

更小的檔案會更快載入,節省頻寬。這是看得見的利益。更大的優勢就是程式碼維護。小程式碼更容易把握,更快學會,更少的條條框框。

目前 Muut 客戶端壓縮後是 89kb,gzipped壓縮後是 32kb。這比其它的論壇平臺要小10 倍。體積明顯很重要,當一半的網路訪問來自於移動裝置,開發人員就會尋找小工具來完成他們的工作。

下面的表會讓你知道,我們使用的具有獨立功能的工具應該是多大的體積。下面列的是我也在使用的,我正好做一下對比,以下均是minified後的大小:

模版、繫結、表單驗證Backbone.js33.9kb語法加亮,支援20+語言Rainbowjs28kb提示,遮罩層,下拉框、標籤切換等Misc. tools20kbWebSocket communicationsocket.io40kbMarkdown 分析器markdown-js23kb

在實際的專案開始之前,這些大概就已經有150kb了。

當前,Muut的包含介面檢視、控制器(api與檢視之間的結合程式碼)等合併後再minified,僅40kb。一個框架應該是多大呢?框架的目標是更小的工作量去達到目標,所以它應該很小。40 kb是容易管理並繼續在之上進行開發。在事情複雜化之前,我還可以增加大量功能。

全面掌控

Muut 使用原生的 pushState 方法來控制URLs,John Resig's "微模版" (6) 來顯示檢視,內部的模型與檢視的互動使用自定義事件。而不使用路由及自動資料繫結的功能。

每個事情都完全按照我們預期的執行,出現bug也容易找到。這裡沒有不可知的,不明道理的程式碼。這裡沒有祕密,並且呼叫堆疊也很淺。我們可以針對特殊需要而去組織程式碼,而這裡沒有固定的框架來控制必須如何做。

不混合程式設計樣式

沒有外部包更新

沒有這依賴hell

每週都能愉快釋出新版本!

特殊需求

Muut客戶端只是一個包含全部HTML程式碼的JavaScript檔案。當檔案載入後它會在一個單獨的anchor(A)標籤中渲染自己。專案的打包與啟動與傳統的單頁面程式有很大不同。

Muut服務端必須能夠隨時通知客戶端。客戶端與服務端以一種點對點的雙向模式進行通訊。

我們通過WebSocket傳送JSON-RPC訊息,而不會考濾使用REST:像Muut這種實時程式不能構建在REST之上,因為REST所採用的是一種請求-響應模式並且它不能理解push事件等東西。

現在的框架,例如ember資料,是面向REST的,並且它們的示例和文件也是基於REST的。WebSocket示例有遺漏,或只是試驗性的。Muut所面臨的挑戰是很獨特的。

技術鎖定

如果你檢視了任何程式語言的框架史你會發現它也是一部失敗史。框架來了又走了。今天的JavaScript框架都很年輕。Backbone, Angular和Ember現在可能很流行,但幾年後就不一定了。

我們來看下Angular (藍), Backbone (黃) 和 Ember (紅)的Goole Trends(谷歌公司的一項搜尋產品) (2):



JavaScript是世界上最流行的程式語言,並且提供了多種程式設計風格。但事物也在以一種不可思議的速度變化著。因此使憤怒的框架社群不斷推翻曾經最好的應用構建方式。

沒有最好的方式.

有許多不同的替代方式,目前Angular正處於巨大的增長之中. "AngularJS允許你的應用程式擴充HTML." 這是最好的方式嗎? Backbone和Ember是否正處於危險的境地?2012年在X框架中有所投入的公司,可能馬上會意識到,他們的開發團隊已經在談論下一個新技術了.作為使用這些框架其中之一的開發者,我擔心他們的生命週期.

另一方面,讓我們來比較一下jQuery和Angular (3):



上面的圖告訴了你jQuery的普及程度.它正在全世界57.2%的網站中使用,其中92.7%的網站的JavaScript庫是公開的. (4) 這裡沒有技術限制.但是作為一個嵌入式應用程式,我們不能期望人們,在已經使用jQuery的網站中,載入其他的框架.

Muut使用了jQuery的全部內容,在設計API的時候,我甚至偷師jQuery.它很簡潔好用.我(依舊)喜歡這點.

為什麼不用 Angular?

Angular 看起來是很有前途的。表面上,我可以用原生的js寫我的模型,讓Angular去渲染到檢視上,且不需要任何膠水程式碼,這看起來非常棒!但有一系列原因讓我不喜歡這個框架。

首先,它和Muut一樣的大小(91kb).但我只想要雙向資料繫結而已,我被迫載入整個框架。它為我提供過多東西。我希望他們單獨做一個資料繫結的模組,讓它更簡單即可。人們也不需要關心內在的實現機制,比如$watch, $apply 及$digest。

儘管它標榜自己是很簡單,但它的API是非常大的。目前它們的文件中邊欄竟有147節內容。那需要麻煩的理解認識過程。我只需要一張空桌子來構建我的工作。

另外,我真的不喜歡把這麼多的邏輯放到檢視中或把我的程式碼包裝後,放到"directives" or "filters"中去.Muut的邏輯只有適當的複雜度,最好用原生的JavaScript就能表達。

為什麼不用 Ember.js?

Ember 是龐大的,恩,就是非常大!minified後的庫大小也是240kb.不用說,它們的API也是龐大的。我從它們的文件的第一節(Modules > Ember)看,只這一節便有80個二級節點。

我最不能接受的是,我必須把我寫的物件用Ember.Object來包裝才能引入API中的方法。

一個大框架使用大量的特有語法是一個冒險的選擇,想想 Enterprise Java Beans吧!

為什麼不用 Backbone.js?

Backbone 在三個中,最小最簡單的框架,minified後大小是33.9kb。它必須依賴 underscore.js庫,這樣它就大於Muut一半的大小了。

我用Backbone的問題是:我不喜歡Backbone組織程式碼的方式。它有太多的樣版,但我喜歡更喜歡寫出簡潔緊湊的程式碼。我完全認同它把API程式碼與UI程式碼分離的觀點,但 Kim Joar Bekkelund的關於把jQuery程式碼轉到Backbone的文章對我毫無意義。對我而言,很難去用它的程式碼。

與Ember一樣,Backbone不能用POJO's,所以你必須用Backbone.Model.extend來包裝你的物件,引入也不必要的框架定義的方法。

在以上面個框架中,Backbone最最保守選擇,它不給你做什麼看不見的工作(Magic),甚至即使它停止開發,你還可以用自己的程式碼去打補丁或替換掉它的程式碼。

最後,作為一個RESTful的框架,它並不能完美地適於於實時通訊的地方。


但jQuery正在變成義大利麵,是嗎?

通常的論題是,在應用程式中堆疊了成千上萬行程式碼後,jQuery地獄將會爆發.這個應用程式沒有結構,程式碼也是一團糟.這並不正確.當API完全從其他程式碼中剝離出來的時候,利用jQuery很容易構建控制器.

通常,我的控制器程式碼像下面這樣:
// controller for a Topic model
function drawTopic(topic) {
  
   // generate new element with micro templating
   var root = tmpl("<div>some html</div>", topic);
  
   // topic elements
   var seed_post = $(".seed", root),
      replies = $(".replies", root);

   // listen to events on model
   topic.expand(function() {
      // do something with the elements
  
   }).collapse(function() {
      // do something else
  
   }).remove(function(post) {
      // etc
  
   }).reply(function(post) {
  
   })...
  
}

這就是我個人組織程式碼的方式.Web應用程式的目標不應該必須限定在DOM,或者物件導向的實踐,或者純MVC模式.一個成功的應用程式應該保持簡單,而不要陷入學術化的怪圈.

總結

正是我們結合了完美主義和極簡主義, Muut是一個極輕量,易管理,和獨立的Web應用集合。 與“從頭構建”的方式一致,它適用於我們的伺服器側程式碼和UX,如果不是在幾年前,能力高超的團隊和許多的人有相同的想法,你就不會看到類似討論平臺的出現。
評論(2)

相關文章