This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

When I first got to know Webpack, I would only generate a file called bundle after using WebPack. After I got familiar with Webpack, if I had some understanding of front-end optimization, I would try to split the bloated bundle into several small files and load them as needed.

This article hopes to explain some configuration of Webpack, so that readers have a certain understanding and mastery of the related operations. The following operations are described in the webpack@4 environment.

This effect is achieved in Webpack through the optimization.splitChunks configuration, which is also the configuration of the SplitChunksPlugins plug-in.

Webpack provides default values for Optimization.splitchunks, so let’s take a look:

// 
// ** splitChunks by default **
//
{
  chunks: 'async'.minSize: 30000.maxSize: 0.minChunks: 1.maxAsyncRequests: 5.maxInitialRequests: 3.automaticNameDelimiter: '~'.automaticNameMaxLength: 30.name: true.cacheGroups: {
    vendors: {
      test: /[\\/]node_modules[\\/]/,
      priority: -10
    },
    default: {
      minChunks: 2.priority: -20.reuseExistingChunk: true}}};Copy the code

Let’s take a closer look at the configuration

chunks

By configuring this option, developers can select the chunk to optimize, and modules in the selected chunk will be analyzed and new chunks will be generated according to certain policies.

Allow all, async, INITIAL, (chunkName) => Boolean.

  • Initial: All chunk** immediately loaded (such as bundle files) ** will be checked
  • Async: All chunks loaded lazily will be checked
  • All: equivalent toinitial + asyncIn effect, all chunks will be checked
  • (chunkName) => Boolean: Functional form can provide more fine-grained control

The default is Async, so our bundle will not be optimized, so we can try to change it to INITIAL and compile it again.

{
  chunks: 'initial',}Copy the code

In addition to generating the bundle, there might be files named VENDORS ~ XXx. js. (If not, try importing packages from node_modules into your code and recompiling to see the results.)

After the changes of the two compilations, namely chunks moving from Async to Initial, the bundle was optimized for being a chunk loaded immediately.

MinSize, maxSize

As the name implies, minSize and maxSize specify the minimum/maximum size of files for the newly generated chunk. Only when the maximum and minimum file sizes of the chunk to be generated are specified, only the chunk files within this size will be generated, otherwise the code will remain unchanged.

MinSize =30000 Indicates that the minimum chunk size must be 30,00bytes. MaxSize =0 indicates that the maximum size of chunk is not limited. If set to another reasonable value, such as 150,000, the chunk generated exceeds maxSize, the chunk will be further split into smaller chunks.

cacheGroups

The cacheGroups is a key configuration of the splitChunks configuration, which determines how modules should be merged into a new chunk.

{
  vendors: {
    test: /[\\/]node_modules[\\/]/,
    priority: -10}},Copy the code

Each object under a cacheGroups configuration can be considered a cacheGroup, such as the vendors’ key objects in the code above.

cacheGroup.test

Test is used to filter all modules. The filtered modules will be placed in the chunk file corresponding to the cacheGroup. In the example above, the module path is tested with [\\/]node_modules[\\/], and finally all modules in the NODE_modules path are placed under vendors chunk, which is why vendors~xxx.js is generated above.

cacheGroup.priority

Define the priority of a cacheGroup. Since it is possible for each Module to match the test rules of multiple CacheGroups at the same time, it is necessary to determine which cacheGroup to place in based on priority.

name

Name determines the name of the chunk file to be generated. If the default value is true, the generated name format is cacheGroup name ~chunk1 name ~ chunk2name.js, where chunk1 and chunk2 are named because the cacheGroup contains the code associated with these two chunks. If there are more chunks and so on.

automaticNameDelimiter

Careful readers will notice that the ~ used to connect the chunk names in the previous section is actually set by the automaticNameDelimiter configuration item. Developers can use this configuration item to set their own concatenation.

automaticNameMaxLength

By default, the length of the chunk1 to chunk2 name portion in the name section is limited. If the length exceeds the limit, the chunk2 name portion will be truncated.

For example, if set to 3, vendors-chunk1 name ~chunk2 name. Js will become VENDORS ~chu~21737d60.js, retaining only the chu part of length =3. In the case of truncation, an additional paragraph of characters is appended, possibly as a mechanism to avoid file name duplication.

minChunks

New chunk files can be generated only when the number of chunks associated with a cacheGroup exceeds minChunks.

For example, in the default configuration:

{
  default: {
    minChunks: 2.priority: -20.reuseExistingChunk: true}}Copy the code

What is the relationship between splitchunks. minChunks and Cachegroup.minchunks?

In fact, all configurations under splitChunks are inherited or overwritten in the cacheGroup. So for a cacheGroup with a Vendors key, minChunks are 1, so basically nothing is limited, so everything in the NODE_modules folder goes to vendors chunk.

So we know that a cacheGroup whose key is default will hold at least two modules referenced by chunks. If you want to try this, you can reference the same module in the bundle generated by the two entries and then package it. You should find that the module is placed in a file named default~chunk1 name ~chunk2 name.

(Hopefully by now you have a general idea of the chunk generation logic.)