webpack4——splitChunks

webpack4也已经出来好久了,之前写了一篇CommonsChunksplugin的,但webpack4已经废弃了CommonsChunksplugin,改用了splitChunks;splitChunks在用法上和思想用都有所不同,更加方便,优化方式更好,但是总体来说,还是大同小异。

用法

webpack4打包优化直接写在配置项里面,而不是写在插件里面,这是splitChunks的默认配置:


module.exports = {
    //...
    entry:{},
    optimization: {
        splitChunks: {
            chunks: 'async',
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                default: {
                    test: function (module, chunks) {
                        return true
                    },
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        }
    },
 }

配置项详解

splitChunks和CommonsChunksplugin的配置项是差不多的。

1. chunks

string | Function(chunk) 抽取公共模块的来源

string:只有三个值async(动态加载模块),initial(入口模块),all(全部模块入口和动态的)。
Function(chunk): chunk对象包含chunk本身的许多信息,有用的也就是chunk.name,可以通过name选择特定的模块来源,返回true则选中,否则不选中。

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks (chunk) {
        // 选择名字为`my-excluded-chunk`的模块。
        return chunk.name !== 'my-excluded-chunk';
      }
    }
  }
};
2. maxAsyncRequests

Numberdefault:5
异步的按需加载模块最大的并行请求数,通过import()或者require.ensure()方式引入的模块,分离出来的包是异步加载的。

3. maxInitialRequests

Number default:3
初始加载网页的最大并行数.

5. minSize

Number default:30000
打包出来的新的chunk需要满足的最小文件大小,否则不打包,单位B,默认30000

6. maxSize

Number default:0 ;
打包出来的新的chunk最大的文件大小,与minSize相对,超过这个值,将新的chunk再进一步拆分成更小的chunk,单位B,默认0

minSize、maxsize、maxAsyncRequests、maxInitalRequests,相互之间可能存在冲突,比如分离出来的包>maxSize,需要进一步拆分chunk,拆分出来的chunk大小<minSize,或者说拆分出来chunk之后,chunk的数量>maxInitalRequests,这个时候怎么办?它们之间是有优先级的:minSize > maxSize > maxInitialRequest/maxAsyncRequests,也就是我必须先满足minSize才会考虑是否满足maxSize,最后才考虑maxInitialRequest/maxAsyncRequests的条件

7. automaticNameDelimiter

sring
name连接符,分离出来的新chunk的名字,默认基于cacheGroupsKey,chunks来源的name来取,例:缓存组的cacheGroupsKey是vendor,来源chunk是的name是adminAadminB,那么连接符是~,分离出的chunk名字是vendor~adminA~adminB.js

8. name

Boolean | string | function (module, chunks, cacheGroupKey)
分离出来的chunk的取名规则。不能和入口文件同名,如果和入口文件同名,那么入口文件将会被移除,不会被打包

  • Boolean :如果是true,基于cacheGroupsKey,chunks来源的name来取。如果是false,按照数字0排序。
  • string : string作为name, string.js。
  • function (module, chunks, cacheGroupKey):
    1. cacheGroupKey: 缓存组的键名;
    2. chunks: Array类型,splitChunks.chunks的数组集合,每一个chunk对象有很多属性,这里有用也就只有chunks[i].name,即打包来源chunk的键名;
    3. module: 可能有用的值module.contextmodule.resourcemodule.type;module.context公共模块来源chunk的所在文件夹,例如通过 npm 下载的包chunks.context == path.resolve(__dirname , ‘node_modules’);,module.resource公共模块来源chunk的完整路径,module.type文件类型javascript/autocss/auto
    4. 返回值: 返回值作为文件名,同样不能和入口文件同名,否则入口文件会被移除

分割线


上面的默认配置并不好用,也不需要配置,如果你要做精细化的代码分离,需要配置缓存组cacheGroups,cacheGroups拥有上面所有的属性,除此之外还有priorityreuseExistingChunktestenforce四个属性,并且缓存组能够覆盖上面所有的属性。

  1. priority :优先级,default:0;如果两个缓存组都需要将某一公共模块打包,为了不重复打包,肯定只能打包进入其中之一,那么优先考虑priority 高的。
  2. reuseExistingChunk:是否重用已经存在的模块,default:true;例:如果在当前缓存组需要抽离出 jquery.js,但是 jquery.js已经被其它缓存组抽取出来了,那么将会重用已经抽取出来的 jquery.js。
  3. test:function (module, chunks) | RegExp | string 在chunks的基础上,精确的选择那些公共模块应该被打包
  4. enforce:忽略minSize、maxSize、maxAsyncRequests、maxInitalRequests等限制条件直接打包。

缓存组也有默认配置 default ,default的配置会覆盖splitChunks中的默认配置,并且其它缓存组的minSize的优先级低于default缓存组的优先级,所以默认配置最好还是在splitChunks配置,不要在缓存组配置:

optimization: {
        splitChunks: {
            cacheGroups: {
                default: 
                    chunks: "all",
                    priority: -20,
                    reuseExistingChunk: true,
                }
            }
        }
    },

抽取第三方库:test用正则匹配路径中包含“/node_modules/”的模块,name叫vendor,否则name是基于缓存组的键名(此处是“vendor”,默认的是“default”)和chunks来取名的。
example1: 抽取第三方库,adminA和adminB都引入了jquery。

module.exports = {
    mode: 'production',
    context: path.resolve(__dirname),
    entry: {
        adminA: "./adminA.js",
        adminB: "./adminB.js"
    },
    output: {
        filename: "[name].js",
        chunkFilename: "[name].chunk.js",
        path: path.resolve(__dirname, 'dist')
    },
    optimization: {
        splitChunks: {
            chunks: "all",
            maxSize: 80000,
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: "vendor",
                    chunks: "all",
                    minSize:20000
                },
            }
        }
    }
}

在这里插入图片描述

example2: 抽取公共类,adminA和adminB都引入了jquery和childA,childA>20kb。此处分离出来的包name是default ~ adminA ~ adminB ~ 07dd53af.chunk.js”,default是默认配置缓存组的键名,adminA和adminB是chunks来源。
在这里插入图片描述
example3: 在exmaple2的基础上,减少chuildA的体积,此处childA<20kb;minSize:设置为20000;

 optimization: {
        splitChunks: {
            maxSize: 80000,
            //添加
            minSize: 20000
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: "vendor",
                    chunks: "all"
                },
            }
        }
    },

结果:childA没有被分离出来。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值