Teambition是一家追求卓越技術的公司,咱們工程師都很Geek,咱們使用了不少新潮的,開源的技術。同時咱們也貢獻了不少開源的項目。咱們但願可以把一些技術經驗分享給你們。因而有了這個「創做隨筆」。廢話休說,「創做隨筆」第一彈,來自咱們的前端工程師寸志,談一談他在前端模塊化開發方面的一些感想。前端
在模塊化方面,Node.js就顯得遊刃有餘。node
做爲用戶,咱們把代碼放到一個個JavaScript文件中,而後Node.js就有一套規則幫咱們把這些代碼組織起來,Node.js還有包的概念,因而咱們就可使用npm將代碼放到一個個包中,放到這裏那裏的node_modules中使用。很方便不是?感謝Node.js。git
可在瀏覽器端,模塊化這事就沒那麼簡單了。github
前端的一個模塊包含不少東西,JavaScript、CSS、圖片字體等等。甚至,可能根據業務須要,還包含國際化的文件。一個模塊若是包含以上這些東西,複雜度就上了幾個數量級。chrome
怎麼複雜了?和高大上的iOS開發比起來,人家有SDK,代碼隨便往項目裏扔,圖片扔,國際化有成熟的解決方案,最後構建一下一個可運行的應用就出來了。npm
前端缺少SDK,沒有成熟統一的開發方案,集成方案,前端模塊化之路很崎嶇。開發時,咱們須要一種方式來組織,加載代碼,發佈時,咱們還須要另一種方式將代碼、資源合併到一塊兒發佈。瀏覽器
TJ 給出了本身解決方案——Component。能夠份文件開發,而後再把JavaScript、CSS和模板文件合併到一塊兒。我只能說,理想很豐滿,現實很骨感,Component沒法適應各類奇葩的應用場景。緩存
或者咱們自由一點——服務器
依賴的第三方模塊,咱們有Bower,好爽,運行個命令,依賴就安裝好了。前端工程師
可是Bower不是銀彈,Bower只解決了模塊依賴,安裝依賴的問題。Bower中的模塊沒有任何標準和規則,有的只有JavaScript,有的支持AMD,有的可能只有CSS。文件結構,入口文件徹底不同。並非使用Bower安裝的模塊咱們就可使用一樣的方式使用任何一個模塊,使用某種工具將這些模塊打包發佈!
AMD做爲事實上的前端JavaScript模塊化標準,或能夠出來解救咱們。不少Bower模塊都是支持AMD規範的。並且AMD還提供了打包工具,總算有點解脫了。好景不長……
每一個模塊中的HTML怎麼辦,若是咱們使用的框架是Backbone,註定咱們要將HTML模板轉換成JavaScript模塊,或者使用模塊加載器的插件來實現。若是咱們使用AngularJS,那卻是能夠交由AngularJS。發佈時Backbone中的模塊使用AMD打包,AngularJS可使用Grunt內聯到頁面中。
HTML模塊也沒有固定的模式,沒有固定的SDK來解脫咱們。咱們只能組合現有的工具!
CSS就更不用說了,分開寫,使用LESS、SASS來組織?再一次沒有固定的模式沒有SDK。
還有圖片呢,字體呢?
前端若是想作模塊化開發,首先須要針對每一種資源(JavaScript、CSS、模板等)尋找一種模塊與集成方案,而後須要根據狀況的不一樣選用不一樣的工具框架拼湊出來。
目前比較拿的出手的,也就是JavaScript的模塊化,好比AMD或者CMD等等,分別可使用RequireJS和SeaJS。
去年在研究基於Backbone的框架Marionette時,想與Sea.js結合使用。如今來看這種組合是徹底沒有必要的。Marionette提供了模塊化的組織方案,反而生拉硬扯在一塊兒,衝突得很難受。其實把JavaScript文件一列放在HTML中也沒什麼問題。
究竟使用什麼來實現JavaScript,每每與選擇的JavaScript框架有關,選Backbone能夠AMD,也能夠CMD。選AngularJS直接引用就行。
CSS模塊化應該是兩方面的問題——
一是模塊必須有一套基礎樣式。與JavaScript相比,CSS衝突簡直是屢見不鮮,Shadow DOM還沒成熟,原生的CSS樣式隔離還在路上。因此必須有一套基礎樣式來規定這一套模塊化組件的樣式。咱們能夠選Bootstrap,若是閒它過重,也能夠本身寫。
其次,每一個組件必須有命名空間,避免組件間樣式衝突。若是選擇使用LESS、SASS等,那就比較好辦,它們的縮進語法避免寫不少重複的CSS代碼。
若是使用AngularJS,那AngularJS已經幫您解決了模板模塊化的問題,AngularJS能夠根據模塊代碼中的引用加載對應的HTML。若是使用Backbone,能夠選擇各類各樣的模板引擎,Mustache?不過比起AngularJS就低端些,咱們必須本身處理模板文件,要麼經過模塊加載器經過XHR請求,而後動態編譯;或者將Mustache編譯成JS,在當作模塊加載。
放在使用他們的模塊中,該怎麼引用就怎麼引用。
國際化文件?這些就很少說了,總之,每種文件須要選定一種開發的組織方式。
模塊採用統一的模式來開發以後,只需選定一種包的分發方式就好了——Bower。npm不適合這樣的場景,npm的版本管理太過細緻了。若是同一個項目中容許出現同一模塊的不一樣版本,事情就作的太過複雜了。
發佈上線必須一個以終爲始的過程。若是你不追求網站或者應用的速度,那就把那些開發文件直接丟到生產服務器上去吧。別說,我還真見過這樣的商用的網站。
若是講究一些方案,資源合併成數個文件,代碼線上組合和運行方式徹底能夠與本地開發不同。只須要功能在就行。
JavaScript代碼打成一個文件,或者兩個?都行。若是使用RequireJS,那RequireJS提供了打包的工具,打包成幾個文件,什麼粒度,都行。若是是Sea.js也有對應的工具。就算文件都是一個一個列出來,咱們也老是能夠打出來你想要的文件。
CSS等等其餘資源都是如此,就算開發時各自不一樣的結構模式,打包時都是能夠打的。
至於上線CDN,版本號緩存什麼的並不在本文的討論範圍以內。
前端模塊沒有什麼特效藥。惟一要遵照的原則就是,比起Node.js來說,每種資源必需要有一種本身的開發和上線組織方式(Node.js開發和上線都是一致的),開發和上線徹底能夠是兩種方式,大可沒必要人云亦云,只要適合能夠隨意組合;CSS在CSS Scoped Style正式使用以前,應該有一套基礎樣式和沙盒(模塊樣式命名空間)。