webpack4系列教程(六):使用SplitChunksPlugin分割代碼

1. SplitChunksPlugin的概念

起初,chunks(代碼塊)和導入他們中的模塊經過webpack內部的父子關係圖鏈接.在webpack3中,經過CommonsChunkPlugin來避免他們之間的依賴重複。而在webpack4中CommonsChunkPlugin被移除,取而代之的是 optimization.splitChunks 和 optimization.runtimeChunk 配置項,下面展現它們將如何工做。html

在默認狀況下,SplitChunksPlugin 僅僅影響按需加載的代碼塊,由於更改初始塊會影響HTML文件應包含的腳本標記以運行項目。vue

webpack將根據如下條件自動拆分代碼塊:node

  • 會被共享的代碼塊或者 node_mudules 文件夾中的代碼塊
  • 體積大於30KB的代碼塊(在gz壓縮前)
  • 按需加載代碼塊時的並行請求數量不超過5個
  • 加載初始頁面時的並行請求數量不超過3個

舉例1:

// index.js

// 動態加載 a.js
import('./a')

// a.js
import 'vue'

// ...

打包以後的結果會建立一個包含 vue 的獨立代碼塊,當包含 a.js 的原始代碼塊被調用時,這個獨立代碼塊會並行請求進來。webpack

 緣由:

  • vue 來自 node_modules 文件夾
  • vue 體積超過30KB
  • 導入調用時的並行請求數爲2
  • 不影響頁面初始加載

咱們這樣作的緣由是由於,vue代碼並不像你的業務代碼那樣常常變更,把它單獨提取出來就能夠和你的業務代碼分開緩存,極大的提升效率。ios

舉例2:

// entry.js

import("./a");
import("./b");

// a.js
import "./helpers"; // helpers is 40kb in size

// ...

// b.js
import "./helpers";
import "./more-helpers"; // more-helpers is also 40kb in size

// ...

結果:將建立一個單獨的塊,其中包含./helpers它的全部依賴項。在導入調用時,此塊與原始塊並行加載。web

緣由:

  • 條件1:helpers 是共享塊
  • 條件2:helpers大於30kb
  • 條件3:導入調用的並行請求數爲2
  • 條件4:不影響初始頁面加載時的請求

2. SplitChunksPlugin的默認配置

如下是SplitChunksPlugin的默認配置:npm

splitChunks: {
    chunks: "async",
    minSize: 30000, // 模塊的最小體積
    minChunks: 1, // 模塊的最小被引用次數
    maxAsyncRequests: 5, // 按需加載的最大並行請求數
    maxInitialRequests: 3, // 一個入口最大並行請求數
    automaticNameDelimiter: '~', // 文件名的鏈接符
    name: true,
    cacheGroups: { // 緩存組
        vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
        },
        default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true
        }
    }
}

緩存組:

緩存組因該是SplitChunksPlugin中最有趣的功能了。在默認設置中,會將 node_mudules 文件夾中的模塊打包進一個叫 vendors的bundle中,全部引用超過兩次的模塊分配到  default bundle 中。更能夠經過 priority 來設置優先級。axios

chunks:

chunks屬性用來選擇分割哪些代碼塊,可選值有:'all'(全部代碼塊),'async'(按需加載的代碼塊),'initial'(初始化代碼塊)。數組

3. 在項目中添加SplitChunksPlugin

爲了方便演示,咱們先安裝兩個類庫: lodash 和 axios,緩存

npm i lodash axios -S

修改 main.js,引入 lodash 和axios 並調用相應方法:

import Modal from './components/modal/modal'
import './assets/style/common.less'
import _ from 'lodash'
import axios from 'axios'
const App = function () {
  let div = document.createElement('div')
  div.setAttribute('id', 'app')
  document.body.appendChild(div)
  let dom = document.getElementById('app')
  let modal = new Modal()
  dom.innerHTML = modal.template({
    title: '標題',
    content: '內容',
    footer: '底部'
  })
}
const app = new App()
console.log(_.camelCase('Foo Bar'))
axios.get('aaa')

使用SplitChunksPlugin不須要安裝任何依賴,只需在 webpack.config.js 中的 config對象添加 optimization 屬性:

optimization: {
    splitChunks: {
      chunks: 'initial',
      automaticNameDelimiter: '.',
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: 1
        }
      }
    },
    runtimeChunk: {
      name: entrypoint => `manifest.${entrypoint.name}`
    }
  }

配置 runtimeChunk 會給每一個入口添加一個只包含runtime的額外的代碼塊,name 的值也能夠是字符串,不過這樣就會給每一個入口添加相同的 runtime,配置爲函數時,返回當前的entry對象,便可分入口設置不一樣的runtime。

咱們再安裝一個 webpack-bundle-analyzer,這個插件會清晰的展現出打包後的各個bundle所依賴的模塊:

npm i webpack-bundle-analyzer -D

引入:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

使用,在plugins數組中添加便可:

new BundleAnalyzerPlugin()

打包以後:

各個模塊依賴清晰可見,打開 dist/index.html可見咱們的代碼順利運行:

以上就是SplitChunksPlugin的基本用法,更多高級的配置你們能夠繼續鑽研(好比多入口應用)。

相關文章
相關標籤/搜索