webpack SplitChunksPlugin

因为在印记中文的SplitChunksPlugin部分翻译任务被认领了,所以依据webpack官网的SplitChunksPlugin部分翻译一下。

SplitChunksPlugin

最初,代码块(以及导入其中的模块)是通过webpack内部的图形的父子关系连接的。CommonsChunkPlugin 用于避免重复的依赖关系,但是无法进一步优化

从webpack4开始,CommonsChunkPlugin被移除,开始使用optimization.splitChunks。

Defaults

开箱即用的SplitChunksPlugin应该更适用于大部分用户。
默认情况下,它只会影响按需加载的块,因为更改初始块会影响脚本标记,所以HTML文件应包含该脚本以运行项目。

webpack会根据以下条件自动分割代码块
  • 可以被分享的块或者来自node_modules文件夹的模块
  • 大于20kb的块
  • 按需加载块时并行请求的最大数量将小于或等于30
  • 初始页面加载时并行请求的最大数量将小于或等于30
当都满足最后两个条件时,首选是大的块。

Configuration

webpack给想要对这个功能更加可配置的开发者提供了一组选项

⚠️ 注意
选择默认的配置以满足web性能最佳体验,但是项目的最佳策略可能会有所不同。如果你修改了配置,你应该衡量更改的影响以确保能真正的提高性能。

optimization.splitChunks

以下的配置对象代表了SplitChunksPlugin的默认行为
webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 20000,
      minRemainingSize: 0,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

注意
当文件路径被webpack处理的时候,它们在Unix系统上始终包含/,在Windows上始终包含\。
这就是为什么有必要在{cacheGroup} .test字段中使用[\ /]来表示路径分隔符。在跨平台使用时,{cacheGroup} .test中的/或\将导致问题。

注意
从webpack 5开始,不再允许通过一个入口名传递给{cacheGroup}.test和将现有块的名字命{cacheGroup}.name

splitChunks.automaticNameDelimiter

string = '~'

默认情况下,webpack会使用来源或者块的名称生成名称(例如,vendors〜main.js)。上面这个选项可以让你指定生成名字的分隔符。

splitChunks.chunks

string = 'async' function (chunk)

这个配置表明选择哪些块进行优化,当规定为字符串时,有效值为all, async, and initial。为all时会尤其强大,因为意味着这些块可以在在异步和非异步块之间也可以共享块。

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      // include all types of chunks
      chunks: 'all'
    }
  }
};

或者你可以提供更多控制功能。返回值将指明是否包括每个块。

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks (chunk) {
        // exclude `my-excluded-chunk`
        return chunk.name !== 'my-excluded-chunk';
      }
    }
  }
};

⚠️ 提示
您可以将此配置与HtmlWebpackPlugin结合使用。它将为您注入所有生成的vendor(第三方库)块。

splitChunks.maxAsyncRequests

number = 30

按需加载时并行请求的最大数量。

splitChunks.defaultSizeTypes

[string] = ['javascript', 'unknown']

设置将数字用于尺寸时使用的尺寸类型。

splitChunks.minChunks

number = 1

分割之前,模块必须在块之间共享的最短时间

splitChunks.hidePathInfo

boolean

为通过maxSize拆分的部分创建姓名时,防止暴露路径信息

splitChunks.minSize

number = 20000

生成块的最小大小(以字节为单位)

splitChunks.enforceSizeThreshold

splitChunks.cacheGroups.{cacheGroup}.enforceSizeThreshold
number = 50000

强制执行拆分的大小阈值和其他限制(minRemainingSize,maxAsyncRequests,maxInitialRequests)将被忽略。

splitChunks.minRemainingSize
splitChunks.cacheGroups.{cacheGroup}.minRemainingSize

number = 0

webpack 5中引入了splitChunks.minRemainingSize选项,通过确保拆分后剩余的最小块大小大于限制来避免大小为零的模块。开发模式下默认为0。在其他情况下,splitChunks.minRemainingSize的默认值为splitChunks.minSize的值,因此除极少数需要过度干预的情况外,无需手动指定它。

提示
splitChunks.minRemainingSize仅在剩余单个块时生效

splitChunks.layer

splitChunks.cacheGroups.{cacheGroup}.layer
RegExp string function

按模块层将模块分配给缓存组。



中间的方法太多了,有兴趣可以去官网看,下面主要翻译一下比较重要的cacheGroups

splitChunks.cacheGroups

缓存组可以继承或者覆盖所有splitChunks中的任何选项。但是test, priority 和reuseExistingChunk只能在缓存组级别上配置。如果想要禁用任何默认缓存组,把他们设置为false。

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        default: false
      }
    }
  }
};
splitChunks.cacheGroups.{cacheGroup}.priority
number = -20

一个模块可以属于多个缓存组。会优先选择 priority 较高的缓存组进行优化。把默认组的优先级设置为负,就可以让自定义组获得更高的优先级(自定义组默认值为0)

splitChunks.cacheGroups.{cacheGroup}.reuseExistingChunk
boolean = true

如果当前的块包含着从主模块中分离出来的模块,它会被重用,而不是生成新的。这可能会影响块的结果文件名。

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          reuseExistingChunk: true
        }
      }
    }
  }
};
splitChunks.cacheGroups.{cacheGroup}.type
function RegExp string

允许按模块类型将模块分配给缓存组。

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        json: {
          type: 'json'
        }
      }
    }
  }
};
splitChunks.cacheGroups.test
splitChunks.cacheGroups.{cacheGroup}.test
function (module, chunk) => boolean RegExp string

过滤 modules,默认为所有的 modules,可匹配模块路径或 chunk 名字。当一个块的名字被匹配,将选择块中的所有模块。
为{cacheGroup}.test提供函数:

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        svgGroup: {
          test(module, chunks) {
            // `module.resource` contains the absolute path of the file on disk.
            // Note the usage of `path.sep` instead of / or \, for cross-platform compatibility.
            const path = require('path');
            return module.resource &&
                 module.resource.endsWith('.svg') &&
                 module.resource.includes(`${path.sep}cacheable_svgs${path.sep}`);
          }
        },
        byModuleTypeGroup: {
          test(module, chunks) {
            return module.type === 'javascript/auto';
          }
        }
      }
    }
  }
};

为了查看模块和块对象中可用的信息,你可以断点调试;回调中的声明。然后以调试模式运行webpack构建,以检查Chromium DevTools中的参数。
为{cacheGroup}.test提供正则表达式:

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          // Note the usage of `[\\/]` as a path separator for cross-platform compatibility.
          test: /[\\/]node_modules[\\/]|vendor[\\/]analytics_provider|vendor[\\/]other_lib/
        }
      }
    }
  }
};
splitChunks.cacheGroups.{cacheGroup}.filename
string function (pathData, assetInfo) => string

当且仅当是一个初始化的块才允许覆盖文件名。在output.filename中可用的所有占位符也在此处可用。

⚠️ 注意
也可以在splitChunks.filename中全局设置此选项,但这样是不建议这样做,如果splitChunks.chunks没有设置为‘initial’可能会导致错误。应当避免全局设置。

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          filename: '[name].bundle.js'
        }
      }
    }
  }
};

并且作为函数:

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          filename: (pathData) => {
            // Use pathData object for generating filename string based on your requirements
            return `${pathData.chunk.name}-bundle.js`;
          }
        }
      }
    }
  }
};

可以通过在文件名前添加路径来创建文件夹

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          filename: 'js/[name]/bundle.js'
        }
      }
    }
  }
};
splitChunks.cacheGroups.{cacheGroup}.enforce
boolean = false

告知webpack忽略splitChunks.minSize, splitChunks.minChunks, splitChunks.maxAsyncRequests 和splitChunks.maxInitialRequests选项,并且总会为此缓存组创建块。

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          enforce: true
        }
      }
    }
  }
};
splitChunks.cacheGroups.{cacheGroup}.idHint
string

设置块ID的提示。它将被添加到块的文件名中。

webpack.config.js
module.exports = {
  //...
  optimization: {
    splitChunks: {
      cacheGroups: {
        defaultVendors: {
          idHint: 'vendors'
        }
      }
    }
  }
};

后面还有一些示例,有兴趣自行翻阅官方文档
https://webpack.docschina.org/plugins/split-chunks-plugin/#splitchunksmaxasyncrequests

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值