天天看點

webpack練手項目之easySlide(三):commonChunks

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:

  

webpack練手項目之easySlide(三):commonChunks

    關于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的源碼:

webpack練手項目之easySlide(三):commonChunks

  是的,前面引入公共CSS以及引入header部分是完全一緻的,這也就是我們所說的common chunks公共部分。

  接下來我們再來看webpack.config.js中的配置内容:

webpack練手項目之easySlide(三):commonChunks

  在配置檔案中先定義了這兩個入口檔案: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的特殊性,作為全站的導航菜單,一般都是樣式與功能統一的,是以這裡并沒有開放修改接口。

  好的,我們來看下最後的頁面效果:

webpack練手項目之easySlide(三):commonChunks

  當我們滾動向下滾動頁面後,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文法,功能十分強大,值得我們好好研究。

繼續閱讀