一步一步的了解webpack4的splitChunk插件(小结)
初衷
webpack4出了两个月,发现大家包括我对splitChunk的使用都还是在摸索阶段。我也看了挺多别人的配置demo,都觉得不太满意或者没得到太好的解惑,issue 狼蚁网站SEO优化的问题也没什么人回复,只能自己操作了,顺便记录下来,如果大家有更好的,欢迎评论区留下地址。
常用参数
- minSize(默认是30000)形成一个新代码块最小的体积
- minChunks(默认是1)在分割之前,这个代码块最小应该被引用的次数(译注保证代码块复用性,默认配置的策略是不需要多次引用也可以被分割)
- maxInitialRequests(默认是3)一个入口最大的并行请求数
- maxAsyncRequests(默认是5)按需加载时候最大的并行请求数。
- chunks (默认是async) initial、async和all
- test 用于控制哪些模块被这个缓存组匹配到。原封不动传递出去的话,它默认会选择所有的模块。可以传递的值类型RegExp、String和Function
- name(打包的chunks的名字)字符串或者函数(函数可以根据条件自定义名字)
- priority 缓存组打包的先后优先级。
如果你对这些配置还是不熟悉的话,一拉到底,看看文档
正文
先总览一下所有配置,后续会根据demo跑一遍常见的需求。
optimization: { splitChunks: { chunks: "async", // 必须三选一 "initial" | "all"(推荐) | "async" (默认就是async) minSize: 30000, // 最小尺寸,30000 minChunks: 1, // 最小 chunk ,默认1 maxAsyncRequests: 5, // 最大异步请求数, 默认5 maxInitialRequests : 3, // 最大初始化请求书,默认3 automaticNameDelimiter: '~',// 打包分隔符 name: function(){}, // 打包后的名称,此选项可接收 function cacheGroups:{ // 这里开始设置缓存的 chunks priority: 0, // 缓存组优先级 vendor: { // key 为entry中定义的 入口名称 chunks: "initial", // 必须三选一 "initial" | "all" | "async"(默认就是async) test: /react|lodash/, // 正则规则验证,如果符合就提取 chunk name: "vendor", // 要缓存的 分隔出来的 chunk 名称 minSize: 30000, minChunks: 1, enforce: true, maxAsyncRequests: 5, // 最大异步请求数, 默认1 maxInitialRequests : 3, // 最大初始化请求书,默认1 reuseExistingChunk: true // 可设置是否重用该chunk } } } },
接下来看看第一个例子
entry: { pageA: "./pageA", // 引用utility1.js utility2.js pageB: "./pageB", // 引用utility2.js utility3.js pageC: "./pageC" // 引用utility2.js utility3.js }, optimization: { splitChunks: { cacheGroups: { mons: { chunks: "initial", minChunks: 2, maxInitialRequests: 5, // The default limit is too small to showcase the effect minSize: 0 // This is example is too small to create mons chunks } } } },
结果如图,一切都很正常 mons~pageA~pageB~pageC.js 文件就是utility2.js mons~pageB~pageC.js,根据上述代码,这里的utility2被引用了三次,就被抽离了mons~pageA~pageB~pageC.js,然后utility3被引用了两次就放到了mons~pageB~pageC.js,只剩下被引用一次的utility1.js,就直接放到了pageA.js里面,如果这里的utility1.js的也是两次,他还是会新建一个chunk放进去,而不是合并到mons~pageB~pageC.js,除非同入口引用才会合并。
mpageA.js pageB.js pageC.js
这里有个地方是需要优化一下的,就是pageA.js pageB.js pageC.js的代码不多,打出来的包很大,肯定是一些webpack的运行文件,直接加上
runtimeChunk: "single" // 等价于 runtimeChunk: { name: "manifest" }
现在就好了
引用第三方模块 pageA引用vue.js pageB引用react react-dom
vendor: { test: /node_modules/, chunks: "initial", name: "vendor", priority: 10, enforce: true }
,这样子的话,会把pageA pageB pageC所有的库都打包到一起vendor.js
假如我想拆分这个vendor.js为pageA-vendor.js pageB-vendor.js怎么办,我试了很久,试出一个最简单的办法,去掉手动的vendor,让插件自动处理。
splitChunks: { chunks: "all", cacheGroups: { mons: { chunks: "initial", minChunks: 2, maxInitialRequests: 5, // The default limit is too small to showcase the effect minSize: 0 // This is example is too small to create mons chunks } } },
后来,我把webpack mode改成production后,发现不管用了,同样的配置,在生产模式下,打包出来的东西有点匪夷所思,vendor-pageB.js被合并到了pageB.js里面了。
后来我折腾了好久也分析不出来为什么,自己折腾出来一种方式,还是老子手动来吧,自动化一边去
mons: { chunks: "initial", minChunks: 2, maxInitialRequests: 5, // The default limit is too small to showcase the effect minSize: 0 // This is example is too small to create mons chunks }, 'vendor-pageA': { test: /vue/, // 直接使用 test 来做路径匹配 chunks: "initial", name: "vendor-pageA", enforce: true, }, 'vendor-pageB': { test: /react/, // 直接使用 test 来做路径匹配 chunks: "initial", name: "vendor-pageB", enforce: true, },
成功打包出来了自己想要的东西。
动态引入
动态引入大家应该都不陌生,就是大家所说的懒加载,直接在pageA和pageB页面里动态引入mon-async.js,在这里我先说说,splitChunk应该是可以自动化处理类似monChunk里的async,child等情况的。
import(/ webpackChunkName: "mon-async.js" /"./mon-async").then(mon => { console.log(mon); })
还不错,成功打包出来了
这时候再试试,在这个mon-async.js里面在引入共同的代码f.js,看看会不会重复打包
f.js成功的被抽离出来了,其他文件也没有被重复打包,挺好的。
注意的地方
- cacheGroups 会继承和覆盖splitChunks的配置项,test、priorty和reuseExistingChunk只能用于配置缓存组。。
- cacheGroups 里的每一项最好都要加上chunks参数,不然可能打包不出来你想要的东西。
- minSize 默认是30KB(注意这个体积是压缩之前的)在小于30kb的情况下一定要设置一个值,否则也可能打包不出来你想要的东西,而且这东西要加在cacheGroups里面。
- priority 在某些情况下,还是挺有用的,可以设置打包chunks的优先级。
上面的例子里面配置了一个mons,这里的name可以自己设置,也可以不设置,我是没设置的,你可以试试设置了是什么样子的,然后你就会明白这个name其实在某些情况下还是不设置的比较好。
mons: { chunks: "initial", minChunks: 2, maxInitialRequests: 5, // The default limit is too small to showcase the effect minSize: 0 , name: "mons" },
源码
参考文章
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持狼蚁SEO。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程