webpack4 抽離公共代碼


通過webpack打包提取公共代碼

提取公共代碼的必要性

網站都是由多個頁面組成的,一般來說所有的頁面采用的都是相同的技術棧,要么都是Vue,都是React,要么都是Angular,采用的技術是一致的,既然是一致的,就會有公共的代碼,有很多代碼是相同的,如果每個頁面都將這些相同的公共代碼包含進去,會引起一些問題。

  • 相同的資源配重復加載,造成了資源的浪費,(最后的靜態資源包會很大)
  • 每個頁面打開的時間會變長(影響用戶體驗)

因為第一個原因,導致了第二個原因,所以我們將公共代碼抽離出來,在用戶打開一個頁面的時候,順便加載了公共的文件,在打開其他頁面的時候,如果其他頁面也引用了這個公共文件,就不用重新加載,直接從瀏覽器緩存中獲取,這么做解決了以上的兩個問題。
有人說通過cdn加載公共靜態資源也可以解決以上問題,對此,我說:

什么是CDN

內容分發網絡,加速網絡傳輸,就是通過將資源部署到世界各地,用戶訪問時按照就近原則從最近的服務器獲取資源,來提高獲取資源的速度,cdn就是對http的提速

 
image

綜合以上,cdn在數據傳輸層面上降低了用戶打開首頁的時間,和webpack提取公共打碼不是一個方向

 

如何提取公共代碼?

從webpack4開始官方移除了commonchunk插件,改用了optimization屬性進行更加靈活的配置,這也應該是從V3升級到V4的代碼修改過程中最為復雜的一部分

splitChunks: {
    chunks: "async”,//默認作用於異步chunk,值為all/initial/async/function(chunk),值為function時第一個參數為遍歷所有入口chunk時的chunk模塊,chunk._modules為chunk所有依賴的模塊,通過chunk的名字和所有依賴模塊的resource可以自由配置,會抽取所有滿足條件chunk的公有模塊,以及模塊的所有依賴模塊,包括css
    minSize: 30000,  //表示在壓縮前的最小模塊大小,默認值是30kb
    minChunks: 1,  // 表示被引用次數,默認為1;
    maxAsyncRequests: 5,  //所有異步請求不得超過5個
    maxInitialRequests: 3,  //初始話並行請求不得超過3個
   automaticNameDelimiter:'~',//名稱分隔符,默認是~
    name: true,  //打包后的名稱,默認是chunk的名字通過分隔符(默認是~)分隔
    cacheGroups: { //設置緩存組用來抽取滿足不同規則的chunk,下面以生成common為例
       common: {
         name: 'common',  //抽取的chunk的名字
         chunks(chunk) { //同外層的參數配置,覆蓋外層的chunks,以chunk為維度進行抽取
         },
         test(module, chunks) {  //可以為字符串,正則表達式,函數,以module為維度進行抽取,只要是滿足條件的module都會被抽取到該common的chunk中,為函數時第一個參數是遍歷到的每一個模塊,第二個參數是每一個引用到該模塊的chunks數組。自己嘗試過程中發現不能提取出css,待進一步驗證。
         },
        priority: 10,  //優先級,一個chunk很可能滿足多個緩存組,會被抽取到優先級高的緩存組中
       minChunks: 2,  //最少被幾個chunk引用
       reuseExistingChunk: true//  如果該chunk中引用了已經被抽取的chunk,直接引用該chunk,不會重復打包代碼
       enforce: true  // 如果cacheGroup中沒有設置minSize,則據此判斷是否使用上層的minSize,true:則使用0,false:使用上層minSize
       }
    }
}

公共模塊抽離

舉例:

項目中分別有a.js, b.js, page1.js, page2.js這四個JS文件, page1.js 和 page2.js中同時都引用了a.js, b.js, 這時候想把a.js, b.js抽離出來合並成一個公共的js,然后在page1, page2中自動引入這個公共的js,怎么配置呢?如下: 

配置webpack.config.js文件

module.exports = {
  //...
 
  //優化項配置
  optimization: {
    // 分割代碼塊
    splitChunks: {
      cacheGroups: {
        //公用模塊抽離
        common: {
          chunks: 'initial', 
          minSize: 0, //大於0個字節
          minChunks: 2 //抽離公共代碼時,這個代碼塊最小被引用的次數
        }
      }
    }
  }
}

 

第三方模塊抽離

頁面中有時會引入第三方模塊,比如import $ from 'jquery'; page1中需要引用,page2中也需要引用,這時候就可以用vendor把jquery抽離出來,方法如下:

module.exports = {
  //...
 
  //優化項配置
  optimization: {
    // 分割代碼塊
    splitChunks: {
      cacheGroups: {
 
        //公用模塊抽離
        common: {
          chunks: 'initial',
          minSize: 0, //大於0個字節
          minChunks: 2, //在分割之前,這個代碼塊最小應該被引用的次數
        },
        
        //第三方庫抽離
        vendor: {
          priority: 1, //權重
          test: /node_modules/,
          chunks: 'initial',
          minSize: 0, //大於0個字節
          minChunks: 2, //在分割之前,這個代碼塊最小應該被引用的次數
        }
      }
    }
  }
}

 

注意:這里需要配置權重 priority,因為抽離的時候會執行第一個common配置,入口處看到jquery也被公用了就一起抽離了,不會再執行wendor的配置了,所以加了權重之后會先抽離第三方模塊,然后再抽離公共common的,這樣就實現了第三方和公用的都被抽離了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM