一些關於前端Framework的想法(中)
接續一些關於前端Framework的想法(上)而來,我們來看看…
DOM Manipulation framework/library
jQuery、Backbone.View、React.js and Batman.View
我想每個接觸網頁開發的程式人都一定用過jQuery,它提供什麼好處?
- 簡單的API:$node.remove() instead of node.parentNode.removeChild(node)、$.ajax、$node.on……
- Cross-browser compatibility. 至少在遠古時代以來這點一直沒變過。不過我倒是真的好奇現在的幫助有多少?
而Backbone.View與Batman.View則是在基於jQuery element的概念上,提供一層抽象層封裝邏輯;React.js我們稍後再談。
我必須承認,由於我對Native DOM API實在稱不上熟,因此我在這個問題的選擇會傾向至少要使用jQuery,我認為在輕量的網頁開發上,使用jQuery的確可以獲得不少好處,加快開發速度與減少後續的維護成本。
若是要使用Backbone.View或是Batman.View,通常是在中大型網站上才會開始考慮,原因?
- 封裝程式邏輯:如AwesomeCheckbox、TodoItemView、TodoListView等,把該部分用到的內部邏輯用Class封裝起來,並且提供給外界適當的API來操作
- 達成復用性:架構一大,許多東西就會一直重複出現,如果可以把這些東西封裝好,可節省開發時間。
基於上述理由,選定一套Framework通常是必要的。且通常中大型系統會牽涉到多人協作,有一套文件良好的Framework作為共同的溝通語言,會讓開發效率不至於減少太多。注意:開發效率是不會提升的,只能盡量減少消耗;另外在這裡也沒有要談針對新手會不會更好上手的問題,我們假設團隊成員與日後接手的人JS程度相近。
但是,很不幸的,我們以為的優點通常都不會成真,在我個人有限的經驗中,「封裝程式邏輯」通常會失敗,因為所謂的程式邏輯,其實指的就是該元件的狀態,而元件的狀態由以下幾點決定:1. 初始值 2. 使用者輸入 3. Programmatic API,同時有這三種自由度構成的元件,通常最常發生的一件事就是:我頭腦亂掉了#$%^*(!*&^%$#)*&(^%$#@!
再來,「達成復用性」就更可笑了,最常看到的情況是,直接複製一份Code然後再做點些微修改,理由?常常聽到的是,如果在這邊要復用原本的程式碼,我們必須對他進行相當的重構,這件事情的成本太高,現在沒辦法做。……
別懷疑,以上事件真實發生過,我相信各位一定有類似的經驗。我們常以為挑了一套順眼的Framework,開發工作就會一帆風順如期完成,很遺憾地,我們還在21世紀初,人工智慧尚無法取代人類開發。
啊!剛剛是不是忘記React.js,那我們就來看看React會遇到的問題好了。……等等,React不會遇到這兩個問題啊!你會問:這怎麼可能?!也讓我依據有限的經驗來說看看:
封裝程式邏輯
React.createClass 的方式來產生一組Component元件(native ES6 class support is on the road),這點跟其他Framework很像,但是React對待元件狀態有嚴格規定:
- this.props為given properties (by owner),不能修改,也不應該被修改
- this.state為自身的狀態物件,所有的狀態都源自於此(也只該源至於此,否則就是你的問題)
React透過Framework給出強烈的約束行為,限制你的思考方向,因此我們較容易寫出清楚的程式碼:因為狀態的來源只有一個this.state。也因為我們減少狀態來源到只有一個地方(Single Source of Truth!),元件封裝變得容易許多,邏輯部分也只要搞清楚this.state的變化就好。
達成復用性
基於「封裝程式邏輯」的理由,我們剛剛講了this.state被封裝在元件裡面,因此對於使用這個元件的人(owner)而言,它要怎麼去影響元件的狀態?其實就是根據owner傳進去給該元件的props來決定。你可以說,當你決定好這個元件要回應哪些props的時候,介面就已經訂完了,復用性根本連想都不必想,它已經內化在整個React的核心價值,寫好一個元件後,復用性就在那裡:各位,我們準備好了。
你會想,不,哪有那麼好康的事?事實上,正因React完美達到這兩個聖杯,幾乎所有在這裏撞到牆的Web Developers,一使用後便瘋狂的愛上它,社群幾乎是瞬間飆漲起來,非常之可怕。我誠摯的推薦大家好好的玩一下React,新一波的技術革命正在醞釀!