关于splitChunks的一次原理探索

本文介绍了webpack中splitChunks的使用和原理,详细解析了splitChunks如何拆分代码块,包括准备阶段的chunksInfoMap和addModuleToChunksInfoMap,分组阶段的cacheGroups处理,以及检查阶段的规则检查。通过对源码的分析,阐述了splitChunks在优化项目加载性能中的作用。
摘要由CSDN通过智能技术生成

前言

前端时间在做项目加载优化时用到了splitChunks自动拆包,后了解了一下原理写下了此文。

Modules和Chunks

Modules简单来理解就是我们写的功能模块,不管是CommonJS还是ESM都算是一个Module,而Chunks则是webpack根据我们的规则/默认规则打包处理之后生成的产物,比如下图:

SplitChunks如何使用

关于拆包的具体使用,这里贴一个官网的例子简单说说,关于其他配置可参考webpack官网

splitChunks: { 
    chunks: "async", //chunks有三个值,initial表示直接引入的模块,async表示按需引入的模块,all则表示all in
    minSize: 30000, //最小包体积,这里的单位是byte,超过这个大小的包会被splitChunks优化
    minChunks: 1, //模块的最小引用次数,如果引用次数低于这个值,将不会被优化
    maxAsyncRequests: 5, //设置async chunks的最大并行请求数
    maxInitialRequests: 3, //设置initial chunks的最大并行请求数
    automaticNameDelimiter: '~', //产出chunks的文件名分割符
    name: true, //true:根据提取chunk的名字自动生成,false:根据缓存组IdHint生成,string:生成文件命即为这个string
    cacheGroups: { //缓存组,自定义拆包规则在此定义
        vendors: { //默认配置,node_modules的chunk
            test: /[\/]node_modules[\/]/, 
            priority: -10 
      }, 
            default: { //业务代码的chunk
            minChunks: 2, 
            priority: -20, 
            reuseExistingChunk: true //复用已存在的chunks
      } 
  } 
} 

而这一套默认的配置,则是在webpack里面默认定义的,我们可以在WebpackOptionsDefaulter.js里面找到它(当然还有别的配置项):

this.set("optimization.splitChunks", {});this.set("optimization.splitChunks.hidePathInfo", "make", options => {return isProductionLikeMode(options);});this.set("optimization.splitChunks.chunks", "async");this.set("optimization.splitChunks.minSize", "make", options => {return isProductionLikeMode(options) ? 30000 : 10000;//默认配置的minsize根据环境配置是不同的,生产环境的最小体积为30000byte,这里没有找到这样设置的理由,估计是因为开发环境的打包速度更为重要吧});this.set("optimization.splitChunks.minChunks", 1);this.set("optimization.splitChunks.maxAsyncRequests", "make", options => {return isProductionLikeMode(options) ? 5 : Infinity;});this.set("optimization.splitChunks.automaticNameDelimiter", "~");this.set("optimization.splitChunks.automaticNameMaxLength", 109);this.set("optimization.splitChunks.maxInitialRequests", "make", options => {return isProductionLikeMode(options) ? 3 : Infinity;});this.set("optimization.splitChunks.name", true);this.set("optimization.splitChunks.cacheGroups", {});this.set("optimization.splitChunks.cacheGroups.default", {//这里也就是我们看到的默认将业务代码和mode_modules单独拆分的初始化代码automaticNamePrefix: "",reuseExistingChunk: true,minChunks: 2,priority: -20});this.set("optimization.splitChunks.cacheGroups.vendors", {automaticNamePrefix: "vendors",test: /[\/]node_modules[\/]/,priority: -10}); 

接下来举个实际使用例子吧:

splitChunks: { 
     chunks: 'all', 
      automaticNameDelimiter: '.', 
      name: true, 
      minSize: 30000, 
      maxSize: 0, 
      minChunks: 1, 
      maxAsyncRequests: 10, 
      maxInitialRequests: 6, 
      cacheGroups: {
        antdesigns: { 
          name: 'antdesigns',
          test: /[\/]node_modules[\/](@antd|antd|@ant-design)[\/]/,
          priority: 10
      },
        reactfileviewer: { 
          name: 'reactfileviewer',
          test: /[\/]node_modules[\/](react-file-viewer)[\/]/,
          priority: 10
      },
        pdfmake: { 
          name: 'pdfmake',
          test: /[\/]node_modules[\/](pdfmake)[\/]/,
          priority: 10
      },
        bizcharts: { 
          name: 'bizcharts',
          test: /[\/]node_modules[\/](bizcharts)[\/]/,
          priority: 10
      },
        commons: {
          name: 'commons',
          test: /[\/]src[\/]/,
          priority: 1
      },
        vendors: {
          name: 'vendors',
          test: /[\/]node_modules[\/]/,
          priority: -1
      },
} 

这里值得注意的是,在我们的配置里面,任何一项不满足都不会进入该项的拆包逻辑

SplitChunks原理

接下来我们结合源码看看SplitChunks的运行原理&#x

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值