浅谈webpack SplitChunksPlugin实用指南

提到前端打包工具,毫无疑问想先到的是webpack。但是前端发展地很快,时不时会有新东西出现,打包工具这边之前也出现parcel和rollup。各种工具的碰撞,相互汲取优点,促进技术的发展。

webpack4中支持了零配置的特性,同时对块打包也做了优化, CommonsChunkPlugin 已经被移除了,现在是使用 optimization.splitChunks 代替。

下面就开始介绍splitChunks的内容。

默认情况

首先webpack会根据下述条件自动进行代码块分割:

新代码块可以被共享引用,或者这些模块都是来自node_modules文件夹里面

新代码块大于30kb(min+gziped之前的体积)

按需加载的代码块,并行请求最大数量应该小于或者等于5

初始加载的代码块,并行请求最大数量应该小于或等于3

块打包默认情况下只会影响按需加载模块,因为对初始块也进行优化打包会影响HTML中的script标签数,增加请求数。

接下来看些例子来理解默认情况的打包。

模块全部是同步引入

// indexA.js import React from 'react' import ReactDOM from 'react-dom' import _ from 'lodash' console.log(_.join(['a', 'b'], '~')) ReactDOM.render( <div>SplitChunk</div>, document.getElementById('root') )

浅谈webpack SplitChunksPlugin实用指南

默认情况只会影响按需加载模块,所以所有内容全部被打包到一起了。

有模块动态导入

这里首先使用符合ECMAScript 提案 的 import() 语法

// indexA.js import React from 'react' import ReactDOM from 'react-dom' import _ from 'lodash' import(/* webpackChunkName: "async-jquery" */ 'jquery').then(component => { console.log(component) }) console.log(_.join(['a', 'b'], '~')) ReactDOM.render( <div>SplitChunk</div>, document.getElementById('root') )

浅谈webpack SplitChunksPlugin实用指南

这里jquery使用动态导入,打包结果中可以看到jquery被单独打包了

react按需加载

同样的我们试要react按需加载,使用react-router提供的按需加载方案

AsyncModule模块按上面方案异步加载Dashboard

import React from 'react' import ReactDOM from 'react-dom' import {BrowserRouter, Route} from 'react-router-dom' import AsyncModule from './AsyncModule.jsx' import _ from 'lodash' import $ from 'jquery' console.log(_.join(['a', 'b'], '~')) ReactDOM.render( <div> <BrowserRouter> <Route path='https://www.jb51.net/' component={AsyncModule} /> </BrowserRouter> </div>, document.getElementById('root') )

浅谈webpack SplitChunksPlugin实用指南

从打包结果可以看到按需加载的模块被打包到0.js去了。

讲完了webpack默认情况下对打包块的优化,接下来看splitChunks配置项。

配置项

相关配置项:

module.exports = { //... optimization: { splitChunks: { chunks: 'async', minSize: 30000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', name: true, cacheGroups: {} } } }

chunks: 表示哪些代码需要优化,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为async

minSize: 表示在压缩前的最小模块大小,默认为30000

minChunks: 表示被引用次数,默认为1

maxAsyncRequests: 按需加载时候最大的并行请求数,默认为5

maxInitialRequests: 一个入口最大的并行请求数,默认为3

automaticNameDelimiter: 命名连接符

name: 拆分出来块的名字,默认由块名和hash值自动生成

cacheGroups: 缓存组。缓存组的属性除上面所有属性外,还有test, priority, reuseExistingChunk

test: 用于控制哪些模块被这个缓存组匹配到

priority: 缓存组打包的先后优先级

reuseExistingChunk: 如果当前代码块包含的模块已经有了,就不在产生一个新的代码块

配置项基本就上面这些,我们重点来看下chunks和cacheGroups。

chunks

chunks的取值是有initial, async, all。默认情况下是async,在本文第一部分已经介绍了它的表现,所以现在来看下其它两个的表现。

initial , all 模式会将所有来自node_modules的模块分配到一个叫vendors的缓存组;所有重复引用至少两次的代码,会被分配到default的缓存组。

// indexA.js import './Dashboard.jsx' // indexB.js import './Dashboard.jsx' // Dashboard.jsx import React from 'react'

// webpack.config.js splitChunks: { chunks: 'initial' }

浅谈webpack SplitChunksPlugin实用指南

打包表现正如上面所述,产生了两个代码块vendors, default。

可以通过配置optimization.splitChunks.cacheGroups.default: false禁用default缓存组。

// webpack.config.js splitChunks: { chunks: 'initial', cacheGroups: { default: false } }

浅谈webpack SplitChunksPlugin实用指南

至于all和initial的差别,可以看下这篇文章Webpack 4 — Mysterious SplitChunks Plugin (要科学上网)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6425ced99cbd2601f45e5488fe30e753.html