基础
commons-chunk-plugin
split-chunks-plugin
即webpack的分包插件。CommonsChunkPlugin于4.0及以后被移除,使用SplitChunksPlugin替代。
chunk:块,指若干个js module的集合
bundle:形式上是块的集合,意义是代表一个可以运行的整体
chunk和bundle:what-are-module-chunk-and-bundle-in-webpack
比较难说明,搜的基本都是个人总结,官方描述也比较抽象。
就我个人总结来说,一个模块化的js文件就是一个模块,若干个js模块会打包成一个总的js文件,这个js文件称作bundle。但如果是多页面应用,往往会安排为一个html对应一个bundle,那么两个html的bundle之间重复的模块就是重复代码。此时我们会把这两个bundle重复的模块抽出来,称为common chunk,余下的两部分直接称作两个chunk。即此时一共有3个chunk,但依然只有两个bundle。
单页面应用中异步加载,或者单纯想分离出不变的第三方库,均可采用该手段进行优化。
入口chunk:entry
里面的指定的入口,他们对应一个chunk并且key值就是chunk name
CommonsChunkPlugin
最基本使用
CommonsChunkPlugin基本选项:
name
:选择一个chunk。该chunk存在则选中,不存在则新建。代表把下面的chunks他们的重复模块合并到这个chunk
chunks
:chunk来源,不设置代表选择全部入口chunk
minChunks
:被多少次重复引用时才抽出来。数量必须大于等于2,或者少于等于chunks的数量
请对照着官方示例直接上:
图解1:入口有6个,当然有6个chunk了。每个chunk都是js模块的集合,如pageA这个chunk就有4个模块
{a-b,a-c,a-b-c,pageA}
,图里省略了一些路径和入口文件的那个模块(如pageA.js也在pageA这个chunk里,但省略了),这样分析比较清楚。
良心作图2
图解2:第一个
new CommonsChunkPlugin
那个执行完成后,如图所示。有7个chunk,其中a-b-c.js和admin.js被抽出放到admin-commons中
良心作图3
图解3:minChunks为2,即重复引用两次即可抽出,显然a-b重复两次、a-b-c重复3次,均被抽出
良心作图4图解4:a-b-c抽出
最终,9个chunk,生成9个js文件。
至于“父子关系”,看图即可。假如我们要引入adminPageA.js,就要先引入admin-commons.js,因为他有部分代码在admin-commons.js;同理要引入admin-commons.js就要先引入commons.js,最终在html的导入写法如官方例子所示。
进阶使用
1.minChunks: Infinity
有何用?无穷次重复引用才抽出?
明确第三方库 chunk。注意name的说明有说是存在则选择,chunks的说明有说不写则默认选中全部入口chunk,这说明可能会把入口chunk之间重复的模块抽到vendor(早已存在,包含"jquery", "other-lib"模块)。这里只是一个保证,自己能弄明白的时候这个可以换种写法或者直接整个省略不写。
2.children
、async
弄懂这两个就算大成了,剩下的minSize、deepChildren自己猜都能猜到。
这里右转:webpack中ensure方法和CommonsChunkPlugin中的children选项
上面的例子都是基于require直接静态导入的,但是对于动态导入的require.ensure和动态import函数来说,情况比较特殊,因为他们是直接生成目标模块的chunk并挂在当前所在chunk下。如a是父亲,b、c是儿子,在动态引入情况下,b、c可能包含相同的模块。
children
、async
就是用来处理子chunk有重复模块的。
children:true
表示chunks等于当前chunk的所有子chunk(你也可以手动chunks:["..."]来选择它的所有子chunk,前提是你要清晰地知道所有子chunk的chunk name),然后逻辑同上,把选中的chunks的重复模块抽出,合并到当前模块,换种新的说法就是把子chunk重复的模块抽出到父chunk。
async:true
表示异步的,作为 options.name
的子模块,和 options.chunks
的兄弟模块被创建(官网的解释够鬼畜的)。简单来说,就是chunk的重复模块会被抽出,重新组合成一个新的chunk而不是合并到当前chunk。存在的意义基本上就是为上面那个children,作用是把子chunk重复模块抽出成新的chunk,不要合并到父chunk中
SplitChunksPlugin
不知道上面有没有绕晕你,反正是有点复杂的难说明的。因此webpack4.0后提供一个新的分包插件SplitChunksPlugin,让你可以开箱即用,高度抽象。
用法方面,直接当做webpack配置使用即可,不用再去new一个plugin
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
}
}
}
上面是默认配置,你的更改会被合并到该配置中。最外层的配置充当全局配置,可被cacheGroups中的配置给继承和局部覆盖。
这个不再需要我们去分析什么父子chunk、哪些chunk之间可能相同需要抽取等等。即使你硬要配置,也只用站在全局角度去考虑首屏静态加载的js文件最大数量maxInitialRequests、动态加载的最大js数量maxAsyncRequests等,比起CommonsChunkPlugin那坨东西舒服多了。
详细学习可右转:Webpack4之SplitChunksPlugin
网友评论