通过webpack打包提取公共代码
提取公共代码的必要性
网站都是由多个页面组成的,一般来说所有的页面采用的都是相同的技术栈,要么都是Vue,都是React,要么都是Angular,采用的技术是一致的,既然是一致的,就会有公共的代码,有很多代码是相同的,如果每个页面都将这些相同的公共代码包含进去,会引起一些问题。
- 相同的资源配重复加载,造成了资源的浪费,(最后的静态资源包会很大)
- 每个页面打开的时间会变长(影响用户体验)
因为第一个原因,导致了第二个原因,所以我们将公共代码抽离出来,在用户打开一个页面的时候,顺便加载了公共的文件,在打开其他页面的时候,如果其他页面也引用了这个公共文件,就不用重新加载,直接从浏览器缓存中获取,这么做解决了以上的两个问题。
有人说通过cdn加载公共静态资源也可以解决以上问题,对此,我说:
什么是CDN
内容分发网络,加速网络传输,就是通过将资源部署到世界各地,用户访问时按照就近原则从最近的服务器获取资源,来提高获取资源的速度,cdn就是对http的提速
综合以上,cdn在数据传输层面上降低了用户打开首页的时间,和webpack提取公共打码不是一个方向
如何提取公共代码?
从webpack4开始官方移除了commonchunk插件,改用了optimization属性进行更加灵活的配置,这也应该是从V3升级到V4的代码修改过程中最为复杂的一部分
看官网介绍一些基本参数
参数不少,我门之前介绍过过前两个
minimize
如果mode是production类型,minimize的默认值是true,执行默认压缩,
minimizer
当然如果想使用第三方的压缩插件也可以在optimization.minimizer的数组列表中进行配置
SplitChunksPlugin
这一篇文章《webpack4:连奏中的进化》详细介绍了CommonsChunkPlugin和SplitChunksPlugin的区别,以及前者的缺点和后者的优点
一些常用配置如下
splitChunks: {
chunks: "async”,//默认作用于异步chunk,值为all/initial/async/function(chunk),值为function时第一个参数为遍历所有入口chunk时的chunk模块,chunk._modules为chunk所有依赖的模块,通过chunk的名字和所有依赖模块的resource可以自由配置,会抽取所有满足条件chunk的公有模块,以及模块的所有依赖模块,包括css
minSize: 30000, //表示在压缩前的最小模块大小,默认值是30kb
minChunks: 1, // 表示被引用次数,默认为1;
maxAsyncRequests: 5, //所有异步请求不得超过5个
maxInitialRequests: 3, //初始话并行请求不得超过3个
automaticNameDelimiter:'~',//名称分隔符,默认是~
name: true, //打包后的名称,默认是chunk的名字通过分隔符(默认是~)分隔
cacheGroups: { //设置缓存组用来抽取满足不同规则的chunk,下面以生成common为例
common: {
name: 'common', //抽取的chunk的名字
chunks(chunk) { //同外层的参数配置,覆盖外层的chunks,以chunk为维度进行抽取
},
test(module, chunks) { //可以为字符串,正则表达式,函数,以module为维度进行抽取,只要是满足条件的module都会被抽取到该common的chunk中,为函数时第一个参数是遍历到的每一个模块,第二个参数是每一个引用到该模块的chunks数组。自己尝试过程中发现不能提取出css,待进一步验证。
},
priority: 10, //优先级,一个chunk很可能满足多个缓存组,会被抽取到优先级高的缓存组中
minChunks: 2, //最少被几个chunk引用
reuseExistingChunk: true,// 如果该chunk中引用了已经被抽取的chunk,直接引用该chunk,不会重复打包代码
enforce: true // 如果cacheGroup中没有设置minSize,则据此判断是否使用上层的minSize,true:则使用0,false:使用上层minSize
}
}
}
- chunks: 表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all;
- minSize: 表示在压缩前的最小模块大小,默认是30kb;
- minChunks: 表示被引用次数,默认为1;
- maxAsyncRequests: 最大的按需(异步)加载次数,默认为1;
- maxInitialRequests: 最大的初始化加载次数,默认为1;
- name: 拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成,如果是true,将自动生成基于块和缓存组键的名称。如果是字符串或函数将允许您使用自定义名称。如果名称与入口点名称匹配,则入口点将被删除。
- automaticNameDelimiter:'',名称分隔符,默认是
- cacheGroups: 缓存组。
runtimeChunk
将包含chunks 映射关系的 list单独从 app.js里提取出来,因为每一个 chunk 的 id 基本都是基于内容 hash 出来的,所以你每次改动都会影响它,如果不将它提取出来的话,等于app.js每次都会改变。缓存就失效了。
参考链接
webpack4升级完全指南
webpack4——SplitChunksPlugin使用指南
webpack4:连奏中的进化
网友评论