構(gòu)建移動(dòng)Web應(yīng)用程序的技術(shù)堆棧
編寫web應(yīng)用程序時(shí),有很多的技術(shù)決策。筆者最近回來編寫現(xiàn)代Web應(yīng)用程序,并希望總結(jié)一些曾經(jīng)在開發(fā)周期過程中做了記錄零散的想法。這篇文章是關(guān)于一套對(duì)筆者最近開發(fā)的項(xiàng)目有幫助的框架。筆者重溫了一些最重要的框架類型,其中每一個(gè)可以展開來寫一篇文章。這并不是一個(gè)廣泛的現(xiàn)有產(chǎn)品相比,只是一個(gè)筆者最近使用的部分技術(shù)。
雖然筆者的重點(diǎn)是移動(dòng)優(yōu)先, 筆者認(rèn)為,這套技術(shù)可以應(yīng)用在一般的web應(yīng)用程序。 筆者的決定和數(shù)據(jù)支持考慮了幾個(gè)要求:
基于JavaScript(CoffeeScript,Dart,絕對(duì)值得認(rèn)真看看,但我想避免引起激進(jìn)選擇)
必須在現(xiàn)代瀏覽器工作良好(IOS ***ndroid 4)
挑選一個(gè)MVC框架
在本地UI的應(yīng)用程序開發(fā)中模型視圖控制器模式已經(jīng)使用了幾十年。其基本思路是分開表示層(用戶界面,動(dòng)畫,輸入)和數(shù)據(jù)層(存儲(chǔ),通訊,數(shù)據(jù))。有其他類似的模式,如MVVM的(模型視圖的ViewModel),但主要的想法是在展現(xiàn)和數(shù)據(jù)層之間有定義良好的分離,為了更干凈的代碼和長(zhǎng)期的維護(hù):
有許多JavaScript模型視圖控制器框架的產(chǎn)品。有一些如Backbone.js和Spine.js是用純代碼編寫的,而其他像Knockout.js和Angular依靠DOM數(shù)據(jù)屬性綁定。那些依賴HTML5數(shù)據(jù)DOM屬性的分離視圖和數(shù)據(jù)的MVC系統(tǒng)被認(rèn)為是不對(duì)的。這不包括Knockout.js和Angular框架。 spine.js比 CoffeeScript更容易,根據(jù)我最初的要求排除了CoffeeScript。
backbone.js比大多數(shù)框架更受歡迎(也許除JavaScriptMVC外,似乎像一個(gè)死的項(xiàng)目),還設(shè)有一個(gè)成長(zhǎng)的開源社區(qū)。對(duì)于筆者的應(yīng)用程序棧,筆者選擇了Backbone.js。欲了解更多有關(guān)挑選一個(gè)MVC的信息,檢出TodoMVC,它使用不同的MVC框架實(shí)現(xiàn)相同的Todo應(yīng)用程序。還可以看到這個(gè)MVC框架的比較,它強(qiáng)烈贊成Ember.js,一個(gè)出現(xiàn)相對(duì)較晚的框架。筆者尚未有機(jī)會(huì)使用它,但它在我的清單上。
選擇一個(gè)模板引擎
要在網(wǎng)絡(luò)上建立一個(gè)嚴(yán)謹(jǐn)?shù)膽?yīng)用程序,你不可避免地要建立大型的DOM樹。如果使用JavaScript API來操作DOM,不如使用基于字符串的模板編寫html來得更簡(jiǎn)單高效。JS模板已經(jīng)逐步形成一個(gè)奇怪的約定,嵌入模板的內(nèi)容到腳本標(biāo)記內(nèi):。使用所有的模板引擎的基本做法是作為一個(gè)字符串來加載模板,構(gòu)建模板參數(shù),然后通過模板引擎模板和參數(shù)運(yùn)行。
backbone.js依賴于Underscore.js,它有一個(gè)有些局限的有詳細(xì)語法的模板引擎。有其他可供選擇,包括jQuery模板,Handlebars.js,Mustache.js和許多其他的。 jQuery模板已經(jīng)被jQuery團(tuán)隊(duì)準(zhǔn)備廢棄了,所以我沒有考慮這個(gè)選項(xiàng)。Mustache是一個(gè)跨語言的模板系統(tǒng),具有簡(jiǎn)單和成熟的決定,以支持盡可能少的邏輯。事實(shí)上,在Mustache最復(fù)雜的構(gòu)造是遍歷一個(gè)對(duì)象數(shù)組的方式。 handlebars.js建于Mustache之上,加入一些不錯(cuò)的功能,如預(yù)編譯模板和模板表達(dá)式。對(duì)于筆者而言,并不需要這些額外的功能,然后選擇了筆者的模板平臺(tái)Mustache.js。
在一般情況下,筆者的印象是,現(xiàn)有的模板框架可比較的功能是很少的,因此決定在很大程度上是個(gè)人喜好的問題。
選擇一個(gè)CSS框架
CSS框架是必不可少的工具,用來擴(kuò)展CSS如變量等方便的功能集,創(chuàng)建分層的CSS選擇器的方式,以及一些更先進(jìn)的功能。這實(shí)質(zhì)上是創(chuàng)建了一個(gè)新的語言:CSS的增強(qiáng)版本(姑且稱之為它的CSS++)。為便于開發(fā),一些框架在瀏覽器中實(shí)現(xiàn)了一個(gè)JavaScript的CSS+ +解釋器,而一些其他框架讓你監(jiān)控一個(gè)CSS+ +文件,并每當(dāng)有更改就編譯它。所有的CSS框架應(yīng)提供命令行工具來編譯CSS++成CSS給開發(fā)。
像模板語言一樣,也有很多選擇。筆者的選擇是出于個(gè)人的語法偏好,筆者更喜歡SCSS,因?yàn)樗苊饬讼馌怪異的語法。 SCSS的一個(gè)缺點(diǎn)是,它并沒有附帶一個(gè)JavaScript解釋器(有一個(gè)非官方的,筆者還沒有試過),但可用命令行監(jiān)視器。還有其他類似的CSS框架,包括LESS和Stylus。
如何布局視圖Views
HTML5提供了多種方式來布局內(nèi)容,MVC框架對(duì)這些布局技術(shù)的使用無要求,留給開發(fā)者你一點(diǎn)困難。
一般來說,對(duì)documents相對(duì)位置是合適的,但對(duì)apps除外。應(yīng)避免絕對(duì)定位,像tables。許多Web開發(fā)人員已經(jīng)轉(zhuǎn)向使用float屬性對(duì)準(zhǔn)元素的,但是這只是第二理想的構(gòu)建應(yīng)用程序的觀點(diǎn),因?yàn)樗鼪]有類似應(yīng)用程序的布局,導(dǎo)致許多奇怪的問題和臭名昭著的clearfix hacks。
經(jīng)過多年來的布局與各種網(wǎng)絡(luò)技術(shù)的實(shí)驗(yàn),筆者認(rèn)為一個(gè)固定的定位和flex box的模型相結(jié)合是移動(dòng)互聯(lián)網(wǎng)應(yīng)用的理想選擇。筆者使用的是將屏幕上的界面元素(頁(yè)眉,側(cè)邊欄,頁(yè)腳等)固定定位。flex box 模型對(duì)在頁(yè)面上布局堆疊視圖(Stacked views)是很棒的(水平或垂直的)。只有CSS盒模型明顯地對(duì)界面設(shè)計(jì)進(jìn)行了優(yōu)化,非常類似Android的LinearLayout 管理器。對(duì)于有關(guān)flex box模型的更多信息,請(qǐng)閱讀保羅的文章,并注意該規(guī)范正在由一個(gè)新的,非向后兼容的版本取代。
自適應(yīng)Web應(yīng)用程序
***一節(jié),在這個(gè)問題上:筆者大力提倡創(chuàng)建設(shè)備特定的用戶界面。這意味著為不同的形式屏幕重新編寫視圖代碼部分。幸運(yùn)的是,MVC模式,使得它比較容易為多個(gè)視圖(如平板電腦和手機(jī))重用業(yè)務(wù)邏輯model。
iOS Flipboard演示了這個(gè)想法很好,它為平板電腦和手機(jī)用戶提供了為每個(gè)設(shè)備外形高度定制的體驗(yàn)。手機(jī)用戶界面特別為垂直點(diǎn)擊進(jìn)行了優(yōu)化,允許單手使用。平板的UI讓兩手反面持有設(shè)備工作良好。
輸入的考慮
移動(dòng)用戶與您的應(yīng)用程序進(jìn)行交互的主要方式是通過用手指觸摸屏幕。這與基于鼠標(biāo)的互動(dòng)相當(dāng)不同,因?yàn)橛蓄~外9點(diǎn)在跟蹤屏幕,這意味著開發(fā)人員編寫移動(dòng)應(yīng)用程序時(shí),需要拋棄移動(dòng)鼠標(biāo)事件。此外,在移動(dòng)鼠標(biāo)事件有300ms延遲點(diǎn)擊的問題(有一個(gè)著名的觸摸式的解決方法)。在移動(dòng)瀏覽器使用這些事件的詳細(xì)信息,請(qǐng)參閱我的觸摸事件的文章。
只有S /mousedown/ touchstart/所有的事件處理程序是不夠的。有 一套全新的用戶期待的觸摸設(shè)備手勢(shì),如點(diǎn)擊、通過瀏覽圖像列表導(dǎo)航。雖然蘋果公司有一個(gè)鮮為人知的手勢(shì)API,但沒有在網(wǎng)頁(yè)上做手勢(shì)檢測(cè)的開放規(guī)范。我們真的需要一個(gè)JavaScript手勢(shì)檢測(cè)庫(kù),去處理一些較常見的手勢(shì)。
如何使其離線工作
對(duì)于一個(gè)應(yīng)用程序脫機(jī)工作,你需要確保兩件事情真實(shí):
Assets資產(chǎn)可用(通過AppCache,文件系統(tǒng)API等)
數(shù)據(jù)是可用的(通過LocalStorage,WebSQL,IndexedDB等)
實(shí)踐中,在網(wǎng)絡(luò)上建立離線應(yīng)用是一個(gè)棘手的問題。一般來說脫機(jī)功能應(yīng)從一開始就加入你的應(yīng)用程序。讓現(xiàn)有Web應(yīng)用程序沒有顯著的重寫代碼運(yùn)行在離線狀態(tài)下是特別困難的。此外,脫機(jī)技術(shù)還有各種未知的存儲(chǔ)限制,而且未知超出限制時(shí)會(huì)發(fā)生什么不確定的行為。***,在離線的技術(shù)堆棧還有一些技術(shù)問題,最顯著的是AppCache,正如我在以前的文章提到。
寫真正的離線功能的應(yīng)用程序是一個(gè)非常有趣的方法是“離線優(yōu)先”。換句話說,如果沒有互聯(lián)網(wǎng)連接全部寫入本地,當(dāng)存在互聯(lián)網(wǎng)連接,實(shí)現(xiàn)同步數(shù)據(jù)同步層。在Backbone.js MVC模型,這可以很好地適應(yīng)自定義Backbone.sync適配器。
單元測(cè)試
單元測(cè)試您的UI是有困難的。然而,因?yàn)槟闶褂肕VC的模型,它是完全隔離的UI和數(shù)據(jù)結(jié)果,因此,可方便測(cè)試。QUnit是一個(gè)相當(dāng)不錯(cuò)的選擇,特別是因?yàn)樗试S使用它的start()和stop()方法單元測(cè)試異步代碼。
總結(jié)
總之,筆者使用Backbone.js 作為 MVC 框架,Mustache.js做為模板,SCSS作為CSS框架,CSS的Flex box展現(xiàn)界面views,自定義觸摸事件和QUnit單元測(cè)試工具,來寫筆者的移動(dòng)Web應(yīng)用程序。脫機(jī)支持,筆者仍然嘗試用各種技術(shù),并希望未來繼續(xù)寫篇文章。雖然筆者強(qiáng)烈相信有必要在這里列出每種工具(如MVC),筆者也相信,筆者在這里描述的許多具體的技術(shù)是可以互換的(如Handlebars 和 Mustache)。
還有一件事:2012年1月17日,Thorax宣布發(fā)布。這是一個(gè)基于Backbone一套開發(fā)庫(kù),非常類似我在這篇文章里描述的思想。筆者還沒有在任何深度研究,但名稱是偉大的:)
使用一套類似的框架嗎?有你最喜歡的?覺得筆者缺少一個(gè)重要的框架嗎?讓筆者知道!