内容简介:起初,chunks(代码块)和导入他们中的模块通过webpack内部的父子关系图连接.在webpack3中,通过CommonsChunkPlugin来避免他们之间的依赖重复。而在webpack4中CommonsChunkPlugin被移除,取而代之的是 optimization.splitChunks 和 optimization.runtimeChunk 配置项,下面展示它们将如何工作。在默认情况下,SplitChunksPlugin 仅仅影响按需加载的代码块,因为更改初始块会影响HTML文件应包含的脚本
1. SplitChunksPlugin的概念
起初,chunks(代码块)和导入他们中的模块通过webpack内部的父子关系图连接.在webpack3中,通过CommonsChunkPlugin来避免他们之间的依赖重复。而在webpack4中CommonsChunkPlugin被移除,取而代之的是 optimization.splitChunks 和 optimization.runtimeChunk 配置项,下面展示它们将如何工作。
在默认情况下,SplitChunksPlugin 仅仅影响按需加载的代码块,因为更改初始块会影响HTML文件应包含的脚本标记以运行项目。
webpack将根据以下条件自动拆分代码块:
- 会被共享的代码块或者 node_mudules 文件夹中的代码块
- 体积大于30KB的代码块(在gz压缩前)
- 按需加载代码块时的并行请求数量不超过5个
- 加载初始页面时的并行请求数量不超过3个
举例1:
// index.js // 动态加载 a.js import('./a')
// a.js import 'vue' // ...
打包之后的结果会创建一个包含 vue 的独立代码块,当包含 a.js 的原始代码块被调用时,这个独立代码块会并行请求进来。
原因:
- vue 来自 node_modules 文件夹
- vue 体积超过30KB
- 导入调用时的并行请求数为2
- 不影响页面初始加载
我们这样做的原因是因为,vue代码并不像你的业务代码那样经常变动,把它单独提取出来就可以和你的业务代码分开缓存,极大的提高效率。
举例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
它的所有依赖项。在导入调用时,此块与原始块并行加载。
原因:
helpers helpers
2. SplitChunksPlugin的默认配置
以下是SplitChunksPlugin的默认配置:
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 来设置优先级。
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的基本用法,更多高级的配置大家可以继续钻研(比如多入口应用)。
本人才疏学浅,不当之处欢迎批评指正。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Webpack:代码分割
- React服务端渲染(代码分割和数据预取)
- 从零开始实现穿衣图像分割完整教程(附python代码演练)
- webpack4.29.x成神之路(十九) css代码分割
- webpack4.29.x成神之路(十五) 代码分割(code spliting)上
- CVPR2019| 12篇CVPR论文开源代码(DeepFashion2/语义分割/人脸数据集基准等)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。