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

1. SplitChunksPlugin的概念

起初乾巧,chunks(代碼塊)和導(dǎo)入他們中的模塊通過webpack內(nèi)部的父子關(guān)系圖連接.在webpack3中预愤,通過CommonsChunkPlugin來避免他們之間的依賴重復(fù)植康。而在webpack4中CommonsChunkPlugin被移除,取而代之的是 optimization.splitChunks 和 optimization.runtimeChunk 配置項,下面展示它們將如何工作存崖。

在默認(rèn)情況下睡毒,SplitChunksPlugin 僅僅影響按需加載的代碼塊,因為更改初始塊會影響HTML文件應(yīng)包含的腳本標(biāo)記以運行項目供搀。

webpack將根據(jù)以下條件自動拆分代碼塊:

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

舉例1:

// index.js

// 動態(tài)加載 a.js
import('./a')
// a.js
import 'vue'

// ...

打包之后的結(jié)果會創(chuàng)建一個包含 vue 的獨立代碼塊,當(dāng)包含 a.js 的原始代碼塊被調(diào)用時趁曼,這個獨立代碼塊會并行請求進(jìn)來棕洋。

原因:

  • vue 來自 node_modules 文件夾
  • vue 體積超過30KB
  • 導(dǎo)入調(diào)用時的并行請求數(shù)為2
  • 不影響頁面初始加載

我們這樣做的原因是因為,vue代碼并不像你的業(yè)務(wù)代碼那樣經(jīng)常變動摄悯,把它單獨提取出來就可以和你的業(yè)務(wù)代碼分開緩存愧捕,極大的提高效率。

舉例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

// ...

結(jié)果:將創(chuàng)建一個單獨的塊,其中包含./helpers它的所有依賴項管跺。在導(dǎo)入調(diào)用時禾进,此塊與原始塊并行加載。

原因:

  • 條件1:helpers 是共享塊
  • 條件2:helpers大于30kb
  • 條件3:導(dǎo)入調(diào)用的并行請求數(shù)為2
  • 條件4:不影響初始頁面加載時的請求

2. SplitChunksPlugin的默認(rèn)配置

以下是SplitChunksPlugin的默認(rèn)配置:

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

緩存組:

緩存組因該是SplitChunksPlugin中最有趣的功能了艇拍。在默認(rèn)設(shè)置中卸夕,會將 node_mudules 文件夾中的模塊打包進(jìn)一個叫 vendors的bundle中婆瓜,所有引用超過兩次的模塊分配到 default bundle 中。更可以通過 priority 來設(shè)置優(yōu)先級碍讨。

chunks:

chunks屬性用來選擇分割哪些代碼塊蒙秒,可選值有:'all'(所有代碼塊),'async'(按需加載的代碼塊)覆获,'initial'(初始化代碼塊)瓢省。

3. 在項目中添加SplitChunksPlugin

為了方便演示,我們先安裝兩個類庫: lodash 和 axios摹量,

npm i lodash axios -S

修改 main.js馒胆,引入 lodash 和axios 并調(diào)用相應(yīng)方法:

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: '標(biāo)題',
    content: '內(nèi)容',
    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纠俭,配置為函數(shù)時冤荆,返回當(dāng)前的entry對象,即可分入口設(shè)置不同的runtime匙赞。

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

npm i webpack-bundle-analyzer -D

引入:

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

使用,在plugins數(shù)組中添加即可:

new BundleAnalyzerPlugin()

打包之后:

?

?

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

?

以上就是SplitChunksPlugin的基本用法匹中,更多高級的配置大家可以繼續(xù)鉆研(比如多入口應(yīng)用)。

傳送門:

webpack4系列教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挂绰,一起剝皮案震驚了整個濱河市葵蒂,隨后出現(xiàn)的幾起案子重虑,更是在濱河造成了極大的恐慌,老刑警劉巖缺厉,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件提针,死亡現(xiàn)場離奇詭異,居然都是意外死亡关贵,警方通過查閱死者的電腦和手機(jī)揖曾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來练链,“玉大人奴拦,你說我怎么就攤上這事〈硌” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵潮模,是天一觀的道長痴施。 經(jīng)常有香客問我究流,道長动遭,這世上最難降的妖魔是什么厘惦? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮炎疆,結(jié)果婚禮上国裳,老公的妹妹穿的比我還像新娘全跨。我一直安慰自己,他們只是感情好浓若,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布挪钓。 她就那樣靜靜地躺著,像睡著了一般碌上。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上天梧,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天霞丧,我揣著相機(jī)與錄音,去河邊找鬼后豫。 笑死突那,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饭豹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼它褪,長吁一口氣:“原來是場噩夢啊……” “哼翘悉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起妖混,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤制市,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后祥楣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡责鳍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年历葛,在試婚紗的時候發(fā)現(xiàn)自己被綠了嘀略。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡宏娄,死狀恐怖逮壁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卖宠,我是刑警寧澤忧饭,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站刺洒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏逆航。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一拇惋、第九天 我趴在偏房一處隱蔽的房頂上張望抹剩。 院中可真熱鬧,春花似錦胡嘿、人聲如沸境蔼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吴藻。三九已至弓柱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矢空,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工粥血, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留酿箭,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓缔御,卻偏偏與公主長得像妇蛀,于是被迫代替她去往敵國和親笤成。 傳聞我的和親對象是個殘疾皇子眷茁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容