起初,chunks(代碼塊)和導入他們中的模塊經過webpack內部的父子關係圖鏈接.在webpack3中,經過CommonsChunkPlugin來避免他們之間的依賴重複。而在webpack4中CommonsChunkPlugin被移除,取而代之的是 optimization.splitChunks 和 optimization.runtimeChunk 配置項,下面展現它們將如何工做。html
在默認狀況下,SplitChunksPlugin 僅僅影響按需加載的代碼塊,由於更改初始塊會影響HTML文件應包含的腳本標記以運行項目。vue
webpack將根據如下條件自動拆分代碼塊:node
// index.js // 動態加載 a.js import('./a')
// a.js import 'vue' // ...
打包以後的結果會建立一個包含 vue 的獨立代碼塊,當包含 a.js 的原始代碼塊被調用時,這個獨立代碼塊會並行請求進來。webpack
咱們這樣作的緣由是由於,vue代碼並不像你的業務代碼那樣常常變更,把它單獨提取出來就能夠和你的業務代碼分開緩存,極大的提升效率。ios
// 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
helpers
是共享塊helpers
大於30kb如下是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屬性用來選擇分割哪些代碼塊,可選值有:'all'(全部代碼塊),'async'(按需加載的代碼塊),'initial'(初始化代碼塊)。數組
爲了方便演示,咱們先安裝兩個類庫: 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的基本用法,更多高級的配置你們能夠繼續鑽研(好比多入口應用)。