minSize设置的是生成文件的最小大小,单位是字节。如果一个模块符合之前所说的拆分规则,但是如果提取出来最后生成文件大小比minSize要小,那它仍然不会被提取出来。这个属性可以在每个缓存组属性中设置,也可以在splitChunks属性中设置,这样在每个缓存组都会继承这个配置。这里由于我的demo中文件非常小,为了演示效果,我把minSize设置为30字节,好让公共模块可以被提取出来,正常项目中不用设这么小。
- priority
priority属性的值为数字,可以为负数。作用是当缓存组中设置有多个拆分规则,而某个模块同时符合好几个规则的时候,则需要通过优先级属性priority来决定使用哪个拆分规则。优先级高者执行。我这里给业务代码组设置的优先级为-20,给第三方库组设置的优先级为-10,这样当一个第三方库被引用超过2次的时候,就不会打包到业务模块里了。
- test
test属性用于进一步控制缓存组选择的模块,与chunks属性的作用有一点像,但是维度不一样。test的值可以是一个正则表达式,也可以是一个函数。它可以匹配模块的绝对资源路径或chunk名称,匹配chunk名称时,将选择chunk中的所有模块。我这里用了一个正则/[\\/]node_modules[\\/]/来匹配第三方模块的绝对路径,因为通过npm或者yarn安装的模块,都会存放在node_modules目录下。
运行一下webpack:
可以看到新产生了一个叫vendor.js的文件(name属性的值),同时common.js文件体积由原来的311k减少到了861bytes!
进入dist目录,检查js文件:
a.js里不包含任何模块代码。
common.js只包含a和c模块的代码。
index.js只包含b和index模块的代码。
vendor.js只包含jquery模块的代码。
现在,我们在上一步的基础上,成功从common.js里把第三方库jquery抽离出来放到了vendor.js里。
3.2 拆分指定文件
如果我们还想把项目中的某一些文件单独拎出来打包(比如工程本地开发的组件库),可以继续添加拆分规则。比如我的src下有个locallib.js文件要单独打包,假设a.js中引入了它。
//a.js require('./c.js'); require('./locallib.js'); //引入自己本地的库 const $ = require('jquery') function fn() { console.log('a-------'); } module.exports = fn();
可以这么配置:
//webpack.config.js optimization: { splitChunks: { minSize: 30, //提取出的chunk的最小大小 cacheGroups: { default: { name: 'common', chunks: 'initial', minChunks: 2, //模块被引用2次以上的才抽离 priority: -20 }, vendors: { //拆分第三方库(通过npm|yarn安装的库) test: /[\\/]node_modules[\\/]/, name: 'vendor', chunks: 'initial', priority: -10 }, locallib: { //拆分指定文件 test: /(src\/locallib\.js)$/, name: 'locallib', chunks: 'initial', priority: -9 } } } }
我在缓存组下又新增了一个拆分规则,通过test正则指定我就要单独打包src/locallib.js文件,并且把优先级设置为-9,这样当它被多次引用时,不会进入其他拆分规则组,因为另外两个规则的优先级都比它要低。
运行webpack打包后:
可以看到新产生了一个locallib.js文件。进入dist目录查看:
a.js里不包含任何模块代码。
common.js只包含a和c模块的代码。
index.js只包含b和index模块的代码。
vendor.js只包含jquery模块的代码。
locallib.js里只包含locallib模块的代码。
现在我们又在上一步的基础上独立打包了一个指定的模块locallib.js。
至此,我们就成功实现了抽离公共模块、业务代码和第三方代码剥离、独立打包指定模块。
对比一下,优化前,打包出来js一共有633KB:
优化后,打包出来js一共不到330KB:
优化打包后的文件分类清晰,体积比优化前缩小了几乎50%,有点小完美是不是!击掌!这还只是我举的一个简单例子,在实际多页应用中,优化力度说不定还不止这么多。
小结