不管前端也好,後端也好,都是整個軟件體系的一部分。軟件產品也是產品,它的研發過程也必然是有其目的。絕大多數軟件產品是追逐利潤的,在產品目標肯定的狀況下,成本有兩個途徑來優化:減小部署成本,提升開發效率。html
減小部署成本的方面,業界研究得很是多,好比近幾年很流行的「去IOE」,就是很典型的,從一些費用較高的高性能產品遷移到開源的易替換的產品集羣,又好比使用Linux + Mono來部署.net應用,避開Windows Server的費用。前端
提升開發效率這方面,業界研究得更多,主要途徑有兩點:加快開發速度,減小變動代價。怎樣才能加快開發速度呢?若是咱們的開發不是從新造輪子,而是每一次作新產品均可以利用已有的東西,那就會好不少。怎樣才能減小變動代價呢?若是咱們可以理清模塊之間的關係,合理分層,每次變動只須要修改其中某個部分,甚至不須要修改代碼,僅僅是改變配置就能夠,那就更好了。git
咱們先不看軟件行業,來看一下製造行業,好比汽車製造業,他們是怎麼造汽車的呢?造汽車以前,先設計,把整個汽車分解爲不一樣部件,好比輪子,引擎,車門,座椅等等,分別生產,最後再組裝,因此它的製造過程能夠較快。若是一輛汽車輪胎被扎破了,須要送去維修,維修的人也沒有在每一個地方都修一下,而是隻把輪胎拆下來修修就行了,這個輪胎要是實在壞得厲害,就乾脆換上個新的,整個過程不須要不少時間。github
席德梅爾出過一款很不錯的遊戲,叫作《文明》(Civilization),在第三代裏面,有一項科技研究成功以後,會讓工人工做效率加倍,這項科技的名字就叫作:可替換部件(Replacement Parts)。因此,軟件行業也應當引入可替換的部件,通常稱爲組件。web
在服務端,咱們有不少組件化的途徑,像J2EE的Beans就是一種。組件建造完成以後,須要引入一些機制來讓它們可配置,好比說,工做流引擎,規則引擎,這些引擎用配置的方式組織最基礎的組件,把它們串聯爲業務流程。無論使用什麼技術、什麼語言,服務端的組件化思路基本沒有本質差異,你們是有共識的,具體會有服務、流程、規則、模型等幾個層次。bootstrap
早期展現層基本以靜態爲主,服務端把界面生成好,瀏覽器去拿來展現,因此這個時期,有代碼控制的東西幾乎全在服務端,有分層的,也有不分的。若是作了分層,大體結構就是下圖這樣:後端
這個圖裏,JSP(或者其餘什麼P,爲了舉例方便,本文中相關的服務端技術都用Java系的來表示)響應瀏覽器端的請求,把HTML生成出來,跟相關的JavaScript和CSS一塊兒拿出去展現。注意這裏的關鍵,瀏覽器端對界面的形態和相關業務邏輯基本都沒有控制權,屬於別人給什麼就展現什麼,想要什麼要先提申請的尷尬局面。設計模式
這個時期的Web開發,前端的邏輯是基本可忽略的,因此前端組件化方式大同小異,不管是ASP仍是JSP仍是其餘什麼P,均可以自定義標籤,把HTML代碼和行間邏輯打包成一個標籤,而後使用者直接放置在想要的地方,就能夠了。瀏覽器
在這一時代,所謂的組件化,基本都是taglib這樣的思路,把某一塊界面包括它的業務邏輯一塊兒打成一個端到端的組件,整個很是獨立,直接一大塊從界面到邏輯都有,並且邏輯基本上都是在服務端控制,大體結構以下圖所示。前端框架
自從Web2.0逐漸流行,Web前端已經再也不是純展現了,它逐漸把之前在C/S裏面作的一些東西作到B/S裏面來,好比說Google和微軟的在線Office,這種複雜度的Web應用若是還用傳統那種方式作組件化,很顯然是行不通的。
咱們看看以前這種組件化的方式,本質是什麼?是展示層跟業務邏輯層的隔離,後端在處理業務邏輯,前端純展示。若是如今還這麼劃分,就變成了前端有界面和邏輯,後端也有邏輯,這就比較亂了。咱們知道,純邏輯的分層組件化仍是比較容易的,任何邏輯若是跟展示混起來,就比較麻煩了,因此咱們要把分層的點往前推,推到也能把單獨的展示層剝離出來。
以下圖所示,由於實際上HTML、CSS、JavaScript這些都逐漸靜態化,因此再也不須要把它們放在應用服務器上了,咱們能夠把它們放在專門的高性能靜態服務器上,再進一步發展,就能夠是CDN(Content Delivery Network,內容分發網絡)。前端跟後端的通訊,基本都是經過AJAX來,也會有一些其餘的好比WebSocket之類,總之儘可能少刷新了。
在這張圖裏面能夠看到,真正的前端已經造成了,它跟應用服務器之間造成了自然的隔離,因此也可以很獨立地進行一些發展演進。
如今不少Web程序在往SPA(單頁面程序,Single Page Application)的方向發展,這類系統一般比較相似傳統的C/S程序,交互過程比較複雜,所以它的開發過程也會遇到一些困難。
那爲何你們要作SPA呢?它有不少明顯的好處,最核心的優點就是高效。這個高效體如今兩個方面:一是對於用戶來講,這種方式作出來的東西體驗較好,相似傳統桌面程序,對於那些須要頻繁操做的行業用戶,有很大優點。二是運行的效率較高,以前集成一些菜單功能,可能要用iframe的方式引入,但每一個iframe要獨立引入一些公共文件,服務器文件傳輸的壓力較大,還要初始化本身的一套內存環境,比較浪費,互相之間也不太方便通訊,通常要經過postMessage之類的方式去交互。
有了SPA以後,好比一塊界面,就能夠是一個HTML片斷,用AJAX去加載過來處理以後放到界面上。若是有邏輯的JavaScript代碼,也能夠用require之類的異步加載機制去運行時加載,總體的思路是比較好的。
不少人說,就以這樣的需求,用jQuery再加一個異步js加載框架,不是很足夠了嗎?這兩個東西用得好的話,也是可以解決一些問題的,但它們處理的並非最關鍵的事情。在Web體系中,展示層是很自然的,由於就是HTML和CSS,若是隻從文件隔離的角度,也能夠作出一種劃分的方式,邏輯放在單獨的js文件裏,html內部儘可能不寫js,這就是以前比較主流的前端代碼劃分方式。
剛纔咱們提到,SPA開發的過程當中會遇到一些困難,這些困難是由於複雜度大爲提高,致使了一些問題,有人把這些困難歸結爲純界面的複雜度,好比說,控件更復雜了之類,沒有這麼簡單。問題在於什麼呢?我打個比方:咱們在電腦上開兩個資源管理器窗口,瀏覽到同一個目錄,在一個目錄裏把某個文件刪了,你猜猜另一個裏面會不會刷新?
毫無疑問,也會刷新,可是你看看你用的Web頁面,若是把整個複雜系統整合成單頁的,能保證對一個數據的更新就實時反饋到全部用它的地方嗎?怎麼作,是否是很頭疼?代碼組織的複雜度大爲提升,因此須要作一些架構方面的提高。
提到架構,咱們一般會往設計模式上想。在著名的《設計模式》一書中,剛開始就講了一種典型的處理客戶端開發的場景,那就是MVC。
傳統的MVC理念咱們並不陌生,由於有Struts,因此在Web領域也有比較經典的MVC架構,這裏面的V,就負責了整個前端的渲染,並且是服務端的渲染,也就是輸出HTML。以下圖所示:
在SPA時代,這已經不合適了,因此瀏覽器端造成了本身的MVC等層次,這裏的V已經變成客戶端渲染了,一般會使用一些客戶端的HTML模版去實現,而模型和控制器,也相應地在瀏覽器端造成了。
咱們有不少這個層面的框架,好比Backbone,Knockout,Avalon,Angular等,採用了不一樣的設計思想,有的是MVC,有的是MVP,有的是MVVM,各有其特色。
以Angular爲例,它推薦使用雙向綁定去實現視圖和模型的關聯,這麼一來,若是不一樣視圖綁定在同一模型上,就解決了剛纔所說的問題。而模型自己也經過某種機制,跟其餘的邏輯模塊進行協做。
這種方式就是依賴注入。依賴注入的核心理念就是經過配置來實例化所依賴的組件。使用這種模式來設計軟件架構,會犧牲一些性能,在跟蹤調試的便利性等方面也會有所損失,但換來的是無與倫比的鬆耦合和可替代性。
好比說,這些組件就能夠單獨測試,而後在用的時候隨手引入,毫無壓力。對於從事某一領域的企業來講,光這一條就足以吸引他在上面大量投入,把全部不常變更領域模型的業務代碼都用此類辦法維護起來,這是一種財富。
若是咱們來設計Angular這麼一個前端框架,應當如何入手呢?很顯然,邏輯的控制必須使用JavaScript,一個框架,最本質的事情在於它的邏輯處理方式。
咱們的界面爲何能夠多姿多彩?由於有HTML和CSS,注意到這兩種東西都是配置式的寫法,參照後端的依賴注入,若是把這二者視爲跟Spring框架中一些XML等同的配置文件,思路就豁然開朗了。
與後端不一樣的是,充當前端邏輯工具的JavaScript不能作入口,必須掛在HTML裏才能運行,因此出現了一個怪異的情況:邏輯要先掛在配置文件(HTML)上,先由另外的容器(瀏覽器或者Hybird的殼)把配置文件加載起來,而後才能從某個入口開始執行邏輯。好消息是,過了這一步,邏輯層就開始大放異彩了。
從這個時候開始,框架就啓動了,它要作哪些事情呢?
這些是主線流程,還有一些支線,好比:
SPA的一個典型特徵就是部分加載,界面的部件化也是其中比較重要的一環。界面片斷在動態請求獲得以後,藉助模版引擎之類的技術,通過某種轉換,放置到主界面相應的地方。因此,從這個角度來看,HTML的組件化很是容易理解,那就是界面的片斷化和模板化。
JavaScript這個部分有好幾個發展階段。
JavaScript組件化的目標是什麼呢,是清晰的職責,鬆耦合,便於單元測試和重複利用。這裏的鬆耦合不只體如今js代碼之間,也體如今js跟DOM之間的關係,因此像Angular這樣的框架會有directive的概念,把DOM操做限制到這類代碼中,其餘任何js代碼不操做DOM。
如上圖所示,總的原則是先分層次,層內再做切分。這麼作的話,再也不存在以前那種端到端組件了,使用起來沒有原先那麼方便,但在另外不少方面比較好。
這方面,業界也有不少探索,好比LESS,SASS,Stylus等。爲何CSS也要作組件化呢?傳統的CSS是一種扁平的文本結構,變動成本較高,好比說想要把結構從鬆散改緊湊,須要改動不少。若是把實際使用的CSS只看成輸出結果,而另外有一種適合變動的方式看成中間過程,這就好多了。好比說,咱們把一些東西定義成變量,每一個細節元素使用這些變量,當須要總體變動的時候,只需修改這些變量而後從新生成一下就能夠了。
以上,咱們討論了大體的Web前端開發的組件化思路,後續將闡述組件化以後的協做過程和管控機制。