1. 程式人生 > >前端工程化思考與實踐(二)

前端工程化思考與實踐(二)

run test 代碼 -m link 本地 生成頁面 函數 說我

4. 前端工程化開發實踐

由於Nodejs npm的環境搭建往上很多,這裏就不過多介紹它們了

這裏我們將更多介紹FIS3RequireJS r.js

4.1 模塊化開發:

4.1.1 開發目錄結構

  技術分享圖片

左圖為開發目錄結構,

技術分享圖片 右圖中新增js 目錄、fis-conf.js文件,js 目錄用來存放require.js的頁面級入口文件

4.1.2 HTML文件的模塊化處理

任何頁面都可以拆分為若幹組件,在開發環境下,可以迅速定位組件位置,修改組件

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.jsconfig.js打包到一起,在引用入口文件前就同步調用了。

這樣做相當於全局定義了require.config並且在頁面中同步調用,一定是會在入口文件前,解決了之前的問題

技術分享圖片 註意require.configshim只用做兩個功能,一個是表明依賴順序關系,一個是加載不符合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 圖片的處理

FIS3fis-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.jsrequire.js以及config.js,此外我們還通過Requirejs異步引入了一個模塊名為index_mainjs模塊。

那麽根據上面fis-conf.js中的配置,我們的文件將會構建成什麽樣子呢。

首先,我們的配置命中了當前目錄及其子目錄下的所有.less文件,並且調用了插件fis-parser-less插件將.less文件轉換為.css文件後輸出。

然後我們在文件打包階段調用了fis-postpackager-loader插件,用過allInOne這個配置,將頁面中同步引用的CSS文件、JS文件分別打包。這裏我們同步引用的js文件有html5.jsrequire.js以及config.js

但是仔細看,在我們HTML代碼中有個<!--ignore-->的註釋,這裏就是為了告訴FIS3,打包時請忽略這個文件,因此FIS3打包會跳過html5.js,然後打包require.jsconfig.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.jsrequirejs的依賴進行打包。如果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命令代表修改輸出目錄到../temptestFIS3構建時還有其他參數可以選擇,具體可以參考FIS3的文檔。

完成構建後我們可以看到,我們頁面的請求數減少了,並且文件都帶上了MD5指紋

技術分享圖片

技術分享圖片

4.2.4 使用過程中遇到的問題

由於我們使用了文件指紋,所以每個文件的文件名中間會插入一個表示文件大小的MD5碼。

比如index.js會變成index_d82af77.js,根據FIS3“定位資源”的規則,構建時FIS3會自動替換掉html中的scriptlinkstylevideoaudioembed等標簽的srchref屬性中的值,但是使用Requirejs時在data-main中的異步引入的文件和在config.js中配置的路徑就沒有那麽好運了。

解決方法:

u前面有提到全局配置require.config,事先就將data-main中文件路徑用模塊名替代。這樣能解決data-main中路徑無法替換的問題。

u這裏可以使用FIS3提供的資源定位能力,在config.js中使用__uri()函數解決該問題

5. 結語

這篇文章寫於去年4月,由於沒有註冊博客園的賬號,因此現在才發布過來。一年多的時間前端工程領域的變化很大,我們團隊也經歷了FIS、grunt到現在webpack的變化,我也希望通過這篇基礎文章 ,拋磚引玉,讓大牛們更多來分享下你們的前端工程化經驗。

前端工程化思考與實踐(二)