Webpack 提取公共代 CommonsChunkPlugin

背景 

若是不提取公共部分會有什麼後果? react

  1. 相同資源重複加載引用,浪費用戶流量以及服務器成本;webpack

  2. 每一個頁面須要加載的資源太多,致使網頁首頁加載緩慢; web

提取以後有什麼優勢? 瀏覽器

  1. 相同資源只打包加載一次,減小網絡傳輸流量,下降服務器壓力; 緩存

  2. 頁面加載速度加快,提交用戶體驗; bash

具體用法 

思路 

  1. 根據項目使用的技術棧,把全部頁面都要使用到的基礎庫提取出來,造成一個`base.js`,這個文件包含技術棧運行所須要的全部基礎環境依賴;(只要技術棧不變,基本能夠持久緩存) 服務器

  2. 剔除全部公共基礎依賴代碼以後,再從全部頁面中把都依賴的公共代碼提取出來,造成一個`common.js`; 網絡

  3. 再爲每一個頁面生成一個獨立的文件,那這些文件就再也不包含`base.js`、`common.js`的代碼,只包含各個頁面獨立的業務代碼; async


定義與概念 

CommonsChunkPlugin用於提取公共代碼,根據配置,把基礎庫以及業務邏輯公共代碼抽離提取出來,減小資源重複引用; 
ui

CommonsChunkPlugin 對單入口文件不能提取公共的代碼,只能提取 webpack runtime的環境代碼;提取的對象是

配置參數

name: ''複製代碼

提取公共代碼的文件名

names: string[]複製代碼

names中配置的是入口名,不是路徑,若是這裏配置的名字與 入口chunk(輸出文件名,在entry中設置或在動態輸出)中的對應起來,則直接提取,若是沒有在entry中同名,則建立一個包含webpack運行環境的環境代碼,並做爲抽離內容,把運行環境從提取入口中抽離出來;

chunks: string[]複製代碼

chunks 配置的是提取公共代碼的源,即須要在哪些入口中提取公共的代碼;個人理解是這裏若是自由配置的話,應該是要在入口chunk那裏選擇須要提取的入口(這個不知道對不對,由於我若是直接引用文件路徑的話,效果沒看到)

若是不設置這個值,全部入口chunk,都會做爲提取的對象

filename: string複製代碼

common chunk 文件名模版,若是不設置,則不修改原來的文件名(也不會修改在name/names中配置的名字,可是若是配置了,優先使用)

minChunks: number | Infinity | function(module, count) => boolean複製代碼

number  一個模塊被提取以前,必需要在 入口chunks中出現的至少次數;

Infinity  默認是對全部chunk進行提取;

function(module, count) => boolean  自定義提取的規則

minChunks取值需大於2,小於chunks的長度(即chunks配置項的長度或全部入口的長度)

minSize: number複製代碼

在公共模塊建立以前,全部 公共模塊的最小大小

children: boolean複製代碼

若是設置爲 true,全部 公共chunk 的子模塊都會被選擇;通常不設置這個值,畢竟咱們值爲了對公共代碼的抽離,而不是想要所有抽離;不過這個也要針對不一樣的項目來處理,畢竟配置這個東西也是很自由的;

async:boolean|string複製代碼

這個暫時沒有研究出來是什麼.....

具體配置

這個的配置一點也不復雜,主要是要根據實際狀況進行配置比較複雜,狀況通常分紅下面幾種

  1. 項目是單入口應用仍是多入口應用,這決定你是否合適使用CommonsChunkPlugin  

  2. 對哪些入口chunk進行提取,這決定了 nameschunkschildren配置項的設置

  3. 提取的粒度,這決定了minChunksminSize配置項的設置

基本上根據上面幾條,而後配置entry以及plugin就OK了,抽取的思路文章開頭也提到了,因此就不列舉各類狀況了

// 提取公共代碼主要修改的範圍以下,
// manifest 的提取是把webpack啓動運行部分代碼,把部分代碼抽離出來,
// 那每次業務代碼有修改時,並不會影響到這個文件的hash,那就能夠持久化在瀏覽器,減小用戶加載的流量
module.exports = {  
  entry: {    
    main: ['./src/index.js'],    
    vendor: ['react']  
  },  
  plugins: [    
    new webpack.optimize.CommonsChunkPlugin({      
      names:['vendor', 'manifest'],          
      children: false,     // 是否對全部源chunks的子模塊都包含          
      minChunks: 2,        // 提取代碼的粒度          
      // chunks: [],       // 須要提取公共代碼的源chunks     
    }),  
  ]
}

複製代碼
相關文章
相關標籤/搜索