初探 Backbone.js
Backbone.js 是一套前端 Javascript Framework,它提供 MVC 架構,包含了 Model、View、Controller來讓使者操作。Model提供了key-value 結構,以及可以 binding 大量 event,開發者可以透過 RESTful JSON interface 來跟 Backbone.js 的 Model 及 Collection 搭配。
· Model:可用來設置和獲取 data (例如:men Model)
·
Collection:某一類型 model 的有序集合 (例如:people Collection,包括 men & momen model )
· View:操作 Model 與 DOM 的互動與呈現 (例如:men
run),可以綁定既有的 DOM 或是自己新增 DOM
· Controller:負責分派 model 與
view 之間的商業邏輯
Backbone 優點
1.
檔案很小
2.
可以將所有的state 和 model 放在同一個地方
3.
model 的任何調整,可以自動同步到UI (不管有幾個地方需要同步)
4.
較好維護的程式碼結構
5.
較少的 “耦合程式碼”
6.
龐大的社群以及文件可參考
----------------------------------------------------------------------------------------------------
初探 RequireJS
一直以來,我們都習慣使用 script 這個 HTML 標籤來載入
JavaScript 檔案。這種方式有兩種缺點:
1. 無法在 JavaScript 程式中直接管理相依性,必須在 HTML 中處理。
2. 雖然目前新式瀏覽器已經能夠以非同步的方式來載入 js 檔案,但是舊型瀏覽器還是會有阻塞 (blocking) 問題。
終於 CommonJS 提出了 AMD 這個 API 規範,用以讓我們的 JavaScript 程式可以模組化,並同時解決 js 檔案載入時的阻塞問題。目前已經有許多實作 AMD 規範的 JavaScript Library 了,而 RequireJS 則是目前討論最多,應用最廣的其中一個實作。
什麼是AMD?
AMD 提出了一種基於模組的非同步載入 JavaScript 代碼的機制,它推薦開發人員將 JavaScript 代碼封裝進一個個模組,對全域物件的依賴變成了對其他模組的依賴,無須再聲明一大堆的全域變數。通過延遲和按需載入來解決各個模組的依賴關係。模組化的 JavaScript 代碼好處很明顯,各個功能元件的松耦合性可以極大的提升代碼的複用性、可維護性。這種非阻塞式的並髮式快速載入 JavaScript 代碼,使 Web 頁面上其他不依賴 JavaScript 代碼的 UI 元素,如圖片、CSS 以及其他 DOM 節點得以先載入完畢,Web 頁面載入速度更快,使用者也得到更好的體驗。
傳統 JavaScript 代碼的問題
讓我們來看看一般情況下 JavaScript 代碼是如何開發的:通過
<script> 標籤來載入 JavaScript
檔,用全域變數來區分不同的功能代碼,全域變數之間的依賴關係需要顯式的通過指定其載入順序來解決,發佈應用時要通過工具來壓縮所有的 JavaScript 代碼到一個檔。當 Web 專案變得非常龐大,前端模組非常多的時候,手動管理這些全域變數間的依賴關係就變得很困難,這種做法顯得非常的低效。
簡單來說(範例一)
最早的時候,所有Javascript代碼都寫在一個文件裡面,只要加載這一個文件就夠了。後來,代碼越來越多,一個文件不夠了,必須分成多個文件,依次加載。
假設網頁原本執行main.js前,需要讀取 a.js,b.js,c.js,d.js,原始碼如下:
--main.js--
這樣的寫法有很大的缺點
首先,加載的時候,瀏覽器會停止網頁渲染,加載文件越多,網頁失去響應的時間就會越長;
其次,由於js文件之間存在依賴關係,因此必須嚴格保證加載順序,比如上例的a.js要在b.js的前面,依賴性最大的模塊一定要放到最後加載,當依賴關係很複雜的時候,代碼的編寫和維護都會變得困難。
利用requireJS的情況下,可以將程式碼修改成如下:
--require.js—
這指令除了會協助載入require.js 以外,還會自動幫讀取main.js。只要修改data-main="檔名.js"就可以讀取其他任意JS,例如:data-main="my",便會自動讀取my.js。
將著我們需要對main.js做以下修改,在main.js裡引用a,b,c,d,如下圖:
--main.js—
--main.js—
透過這樣的方式可以由系統幫你載入 a.js,b.js,c.js,d.js 4 個 JS 檔,
require.js的誕生,就是為了解決這兩個問題:
(1)實現js檔的非同步載入,避免網頁失去回應;
(2)管理模組之間的依賴性,便於代碼的編寫和維護。
模組化(範例二)
當把所有的程式邏輯都寫在 js/main.js 的 callback 裡面是沒問題的,但那就沒辦法達到我們想要的模組化了。
而 RequireJS 也實作 AMD 所定義的 define API 方法,所以我們就可以用它來實現程式的模組化。 define 的 API 如下:
其中 id 格式為字串,代表模組的名稱,可以不寫。如果要寫的話,就必須是相對於 js/main.js 的檔案路徑,但不用加上 js 副檔名,例如 ../lib/foo 或 ./js/bar 。
而 dependencies 格式為陣列,作用與 require 中的 dependencies 相同。一般來說如果我們在 js/main.js 中定義好相依性後,這裡可以不需要特別指定。
最後的 factory 則為一個工廠方法,它必須回傳一個物件,也就是我們的模組。
接著我們把原來 require API 中的 callback 改成模組,並將它放到 js/app.js 中:
--js/app.js--
js/app.js 會回傳一個包含 initialize 方法的物件模組,而這個方法就是我們前面的 callback 。注意這個例子裡並沒有設定模組的 id 。
接下來我們把 js/app.js 加到 require 的第一個參數中,特別注意這裡的 app 是指 js/app.js ,而不是模組名稱。
--js/main.js--
在 callback 的第一個參數 App 會對應到 js/app.js 中所回傳的物件,這意謂著我們可以為該物件指定新的 namespace 。
到這裡其實可以應付很多基本的應用了,不過如果當 library 間有相依性問題時,這樣的寫法就可能會出錯了。
心得
以往在寫
JavaScript 時,雖然都會儘可能模組化,但變數的管理還有程式拆解不易的狀況,都是自己在維護
JavaScript 程式時很大的痛處。
在瞭解 RequireJS 的強大後,我相信以這樣的模組化方式再搭配 Backbone.js 的架構,一定可以讓系統在開發與維護上更為有組織性。






沒有留言:
張貼留言