CommonsChunkPlugin主要是用来提取第三方库和公共模块,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大,从而导致加载时间过长,是一把优化项目的利器。
先来说一下各种教程以及文档中CommonsChunkPlugin提及到chunk有哪几种,主要有以下三种:
1.webpack当中配置的入口文件(entry)是chunk,可以理解为entry chunk
2.入口文件以及它的依赖文件通过code split (代码分割)出来的也是chunk,可以理解为children chunk
3.通过commonsChunkPlugin创建出来的文件也是chunk,可以理解为commons chunk
CommonsChunkPlugin可配置的属性:
name:可以是已经存在的chunk(一般指入口文件)对应的name,那么就会把公共模块代码合并到这个chunk上;否则,就会创建名字为name的commons chunk进行合并
filename:指定commons chunk的文件名
chunks:指定该source chunk,即指定从哪些chunk当中去找公共模块,省略该选项的时候,默认就是entry chunks
minChunks:既可以数字,也可以是函数,还可以是Infinity,具体用法和区别下面会说。
CommonsChunkPlugin插件的作用:
让我们分三步讲解:
1.不分离出第三方库和自定义公共模块
项目初始结构,后面打包后会生成dist目录:
src目录下各个文件内容都很简洁的,如下:
package.json文件:
webpack.config.js:
接着在命令行运行npm run build,此时项目中多了dist目录:
再来看一下命令行中webpack的打包信息:
查看first.js和second.js,会发现共同引用的common.js文件和jquery都被打包进去了,这肯定不合理,公共模块重复打包体积过大。
2.分离出第三方库、自定义公共模块、webpack运行文件
这时候修改webpack.config.js新增一个入口文件vendor和CommonsChunkPlugin插件进行公共模块的提取:
查看dist目录下,新增了一个vendor.js的文件:
再来查看一下命令行中webpack的打包信息:
通过查看vendor.js文件,发现first.js和second.js文件中依赖的jquery和common.js都被打包进vendor.js中,同时还有webpack的运行文件,总的来说,我们初步的目的达到,提取公共模块,但是它们都在同一个文件中。
到这里,肯定有人希望自家的vendor.js纯白无瑕,只包括第三方库,不包括自定义的公共模块和webpack运行文件,又或者希望包含第三方库和公共模块,不包含webpack运行文件。
其实,这种想法是对的,特别是分离出webpack运行文件,因为每次打包webpack运行文件都会变,如果你不分离出webpack运行文件,每次打包生成bendor.js对应的哈希值都会变化,导致vendor.js改变,但实际上你的第三方库其实是没有变,然而浏览器会认为你原来缓存的vendor.js就失效,要重新去服务器中获取,其实只是webpack运行文件变化而已,就要人家重新加载,好冤啊。。。
那么怎么解决呢?
单独分离出第三方库、自定义公共模块、webpack运行文件
这里我们分两步走:
1.先单独抽离出webpack运行文件
2.接着单独抽离第三方库和自定义公共模块,这里利用minChunks有两种方法可以完成,往后看就知道了。
1.抽离webpack运行文件
先来抽离webpack运行文件,修改webpack配置文件:
其实上面这段代码,等价于下面这段:
上面这段抽离webpack运行文件代码的意思是创建一个名为runtime的commons chunk进行webpack运行文件的抽离,其中source chunks是vendor.js。
查看dist目录下,新增了一个runtime.js的文件,其实就是webpack的运行文件:
再来查看一下命令行中webpack的打包信息,你会发现vendor.js的体积已经减小,说明已经把webpack运行文件提取出来了:
可是,vendor.js中还有自定义的公共模块common.js,人家只想vendor.js拥有项目依赖的第三方库而已(这里是jquery),这个时候把minChunks这个属性引进来。
minChunks可以设置为数字、函数和Infinity,默认值是2,并不是官方文档说的入口文件的数量,下面解释下minChunks含义:
1.数字:模块被多少个chunk公共引用才被抽取出来成为commons chunk
2.函数:接受(module,count)两个参数,返回一个布尔值,你可以在函数内进行你规定好的逻辑来决定某个模块是否提取成为commons chunk
3.Infinity:只有当入口文件(entry chunks)>3才生效,用来第三方库中分离自定义的公共模块
2、抽离第三方库和自定义公共模块
要在vendor.js中把第三方库单独抽离出来,上面也说到了有两种方法。
第一种方法minChunks设为Infinity,修改webpack配置文件如下:
查看dist目录下,新增了一个common.js的文件:
再来看一下命令行中webpack的打包信息,自定义的公共模块分离出来:
这时候的vendor.js就纯白无瑕,只包含第三方文件,common.js就是自定义的公共模块,runtime.js就是webpack的运行文件。
更多知识点请查看:https://segmentfault.com/a/1190000012828879
网友评论