我那進了"模塊化研究"小組.所以嘞.研究模塊化以及如何讓項目的模塊化更加合理和高效是我們小組的主要目的.
首先,在實行模塊化之前,得先鞏固模塊化開發的理論基礎,因為理論是實踐的基礎。
只有這樣,在過程中理論與實踐相結合,才有可能達到最滿意的效果.
什么是模塊化?
- 模塊化就是為了減少系統耦合度,提高高內聚,減少資源循環依賴,增強系統框架設計。
- 讓開發者便于維護,同時也讓邏輯相同的部分可復用
- 模塊化開發:針對js、css,以功能或業務為單元組織代碼。js方面解決獨立作用域、依賴管理、
api暴露、按需加載與執行、安全合并等問題,css方面解決依賴管理、組件內部樣式管理等問題。
任何事物都有一個過程,那么模塊化的過程通俗點講就是:
模塊化的過程就是:
- 1、拆分
將整個系統按功能
,格式
,加載順序
,繼承關系
分割為一個一個單獨的部分.
注意:拆分的粒度問題,可復用問題,效率問題.如何這些問題處理的不好,就有可能出現不想要的后果。- 2、歸納
將功能或特征相似的部分組合在一起,組成一個資源塊.- 3、總結
將每個資源塊按找需求,功能場景以及目錄約束放到固定的地方以供調用.
模塊的歷程
模塊化的發展也是從草根一步一步走過來的。從最開始到現在成熟方案:
- namespace
- sass,less
- AMD&CMD
- html模版
- grunt,gulp,webpack
- FIS,YUI,KISSY
在亙古年代,機智的人們為了處理javascript的命名沖突,功能塊管理等等,在js中使用了namespace
。我們可以說這是最原始的模塊化管理模式。
如下:
// 使用namespace之前
var name={};
var name2={};// 使用namespace之后
var nameSpace={}; nameSpace.branchOne={ name:{} }; nameSpace.branchTwo={ name:{} };
添加命名空間,達到拆分js邏輯的目的。
到了現代,處理css
的模塊化的有sass
,less
等工具。根據其提供的語法,便可以有效將css拆分為不同的塊。
還有隨著AMD
和CMD
的出現,javascrip中namespace機制便已經被淘汰殆盡。不過目前我們的項目組中那部分還沒有遷移過來的老代碼還在默默的使用著這種“古老”的方式。根據模塊加載的工具類庫,實現js邏輯的模塊化加載的方式越來越稱為主流。其中的好處大家可以查一查,不在這里就不贅述咯。
但是,最重要的一點必須要提比namespace更加利于維護和復用
。
在html中也存在著各種前端和后端的模版。就像php中的smarty(我們現在就在用)。前端中的juicer,underscore等等。它們同樣的也可以將html按功能特點拆分抽離為單獨的html塊。
不過,上面的只是將js
,css
,html
單獨的進行進行模塊化處理,并沒有一個統一的完整的實現功能模塊劃分,而spm
,webpack
這些工具恰恰做了這些事。它們可以將js,html,css以及其他靜態資源按照開發者的意愿拆分為單獨的模塊,抽離的也更加完整。
上面的工具雖然可以幫助開發者們完成模塊化,但是它們也僅僅只是一個單獨的模塊化工具,并沒有形成一個十分成熟的前端模塊化方案。而fis
,yui
,kissy
這些框架提供了囊括上述全部的功能。可以幫助開發者實現從頭到尾的模塊化。
此外,需要注意的是,前端的模塊化并不應該只專注于某一項(js,css,html)的模塊化,而應該是對項目整體進行解耦,抽離,組裝。從而達到項目整體模塊化的目的。
如何實現?
因為模塊是按功能進行分類的,所以可以先將模塊分為兩類:
- 公共模塊(用于促進代碼復用)
- 業務模塊(用于提升可維護性)
目前,我們產品的V3版本的模塊是通過:
- 把耦合密集的歸為一個模塊
- 模塊間通過固定的接口交互
- 模塊內部實現自由發揮
這3個規則來區分和調用的。
主流的模塊化是什么?
什么是主流的模塊化哪?我接下來就用我們項目組用依賴fis的fisp來粗略的說一下fis的模塊化。
1、html的模塊化分割
將偶合度比較高的頁面片段進行單獨拆分,模塊布局作為公開的接口,進行html片段的繼承 復用與拼裝.
每個單獨的html片段使用單獨并且對應的css片段,html中的圖片可以按照相關性放到模塊文件下的一個單獨的圖片文件夾里.
舉個例子:
當我們在打開外鏈頁的時候,右側圈住的那部分就是一個模塊。那么在html中,它的結構是什么哪?
我們有一個base.tpl
是一個最外頭的模版,結構如下:
還有一個html的主要框架lqyout.tpl
,
一個功能模塊share.tpl
最后哪,就到了我們廣告的模塊?personal.tpl
,
細心的同學可能會發現,這些結構是一層一層的嵌套的。有大到小的分割。由最外頭(base.tpl)->主結構(layout.tpl)->功能結構(share.tpl)->具體廣告模塊(personal.tpl)
這樣哪,就會有效的組織頁面。
html模塊化可以實現多人協同開發頁面.各司其職.有效提高頁面的開發效率,和維護成本. 可以有效減少文件沖突,文件錯誤.
其中,頁面模塊代碼作用域的控制通過css文件來控制。某類具有高度耦合的頁面使用自身的css文件。
2、css的模塊化
根據視覺布局,定義通用的css 以及單個html片段css
3、JS的模塊化
鑒于目前主流的模塊加載器,fis也提供了一個模塊加載器叫mod.js
。用法和requirejs
,seajs
差不多。我們會按照功能將js分割并放到對應的位置。針對于模塊化加載fis有一點做的比較好
為了協調異步環境下模塊開發與性能間的矛盾,我們必須在工程階段就具備依賴分析的能力,把具備依賴關系的資源進行打包。就算不打包,也希望像 F.I.S 那樣有個記錄依賴關系的map.json,可以照單抓藥,一次性地把需要的依賴項加載下來。
因此,在開發期解析模塊依賴、合并代碼、甚至重寫資源路徑都得在工程化的層面完成。工程化和模塊化變成了容易耦合且不得不耦合的兩個話題。
上文提到的基本的原理,真正實施起來還是存在很多問題,模塊粒度問題,公共模塊與普通模塊的區分,繼承模塊是否值得繼承等等,頁面模塊如何劃分。
- 首先,了解你的項目,通過畫網站樹狀圖了解你網站的總體結構和頁面模塊。
- 其次,理清結構邏輯和視覺邏輯,結構邏輯就是看你的頁面由那些模塊組成,視覺邏輯了解可繼承模塊,布局邏輯(網格布局或者非網格布局)
目錄結構:
按照相似性 可以將css html js 以及其他的靜態資源放到一個一個文件夾中.當然,因為標準的確實,至于模塊化的文件如何組織就見仁見智了.
我們的目錄是這樣的:
一個單獨的模塊放到一個單獨的文件夾里,這個模塊的css,html,js以及其他靜態資源也都放到一起,便于管理。
結構差不多可以像這樣:
組件化:
組件化開發 :在模塊化基礎上,以頁面小部件(component)為單位將頁面小部件的js、css、html代碼片段放在一起進行開發、維護,組件單元是資源獨立的,
組件在系統內可復用。比如頭部(header)、尾部(footer)、搜索框(searchbar)、導航(menu)、對話框(dialog)等,甚至一些復雜的組件比如下載(download)等。
通常業務會針對組件化的js部分進行必要的封裝,解決一些常見的組件渲染、交互問題。實現高內聚,低耦合.
就拿我們的會員中心來說,整體是一個大的組件。目錄結構如下:
上述的模塊化特點,目前我們百度網盤使用的FIS已經將這些概念全部實現.而且做的還相當不錯.
好了,正經的模塊化介紹就到此結束。接下來,我為大家闡述一種另類的模塊化
.
換一種思路的模塊化
就拿上面的百度網盤外鏈的單文件分享來說:
每次有用戶請求,上述的每個html塊都要經過php的smarty引擎在服務器端組合成一個完整的html在返回給瀏覽器端,不僅如此,js、css以及其他靜態資源都是.server端一天要做幾十萬次這種重復的操作。它好累!!!
不過,針對于前端開發者來說,fisp做的已經足夠了。它確實已經實現了完整的模塊化。但是僅僅只是針對開發者而已
。
有沒有想過,對于瀏覽器來說,這么一個同樣的功能,每次都是重新加載一個內容和結構都差不多的html,如果能在這塊做點什么東西,就像把模塊化的思想用到瀏覽器上。那么,這個缺口是不是大有可為
。
所以,實現針對于瀏覽器的模塊化可以說是有必要的.從針對于開發者的模塊化轉換到針對瀏覽器的模塊化.這是一個嘗試的革命路線.