Hello,大家好。
在之前兩篇文章中:
webpack練手專案之easySlide(一):初探webpack
webpack練手專案之easySlide(二):程式碼分割
與大家分享了webpack的基本使用方法,以及使用webpack對程式碼進行分割,根據需求進行非同步載入。
今天我們繼續為大家介紹webpack的其他應用方法,主要包括common chunks以及web-dev-server。
1.Demo與Code
在實際的專案開發過程中,我們的專案中會有很多公共的部分,比如一些第三方的元件,CSS樣式等。通過新增一些配置,webpack在打包過程中自動的提取出這些公共元素,並將其打包到一個獨立的檔案中。在頁面上我們只需要引入這個公共的指令碼以及頁面單獨的指令碼即可。
如果大家注意的話,在上一章中我們使用的Demo就已經使用了common chunks:
Demo:http://xiaoyunchen.github.io/easySlide/
Code:https://github.com/xiaoyunchen/easySlide
為了演示效果,我們新增了一個頁面入口,叫做jsEvent.html,現實的功能也就是之前在 http://www.cnblogs.com/souvenir/p/4988367.html 已經實現的功能,演示JS事件流的傳播。只是這次稍微將程式碼改成模組化的形式。
OK。同一個專案下有兩個頁面(實際專案中會更多入口或者頁面),這兩個頁面都需要引用一些公共的元件,比如頭部導航選單,footer腳部資訊等,這些元件一般都是全站通用的,然後每個頁面進行單獨呼叫即可。
我們在專案下增加了一個jsEvent的模組,引入了jsEvent的頁面和呼叫JS:
關於jsEvent模組的實現我們稍後再看,先來看看jsEvent入口JS檔案的內容:
1 (function(){
2 //引入公共CSS與頁面CSS
3 require('../../css/vendor/reset.css');
4 require('../../css/page/jsEvent.css');
5 require('../../css/module/footer.css');
6
7 //引入header
8 require("../module/header.js");
9
10 //引入jsEvent模組
11 var Delegate=require("../module/jsEvent.js");
12 var delegate=new Delegate();
13 delegate.addBodyListener();
14 delegate.addListElement($('#list1'),$('#btn1'));
15 delegate.addListElement($('#list2'),$('#btn2'));
16
17 })();
同樣的,前三行程式碼我們先引入了公共CSS和本頁面所需的CSS。
第8行:引入了header模組。因為header模組除了樣式以外只有一個頁面滾動式固定的功能,所以這裡也需要呼叫其任何方法,只需引入該模組即可。
第11-15行:引入jsEvent模組,並配置相關事件監聽。關於jsEvent這個模組的實現大家可以檢視之前的文章或者原始碼,這裡不再作贅述。
同樣的大家可以再來回顧一下Index.js的原始碼:
是的,前面引入公共CSS以及引入header部分是完全一致的,這也就是我們所說的common chunks公共部分。
接下來我們再來看webpack.config.js中的配置內容:
在配置檔案中先定義了這兩個入口檔案:Index與delegate,然後這裡新引入了一個新的外掛:CommonsChunkPlugin (官方文件)
new webpack.optimize.CommonsChunkPlugin("commons.js", ["index", "delegate"])
通過這句程式碼我們將Index與delegate中的公共部分提取出來並放置在commons.js這個單獨的檔案中,所以我們在頁面中除了需要引入index/jsevent以外,還需要引入這個commons。
再來看看CommonsChunkPlugin 的其他配置選項:
minChunks :公共模組被使用的最小次數。比如配置為3,也就是同一個模組只有被3個以外的頁面同時引用時才會被提取出來作為common chunks。
minSize:作用類似於minChunks,只不過這裡控制的檔案大小。
children:這個引數比較有意思,他可以將common chunks不單獨存放,而是將其加入到所引用的頁面JS中進行合併。關於這個引數我也定義了一個webpack.config2.js以及index2.html用於測試,大家使用 webpack --config webpack.config2.js 就能單獨打一次包,然後發現這次並沒有生成commons.js,因為已經被加入到index.js中,所以在index2.html我們只需要引入bundle.js即可。(咦,怎麼感覺又回去了呢)
2.header元件
這是一個單獨的元件,功能比較簡單,作為頁面的一個導航,同時在頁面滾動的時候固定在最頂部。
我們來看看具體的實現程式碼:
1 (function(){ 2 require('../../css/module/header.css'); 3 4 var headerModule={ 5 config:{ //配置資訊,頭部class/多少高度觸發fixed,fixed class名 6 headerDom:$('.headerWrapper'), 7 fixedTop:80, 8 fixedCls:'header-fixed' 9 }, 10 headerFixed:function(){ //切換class 11 if ($(window).scrollTop()>headerModule.config.fixedTop){ 12 headerModule.config.headerDom.addClass(headerModule.config.fixedCls); 13 }else{ 14 headerModule.config.headerDom.removeClass(headerModule.config.fixedCls); 15 } 16 }, 17 init:function(){ //為window繫結scroll事件 18 $(window).bind('scroll',function(){ 19 headerModule.headerFixed(); 20 }); 21 } 22 }; 23 headerModule.init(); 24 module.exports=null; 25 })();
第2行,不多說,引入header模組所需要的css樣式。
第4行,定義了header元件的實現變數;
第5行,定義了一些配置資訊,具體資訊大家看註釋。
第10行,headerFixed:判斷當前滾動的高度是否大於我們們的配置,如果是的話就新增一個class。
第17行,init行數:初始化函式,為window繫結了這個scroll滾動事件。
第23-24行,主動呼叫了init行數,所以這裡我們的exports為null,沒有任何需要匯出的內容。
這裡需要一下兩個問題:
1.關於header的html模板,這裡沒有載入器來做非同步載入,而是直接寫在每個頁面中的,其實有些增加了維護工作量。實際專案的做法應該是將這個header.html的模板檔案獨立出來,然後通過後端的語法(比如PHP或者Java)來進行引入。這個工作如果由前端來完成的話,需要單獨一個HTTP請求同時需要重新渲染DOM,比較消耗瀏覽器的效能,所以不推薦。
2.關於header模組的配置資訊。根據一般元件的做法,這個引數應該是需要是暴露介面,讓呼叫者可以修改的,但是我們考略到header的特殊性,作為全站的導航選單,一般都是樣式與功能統一的,所以這裡並沒有開放修改介面。
好的,我們來看下最後的頁面效果:
當我們滾動向下滾動頁面後,header上增加了一個class,將header固定在了頁面頂部。
3.web-dev-server
這裡再單獨介紹一個webpack的小功能:web-dev-server.
這個功能的作用在於每次修改儲存後,webpack將會自動重新對資源進行打包,並且自動重新整理頁面。(使用的是socket.io進行通訊)
首先通過npm安裝web-dev-server
npm install web-dev-server --save--dev
安裝完成後再通過 web-dev-server 即可啟動server,啟動成功後命令列會出現如下的提示:
webpack:bundle is now VALID.
然後我們只需要訪問 http://localhost:8080/ 就可以訪問到我們的專案頁面。
可以嘗試修改一下任何一個資原始檔,然後會發現控制檯上webpack重新進行了編譯,而且瀏覽器也自動進行了重新整理,無需我們手動干預。(雙屏開發的同學可以開始鼓掌了...)
小結:
截止到這裡為止,我們對webpack的學習就暫時告一個段落。
webpack是一款非常優秀的前端模組化打包工具,他還有很多實用的功能,因為目前我的專案中還沒有涉及到,所以還沒來得及做深入研究。比如對react/angularjs這樣的前端框架,LESS/JADE等這些模板或者css工具的編譯與支援,同時還相容了AMD/CommonJS/ES6語法,功能十分強大,值得我們好好研究。