4. 前端工程化開發實踐css
因爲Nodejs 、npm的環境搭建往上不少,這裏就不過多介紹它們了。html
這裏咱們將更多介紹FIS3、RequireJS 、r.js。前端
4.1 模塊化開發:html5
4.1.1 開發目錄結構node
左圖爲開發目錄結構,jquery
右圖中新增js 目錄、fis-conf.js文件,js 目錄用來存放require.js的頁面級入口文件webpack
4.1.2 HTML文件的模塊化處理web
任何頁面均可以拆分爲若干組件,在開發環境下,能夠迅速定位組件位置,修改組件npm
FIS3爲咱們提供了方便的資源嵌入功能http://fis.baidu.com/fis3/docs/user-dev/inline.html前端工程化
簡單來講,咱們能夠如同模板開發同樣去寫HTML頁面,例如:
這個首頁頁面自己的樣式和代碼極少,頁面內容都是由」 ?__inline」功能從其餘頁面引入了,
如:banner.html
當文件編譯時,FIS3會自動幫咱們把這些地方替換爲文件中的HTML代碼:
編譯後的index.html:
能夠看到,FIS3幫咱們將banner.html中的代碼完成寫入了index.html。
這裏咱們完成了簡單的頁面代碼模塊化分離,可是這遠遠還不夠,由於咱們的頁面還須要包括CSS文件,JS文件,以及一系列的圖片文件等等。那麼這些東西該這麼完成模塊化分離,而後再打包呢。對於CSS咱們就須要用到LESS的,js則須要Requirejs的幫助。
4.1.3 JS文件的模塊化處理了
這裏咱們須要使用到Requirejs,前面提到過,它是AMD模式的一個實現。因爲js語言的歷史緣由,它在很長一段時間都算不上一個嚴謹的言語,不過通過多年來的不斷努力,人們提出了許多加強它,規範它的方案,這些規範的目的都是爲了 JavaScript 的模塊化開發,特別是在瀏覽器端的。目前這些規範的實現都能達成瀏覽器端模塊化開發的目的。
Requirejs 首先須要一個requirejs.config的配置,該配置的目的在於肯定文件間的依賴關係,設定各個文件的別名,設定文件的加載順序等等。
上面是一個簡單的配置,baseUrl定義了一個相對文件所在目錄的相對路徑,paths設置了相關文件的別名,shim規定文件間的依賴關係,好比baseUI模塊依賴jquery模塊,所以,baseUI須要在jquery加載完後加載。http://www.requirejs.cn/ 詳細配置選項查看這裏。
對於requirejs.config 定義的位置,我嘗試過三種方式:
u 每一個入口文件中都定義一次
u 統一到config.js中去定義,在加載時優先require這個文件,而後在回調函數裏面在寫頁面的依賴
這樣作到時解決了冗餘的問題,可是require的嵌套顯然不太符合做者的初衷.
u 統一到config.js中去定義,而後加require.js和config.js打包到一塊兒,在引用入口文件前就同步調用了。
這樣作至關於全局定義了require.config而且在頁面中同步調用,必定是會在入口文件前,解決了以前的問題
注意require.config中shim只用作兩個功能,一個是代表依賴順序關係,一個是加載不符合AMD規範的js文件。不要用做模塊加載。
接下來就是入口文件和模塊文件的編寫,入口文件我認爲應該是每一個一個,這樣能保證不會加載多餘的文件進來。固然,在特殊狀況下,能夠不一樣頁面引用同一個,靈活應用。
對於模塊文件,我推薦的書寫方式以下,在對象中定義方法,並將對象做爲接口暴露,提供給其餘模塊使用
特別提示一點,不管是入口文件,仍是模塊文件,只要是須要使用的依賴就要寫到依賴數組中,不要想着a依賴過b,我如今只要寫依賴a那邊b也自動依賴了,這樣是違反requirejs的初衷的。
4.1.4 css文件的模塊化處理
目前來講,有兩種方式來對css文件作模塊化處理
u 利用LESS的@import引入模塊
u 利用FIS3的「聲明依賴」功能引入模塊
二者區別在於@import會在LESS文件編譯階段將引用的LESS文件加入該文件中,而@require是在文件打包階段將各個css文件合併到一塊兒。
1.1.5 圖片的處理
FIS3的fis-spriter-csssprites插件便可幫助咱們生成頁面級別的雪碧圖
4.2 自動構建和優化
4.2.1 FIS3 介紹
u FIS3 是基於文件對象進行構建的。
u FIS3有本身的內置語法,實現了「內容嵌入」,「定位資源」,「聲明依賴」三個功能。
u FIS3 編譯的整個流程都是經過配置文件fis-conf.js來控制的。
u FIS3 定義了一種相似 CSS 的配置方式。固化了構建流程,以期讓工程構建變得簡單。
u FIS3 提供了文件指紋的功能,經過分析文件大小,在文件名中添加MD5碼,來解決文件更新時的瀏覽器緩存問題。
以上是我對FIS3一點理解,詳細的教程請移步FIS3網站查看。
FIS3教程:http://fis.baidu.com/fis3/docs/beginning/intro.html
強烈建議跟着教程走一遍,對FIS3有一點了解後再繼續往下看
目前使用到的最重要的幾個功能:
u FIS3編譯功能,經過配置文件fis-conf.js咱們能夠輕鬆的告訴FIS3該如何去處理咱們的前端文件,具體語法和使用方法請查看教程
在這個HTML文件中咱們引用了一個CSS文件,一個LESS文件,同步引用了html5.js,require.js以及config.js,此外咱們還經過Requirejs異步引入了一個模塊名爲index_main的js模塊。
那麼根據上面fis-conf.js中的配置,咱們的文件將會構建成什麼樣子呢。
首先,咱們的配置命中了當前目錄及其子目錄下的全部.less文件,而且調用了插件fis-parser-less插件將.less文件轉換爲.css文件後輸出。
而後咱們在文件打包階段調用了fis-postpackager-loader插件,用過allInOne這個配置,將頁面中同步引用的CSS文件、JS文件分別打包。這裏咱們同步引用的js文件有html5.js,require.js以及config.js。
可是仔細看,在咱們HTML代碼中有個<!--ignore-->的註釋,這裏就是爲了告訴FIS3,打包時請忽略這個文件,所以FIS3打包會跳過html5.js,而後打包require.js、config.js。並將其輸出爲 libs/require_conf.js文件。(因爲html5.js須要dom加載前調用,因此不打包它)
對於CSS文件,咱們在html文件中引入了一個reset.css,同時咱們經過前面一步編譯出了一個index.css,因此這裏FIS3會把這兩個文件打包,而後輸出到index.html_aio.css
文件中,配置中的${filepath}就表明當前文件路徑
u FIS3給咱們提供了一個本地的簡易Nodejs服務器,使用命令行 fis3 server start就能夠啓動。而且該服務一直存在後臺,不關機/重啓 或者 主動中止服務,該服務不會關閉,另外使用命令行fis3 server open能夠打開服務器所在文件夾,給咱們前端開發提供了一個很是方便的服務器環境。通常來講咱們能夠經過127.0.0.1:3000來訪問這個本地服務器。
u FIS3的有強大的監視自動刷新功能,當你的文件夾下任何文件發生變更時,FIS3會自動刷新頁面而且,從新編譯文件。這個功能須要fis3 release –wL來激活。
4.2.2 使用r.js
在使用FIS3的過程當中,發現異步的JS文件的打包,FIS3的庫目前支持還不足,因此我決定暫時使用r.js去替代。
當我在用FIS3打包整個項目以前,我會先用r.js對requirejs的依賴進行打包。若是FIS3同樣,咱們須要編寫一個配置文件來告訴他改如何打包,配置文件命名爲build.js
以上是一個簡單的build.js配置,更多配置能夠參考http://www.chenliqiang.cn/node/22
前面提到過require.config中最好不要經過shim依賴模塊,這是由於這會形成打包後屢次拉取文件,所以所有放在require的依賴數組中處理。
這裏配置完後,咱們經過 node r.js –o build.js 進行打包,生成的新文件夾temp-build
4.2.3 使用FIS3
使用完r.js,咱們開始使用FIS3構建整個項目
在這個配置文件中,咱們設定了兩套構建規則,如同CSS語言中的媒體查詢同樣。咱們這裏使用media來配置第二套構建規則。
在命令行中輸入fis3 release能夠開始執行構建
若是我要執行第二套方案只須要寫爲fis3 release temp 便可
上圖中的-d命令表明修改輸出目錄到../temptest,FIS3構建時還有其餘參數能夠選擇,具體能夠參考FIS3的文檔。
完成構建後咱們能夠看到,咱們頁面的請求數減小了,而且文件都帶上了MD5指紋
4.2.4 使用過程當中遇到的問題
因爲咱們使用了文件指紋,因此每一個文件的文件名中間會插入一個表示文件大小的MD5碼。
好比index.js會變成index_d82af77.js,根據FIS3「定位資源」的規則,構建時FIS3會自動替換掉html中的script、link、style、video、audio、embed等標籤的src或href屬性中的值,可是使用Requirejs時在data-main中的異步引入的文件和在config.js中配置的路徑就沒有那麼好運了。
解決方法:
u前面有提到全局配置require.config,事先就將data-main中文件路徑用模塊名替代。這樣能解決data-main中路徑沒法替換的問題。
u這裏能夠使用FIS3提供的資源定位能力,在config.js中使用__uri()函數解決該問題
5. 結語
這篇文章寫於去年4月,因爲沒有註冊博客園的帳號,所以如今才發佈過來。一年多的時間前端工程領域的變化很大,咱們團隊也經歷了FIS、grunt到如今webpack的變化,我也但願經過這篇基礎文章 ,拋磚引玉,讓大牛們更多來分享下大家的前端工程化經驗。